在生成的电子邮件中添加默认Outlook签名

我正在使用Microsoft.Office.Interop.Outlook.Application生成电子邮件并在用户发送之前将其显示在屏幕上。 该应用程序是一个winform应用程序,在.NET Framework 3.5 SP1C#编码,它是Microsoft Outlook 2003 。 我使用以下代码:

 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); } 

我的问题是:

如何在生成的电子邮件body中插入/添加正在使用该应用程序的用户的默认签名? 任何帮助赞赏。

看看下面的链接。 它解释了在文件系统中可以找到签名的位置以及如何正确读取它们。

http://social.msdn.microsoft.com/Forums/en/vsto/thread/86ce09e2-9526-4b53-b5bb-968c2b8ba6d6

该线程仅提及Window XP和Windows Vista签名位置。 我已确认Windows 7上的Outlook签名与Vista位于同一位置。 我还确认了Outlook 2003,2007和2010的签名位置相同。

如果您选择这条路线,这是一个代码示例。 取自本网站。

 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; } 

编辑: 请参阅此处以查找 Outlook 2013 的默认签名名称或@ japel在2010年此主题中的答案。

有一个非常简单的方法,没有提到。 见下面的修改:

 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; } 

通过在显示邮件项目后编辑HTMLBody,您允许Outlook执行添加默认签名的工作,然后进行复制,编辑和追加。

我有完全相同的问题,但只能使用Interop解决它,从而获得默认签名。

诀窍是调用GetInspector ,它会将HTMLBody属性神奇地设置为签名。 只需阅读GetInspector属性即可。 我用Windows 7 / Outlook 2007测试了这个。

对此解决方案的博客文章的信用。

由于某些原因,根据安装的语言,库会有所不同。 此外,签名可以包含徽标图像,我不知道为什么,但它是由两个不同大小的2个文件制作的。

 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; } 

获取和插入签名:全局变量:

  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; 

字符串处理可以更聪明,但这个工作并给了我神圣的运气。

我通过主要是’偷偷摸摸’来克服这个问题。 如果,当您通过Ctrl + N在Outlook中创建新电子邮件时,它会插入默认签名,我将该空白电子邮件(带签名)存储在临时字符串中,然后将该字符串附加到另一个包含其中内容的字符串中。

以下是一些演示它的代码:

 string s = ""; Outlook.Application olApp = new Outlook.Application(); Outlook.MailItem mail = olApp.CreateItem(Outlook.OlItemType.olMailItem); mail.To = "Hi@World.com"; mail.Subject = "Example email"; s = mainContentAsHTMLString + mail.HTMLBody; mail.Display(); mail.HTMLBody = s; 

我发现了一种非常简单的方法来附加默认的outlook签名(包括图像)。 诀窍是在调用GetInspector后检索正文消息并将消息连接到该消息。

 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 = "xxx@xxx.com" Dim myInspector As Outlook.Inspector = oMsg.GetInspector Dim text As String text = "mail text" & oMsg.HTMLBody oMsg.HTMLBody = text oMsg.Send() 

要获取/设置用户的默认签名,您可以使用Windows注册表。 Outlook 2010的示例:HKEY_CURRENT_USER \ Software \ Microsoft \ Office \ 14.0 \ Common \ MailSettings名称:NewSignature数据类型:字符串值:(签名文件的名称没有结尾)

我有一个针对此问题的变体解决方案,值得分享,并且完成的目的是从任何Outlook帐户发送电子邮件,其中电子邮件文本与您可以选择的任何签名合并。

假设:

您添加了对HtmlAgilityPack的引用,该引用用于格式化HTML内容。

由于我无法找到(通过注册表除外)获取电子邮件帐户签名,因此将其作为文本值传递,并可以在程序中设置为参数,也可以查看Outlook帐户的注册表设置。

来自帐户的是来自系统的有效电子邮件帐户签名文件是由Outlook使用html格式创建的。

我相信这有很多可能的改进。

  ///  /// Sends an email from the specified account merging the signature with the text array ///  /// email to address /// subect line /// email details /// false if account does not exist or there is another exception public static Boolean SendEmailFromAccount(string from, string to, string subject, List 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)); } ///  /// Return an email signature based on the template name ie signature.htm ///  /// Name of the file to return without the path /// an HTML formatted email signature or a blank string 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; } ///  /// Merges an email signature with an array of plain text ///  /// string with the HTML email signature /// array of text items as the content of the email /// an HTML email body public static string CreateHTMLBody(string signature, List 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(""); doc.DocumentNode.AppendChild(node); // select the  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("

" + text[i] + "

")); } // 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("

 

"); } else { txtnode = HtmlAgilityPack.HtmlNode.CreateNode("

" + text[i] + "

"); } cn2.InsertBefore(txtnode, cn2.FirstChild); } // return the full document signature = doc.DocumentNode.OuterHtml; } } } } return signature; } catch (Exception) { return ""; } }

使用Inspectors_NewInspector事件实现Interceptor时,使用GetInspector会导致exception。 您还会发现,在引发Inspectors_NewInspector事件时,Signature尚未添加到MailItem。

如果您使用自己的代码触发Item.Send() (例如您自己的按钮),则“Signature”和“Content End”都会有一个Anchor标签 。 请注意,如果您自己处理Outlookfunction区[发送]按钮单击事件(这对于加载项是常见的),则会从HTMLBody中删除这些标记(在从Word HTML转换为HTML中)。

我的解决方案是处理Item.Open事件,以便在创建/引发Interceptor / Inspectors_NewInspector时,我可以在包含

标记时添加Id属性,以便以后在发送时使用。 即使在发送之后,此属性仍保留在HTML中。

这确保了无论何时调用Send,我都可以在我的代码中检测“Signature”或“Content End”段落。