J'utilise le Microsoft.Office.Interop.Outlook.Application
pour générer un courrier électronique et l'afficher à l'écran avant que l'utilisateur ne puisse l'envoyer. L’application est une application winform
codée en C#
dans le .NET Framework 3.5 SP1
et il s’agit du Microsoft Outlook 2003
. J'utilise le code suivant:
public static void GenerateEmail(string emailTo, string ccTo, string subject, string body)
{
var objOutlook = new Application();
var mailItem = (MailItem)(objOutlook.CreateItem(OlItemType.olMailItem));
mailItem.To = emailTo;
mailItem.CC = ccTo;
mailItem.Subject = subject;
mailItem.HTMLBody = body;
mailItem.Display(mailItem);
}
Ma question est:
Comment insérer/ajouter la signature par défaut de l'utilisateur qui utilise l'application dans la body
de l'email généré? Toute aide appréciée.
Regardez le lien ci-dessous. Il explique où se trouvent les signatures dans le système de fichiers et comment les lire correctement.
http://social.msdn.Microsoft.com/Forums/en/vsto/thread/86ce09e2-9526-4b53-b5bb-968c2b8ba6d6
Le fil de discussion ne mentionne que les emplacements des signatures Windows XP et Windows Vista. J'ai confirmé que les signatures Outlook sur Windows 7 résident au même endroit que Vista. J'ai également confirmé que l'emplacement de la signature est identique pour Outlook 2003, 2007 et 2010.
Voici un exemple de code si vous choisissez cette voie. Tiré de ce site.
private string ReadSignature()
{
string appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Signatures";
string signature = string.Empty;
DirectoryInfo diInfo = new DirectoryInfo(appDataDir);
if(diInfo.Exists)
{
FileInfo[] fiSignature = diInfo.GetFiles("*.htm");
if (fiSignature.Length > 0)
{
StreamReader sr = new StreamReader(fiSignature[0].FullName, Encoding.Default);
signature = sr.ReadToEnd();
if (!string.IsNullOrEmpty(signature))
{
string fileName = fiSignature[0].Name.Replace(fiSignature[0].Extension, string.Empty);
signature = signature.Replace(fileName + "_files/", appDataDir + "/" + fileName + "_files/");
}
}
}
return signature;
}
Edit: Voir ici pour trouver le nom de la signature par défaut pour Outlook 2013 ou la réponse de @ japel dans ce fil de discussion pour 2010.
Il existe un moyen simple et rapide qui n’a pas été mentionné. Voir modifié ci-dessous:
public static void GenerateEmail(string emailTo, string ccTo, string subject, string body)
{
var objOutlook = new Application();
var mailItem = (MailItem)(objOutlook.CreateItem(OlItemType.olMailItem));
mailItem.To = emailTo;
mailItem.CC = ccTo;
mailItem.Subject = subject;
mailItem.Display(mailItem);
mailItem.HTMLBody = body + mailItem.HTMLBody;
}
En modifiant HTMLBody après avoir affiché l'élément mail, vous autorisez Outlook à ajouter la signature par défaut, puis à copier, modifier et ajouter.
J'ai eu exactement le même problème, mais je n'ai pu le résoudre qu'avec Interop et obtenir ainsi la signature par défaut.
L'astuce consiste à appeler GetInspector , qui définira par magie la propriété HTMLBody sur la signature. Il suffit de lire la propriété GetInspector. J'ai testé cela avec Windows 7/Outlook 2007.
Crédits à cet article de blog pour la solution.
Pour une raison quelconque, les bibliothèques sont légèrement différentes en fonction de la langue d’installation ..__ Aussi, une signature peut contenir un logo-image, je ne sais pas pourquoi, mais il est composé de 2 fichiers de 2 tailles différentes.
private string ReadSignature()
{
string appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Signatures";
string signature = string.Empty;
DirectoryInfo diInfo = new DirectoryInfo(appDataDir);
if (diInfo.Exists)
{
FileInfo[] fiSignature = diInfo.GetFiles("*.htm");
if (fiSignature.Length > 0)
{
StreamReader sr = new StreamReader(fiSignature[0].FullName, Encoding.Default);
signature = sr.ReadToEnd();
if (!string.IsNullOrEmpty(signature))
{
string fileName = fiSignature[0].Name.Replace(fiSignature[0].Extension, string.Empty);
signature = signature.Replace(fileName + "_files/", appDataDir + "/" + fileName + "_files/");
}
}
}
else
{
appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Signaturer";
signature = string.Empty;
diInfo = new DirectoryInfo(appDataDir);
if (diInfo.Exists)
{
FileInfo[] fiSignature = diInfo.GetFiles("*.htm");
if (fiSignature.Length > 0)
{
StreamReader sr = new StreamReader(fiSignature[0].FullName, Encoding.Default);
signature = sr.ReadToEnd();
if (!string.IsNullOrEmpty(signature))
{
string fileName = fiSignature[0].Name.Replace(fiSignature[0].Extension, string.Empty);
signature = signature.Replace(fileName + "_files/", appDataDir + "/" + fileName + "_files/");
}
}
}
}
if (signature.Contains("img"))
{
int position = signature.LastIndexOf("img");
int position1 = signature.IndexOf("src", position);
position1 = position1 + 5;
position = signature.IndexOf("\"", position1);
billede1 = appDataDir.ToString() + "\\" + signature.Substring(position1, position - position1);
position = billede1.IndexOf("/");
billede1 = billede1.Remove(position, 1);
billede1 = billede1.Insert(position, "\\");
billede1 = System.Web.HttpUtility.UrlDecode(billede1);
position = signature.LastIndexOf("imagedata");
position1 = signature.IndexOf("src", position);
position1 = position1 + 5;
position = signature.IndexOf("\"", position1);
billede2 = appDataDir.ToString() + "\\" + signature.Substring(position1, position - position1);
position = billede2.IndexOf("/");
billede2 = billede2.Remove(position, 1);
billede2 = billede2.Insert(position, "\\");
billede2 = System.Web.HttpUtility.UrlDecode(billede2);
}
return signature;
}
Obtenir et insérer la signature: Variables globales:
string billede1 = string.Empty; // holding image1
string billede2 = string.Empty; // holding image2
string signature = ReadSignature();
if (signature.Contains("img"))
{
int position = signature.LastIndexOf("img");
int position1 = signature.IndexOf("src", position);
position1 = position1 + 5;
position = signature.IndexOf("\"", position1);
//CONTENT-ID
const string SchemaPR_ATTACH_CONTENT_ID = @"http://schemas.Microsoft.com/mapi/proptag/0x3712001E";
string contentID = Guid.NewGuid().ToString();
//Attach image
mailItem.Attachments.Add(@billede1, Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue, mailItem.Body.Length, Type.Missing);
mailItem.Attachments[mailItem.Attachments.Count].PropertyAccessor.SetProperty(SchemaPR_ATTACH_CONTENT_ID, contentID);
//Create and add banner
string banner = string.Format(@"cid:{0}", contentID);
signature = signature.Remove(position1, position - position1);
signature = signature.Insert(position1, banner);
position = signature.LastIndexOf("imagedata");
position1 = signature.IndexOf("src", position);
position1 = position1 + 5;
position = signature.IndexOf("\"", position1);
//CONTENT-ID
// const string SchemaPR_ATTACH_CONTENT_ID = @"http://schemas.Microsoft.com/mapi/proptag/0x3712001E";
contentID = Guid.NewGuid().ToString();
//Attach image
mailItem.Attachments.Add(@billede2, Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue, mailItem.Body.Length, Type.Missing);
mailItem.Attachments[mailItem.Attachments.Count].PropertyAccessor.SetProperty(SchemaPR_ATTACH_CONTENT_ID, contentID);
//Create and add banner
banner = string.Format(@"cid:{0}", contentID);
signature = signature.Remove(position1, position - position1);
signature = signature.Insert(position1, banner);
}
mailItem.HTMLBody = mailItem.Body + signature;
Le traitement des cordes peut être plus intelligent, mais cela fonctionne et m’a donné mon sinature.
Справился с этой проблемой, будучи в основном "подлый". Сли при создании нового лектронного письма sur OutlookCtrl+N, Он вставляет подпись по умолчанию, я сохраняю это пустое письмо (с подписью) во временной строке, затем добавляю эту строку к другой строке, в которой есть содержимое.
Вот некоторый код, чтобы продемонстрировать то:
string s = "";
Outlook.Application olApp = new Outlook.Application();
Outlook.MailItem mail = olApp.CreateItem(Outlook.OlItemType.olMailItem);
mail.To = "[email protected]";
mail.Subject = "Example email";
s = mainContentAsHTMLString + mail.HTMLBody;
mail.Display();
mail.HTMLBody = s;
J'ai trouvé un moyen très simple de joindre la signature Outlook par défaut (y compris les images). L'astuce consiste à récupérer le message du corps après avoir appelé GetInspector et à y concaténer votre message.
Imports Microsoft.Office.Interop
Dim fdMail As Outlook.MAPIFolder
Dim oMsg As Outlook._MailItem
oMsg = fdMail.Items.Add(Outlook.OlItemType.olMailItem)
Dim olAccounts As Outlook.Accounts
oMsg.SendUsingAccount = olAccounts.Item(1)
oMsg.Subject = "XXX"
oMsg.To = "[email protected]"
Dim myInspector As Outlook.Inspector = oMsg.GetInspector
Dim text As String
text = "mail text" & oMsg.HTMLBody
oMsg.HTMLBody = text
oMsg.Send()
J'ai une solution alternative à ce problème qui vaut la peine d'être partagée et qui est complète dans le but d'envoyer un email à partir de TOUT compte Outlook avec le texte de l'email fusionné avec N'IMPORTE QUELLE signature que vous pouvez sélectionner.
Hypothèses:
Vous avez ajouté une référence au HtmlAgilityPack utilisé pour formater le contenu HTML.
Comme je n'ai trouvé aucun moyen (sauf via le registre) d'obtenir la signature du compte de messagerie, cette valeur est transmise sous forme de valeur de texte et peut être définie en tant que paramètre dans le programme ou en recherchant le compte Outlook dans les paramètres du registre.
Le compte de est un compte de messagerie valide sur le système Le fichier de signature a été créé par Outlook au format html.
Je suis sûr qu'il y a de nombreuses améliorations possibles à cela.
/// <summary>
/// Sends an email from the specified account merging the signature with the text array
/// </summary>
/// <param name="to">email to address</param>
/// <param name="subject">subect line</param>
/// <param name="body">email details</param>
/// <returns>false if account does not exist or there is another exception</returns>
public static Boolean SendEmailFromAccount(string from, string to, string subject, List<string> text, string SignatureName)
{
// Retrieve the account that has the specific SMTP address.
Outlook.Application application = new Outlook.Application();
Outlook.Account account = GetAccountForEmailAddress(application, from);
// check account
if (account == null)
{
return false;
}
// Create a new MailItem and set the To, Subject, and Body properties.
Outlook.MailItem newMail = (Outlook.MailItem)application.CreateItem(Outlook.OlItemType.olMailItem);
// Use this account to send the e-mail.
newMail.SendUsingAccount = account;
newMail.To = to;
newMail.Subject = subject;
string Signature = ReadSignature(SignatureName);
newMail.HTMLBody = CreateHTMLBody(Signature, text);
((Outlook._MailItem)newMail).Send();
return true;
}
private static Outlook.Account GetAccountForEmailAddress(Outlook.Application application, string smtpAddress)
{
// Loop over the Accounts collection of the current Outlook session.
Outlook.Accounts accounts = application.Session.Accounts;
foreach (Outlook.Account account in accounts)
{
// When the e-mail address matches, return the account.
if (account.SmtpAddress == smtpAddress)
{
return account;
}
}
throw new System.Exception(string.Format("No Account with SmtpAddress: {0} exists!", smtpAddress));
}
/// <summary>
/// Return an email signature based on the template name i.e. signature.htm
/// </summary>
/// <param name="SignatureName">Name of the file to return without the path</param>
/// <returns>an HTML formatted email signature or a blank string</returns>
public static string ReadSignature(string SignatureName)
{
string appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Signatures";
string signature = string.Empty;
DirectoryInfo diInfo = new DirectoryInfo(appDataDir);
if
(diInfo.Exists)
{
FileInfo[] fiSignature = diInfo.GetFiles("*.htm");
foreach (FileInfo fi in fiSignature)
{
if (fi.Name.ToUpper() == SignatureName.ToUpper())
{
StreamReader sr = new StreamReader(fi.FullName, Encoding.Default);
signature = sr.ReadToEnd();
if (!string.IsNullOrEmpty(signature))
{
// this merges the information in the signature files together as one string
// with the correct relative paths
string fileName = fi.Name.Replace(fi.Extension, string.Empty);
signature = signature.Replace(fileName + "_files/", appDataDir + "/" + fileName + "_files/");
}
return signature;
}
}
}
return signature;
}
/// <summary>
/// Merges an email signature with an array of plain text
/// </summary>
/// <param name="signature">string with the HTML email signature</param>
/// <param name="text">array of text items as the content of the email</param>
/// <returns>an HTML email body</returns>
public static string CreateHTMLBody(string signature, List<string> text)
{
try
{
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
HtmlAgilityPack.HtmlNode node;
HtmlAgilityPack.HtmlNode txtnode;
// if the signature is empty then create a new string with the text
if (signature.Length == 0)
{
node = HtmlAgilityPack.HtmlNode.CreateNode("<html><head></head><body></body></html>");
doc.DocumentNode.AppendChild(node);
// select the <body>
node = doc.DocumentNode.SelectSingleNode("/html/body");
// loop through the text lines and insert them
for (int i = 0; i < text.Count; i++)
{
node.AppendChild(HtmlAgilityPack.HtmlNode.CreateNode("<p>" + text[i] + "</p>"));
}
// return the full document
signature = doc.DocumentNode.OuterHtml;
return signature;
}
// load the signature string as HTML doc
doc.LoadHtml(signature);
// get the root node and insert the text paragraphs before the signature in the document
node = doc.DocumentNode;
node = node.FirstChild;
foreach (HtmlAgilityPack.HtmlNode cn in node.ChildNodes)
{
if (cn.Name == "body")
{
foreach (HtmlAgilityPack.HtmlNode cn2 in cn.ChildNodes)
{
if (cn2.Name == "div")
{
// loop through the text lines backwards as we are inserting them at the top
for (int i = text.Count -1; i >= 0; i--)
{
if (text[i].Length == 0)
{
txtnode = HtmlAgilityPack.HtmlNode.CreateNode("<p class=\"MsoNormal\"><o:p> </o:p></p>");
}
else
{
txtnode = HtmlAgilityPack.HtmlNode.CreateNode("<p class=\"MsoNormal\">" + text[i] + "<o:p></o:p></p>");
}
cn2.InsertBefore(txtnode, cn2.FirstChild);
}
// return the full document
signature = doc.DocumentNode.OuterHtml;
}
}
}
}
return signature;
}
catch (Exception)
{
return "";
}
}
Pour tous ceux qui recherchent une réponse après toutes ces années.
Dans Outlook 2016 mailItem.HTMLBody contient déjà votre signature/pied de page par défaut.
Dans mon cas, j'ai répondu à quelqu'un. Si vous souhaitez ajouter un message avant, procédez comme indiqué ci-dessous. Simple.
MailItem itemObj = item as MailItem; //itemObj is the email I am replying to
var itemReply = itemObj.Reply();
itemReply.HTMLBody = "Your message" + itemReply.HTMLBody; //here happens the magic, your footer is already there in HTMLBody by default, just don't you delete it :)
itemReply.Send();
Pour obtenir/définir la signature par défaut de l'utilisateur, vous pouvez utiliser le registre Windows. Exemple pour Outlook 2010: Chaîne Valeur: (nom du fichier de signature sans fin)
L'utilisation de GetInspector provoque une exception lors de l'implémentation d'un intercepteur à l'aide de l'événement Inspectors_NewInspector. Vous constaterez également que la signature n'a pas encore été ajoutée à MailItem lorsque l'événement Inspectors_NewInspector est déclenché.
Si vous déclenchez le Item.Send () avec votre propre code (par exemple, votre propre bouton), vous aurez une balise d'ancrage <a>
pour la "Signature" et la "Contenu fin". Notez que ces balises sont supprimées de HTMLBody (dans la traduction de Word HTML en HTML) si vous gérez vous-même l'événement de clic sur le bouton [Envoyer] du ruban Outlook (comme c'est le cas pour les compléments).
Ma solution consiste à gérer l'événement Item.Open afin que, lorsque l'Interceptor/Inspectors_NewInspector soit créé/déclenché, je puisse ensuite ajouter un attribut Id à la balise contenant <p>
à utiliser ultérieurement lors de l'envoi. Cet attribut reste dans le code HTML même après l'envoi.
Cela garantit que chaque fois que l’envoi est appelé, je peux détecter dans mon code les paragraphes "Signature" ou "Fin du contenu".