c# - para - Agregue la firma de Outlook por defecto en el correo electrónico generado.
plantillas para firmas de correo gratis (9)
Estoy utilizando Microsoft.Office.Interop.Outlook.Application
para generar un correo electrónico y mostrarlo en la pantalla antes de que el usuario pueda enviarlo. La aplicación es una aplicación winform
codificada en C#
en .NET Framework 3.5 SP1
y es Microsoft Outlook 2003
. Estoy usando el siguiente código:
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);
}
Mi pregunta es:
¿Cómo inserto / agrego la firma predeterminada del usuario que usa la aplicación en el body
del correo electrónico generado? Cualquier ayuda apreciada.
Echar un vistazo a el siguiente enlace. Explica dónde se pueden encontrar las firmas en el sistema de archivos y cómo leerlas correctamente.
http://social.msdn.microsoft.com/Forums/en/vsto/thread/86ce09e2-9526-4b53-b5bb-968c2b8ba6d6
El hilo solo menciona las ubicaciones de firma de Windows XP y Windows Vista. He confirmado que las firmas de Outlook en Windows 7 se encuentran en el mismo lugar que Vista. También confirmé que la ubicación de la firma es la misma para Outlook 2003, 2007 y 2010.
Aquí hay un ejemplo de código si decides ir por esta ruta. Tomado de este sitio.
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;
}
Edición: consulte aquí para encontrar el nombre de la firma predeterminada para Outlook 2013 o la respuesta de @ japel en este hilo para 2010.
El uso de GetInspector produce una excepción al implementar un Interceptor mediante el evento Inspectors_NewInspector . También encontrará que la Firma aún no se ha agregado al artículo de correo cuando se levanta el evento Inspectors_NewInspector .
Si activa el Item.Send () con su propio código (por ejemplo, su propio botón), tendrá una etiqueta de anclaje <a>
para la "Firma" y el "Fin del contenido". Tenga en cuenta que estas etiquetas se eliminan del HTMLBody (en la traducción de Word HTML a HTML) si maneja usted mismo el evento de clic en el botón [Enviar] de la cinta de Outlook (como es habitual en los complementos).
Mi solución es manejar el evento Item.Open para que cuando se cree / genere el Interceptor / Inspectors_NewInspector, pueda agregar un atributo Id a la etiqueta <p>
para usarlo más tarde al enviar. Este atributo permanece en el HTML incluso después del envío.
Esto garantiza que siempre que se llame el envío, pueda detectar en mi código los párrafos "Firma" o "Fin del contenido".
Hay una manera fácil muy rápida que no se ha mencionado. Ver modificada a continuación:
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;
}
Al editar el HTMLBody después de mostrar el elemento de correo, usted permite que Outlook realice el trabajo de agregar la firma predeterminada y luego, esencialmente, copiar, editar y agregar.
He encontrado una forma muy sencilla de adjuntar la firma de Outlook predeterminada (incluidas las imágenes). El truco es recuperar el mensaje del cuerpo después de llamar al GetInspector y adaptar su mensaje a eso.
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()
He superado el problema siendo principalmente ''astuto''. Si, cuando crea un nuevo correo electrónico en Outlook con Ctrl + N , inserta la firma predeterminada, almaceno ese correo electrónico en blanco (con firma) en una cadena temporal y luego agrego esa cadena a otra cadena que tiene el contenido.
Aquí hay un código para demostrarlo:
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;
He tenido exactamente el mismo problema, pero pude resolverlo solo con Interop, y así obtener la firma predeterminada.
El truco es llamar a GetInspector , que establecerá mágicamente la propiedad HTMLBody a la firma. Basta con leer la propiedad GetInspector es suficiente. He probado esto con Windows 7 / Outlook 2007.
Créditos a esta entrada de blog por la solución.
Para obtener / configurar la firma predeterminada del usuario puede usar el registro de Windows. Ejemplo para Outlook 2010: HKEY_CURRENT_USER / Software / Microsoft / Office / 14.0 / Common / MailSettings Nombre: NewSignature Tipo de datos: String Valor: (nombre del archivo de firma sin finalización)
Por alguna razón, las bibliotecas se hacen un poco diferentes dependiendo del idioma instalado. También una firma puede contener una imagen de logotipo, que no sé por qué, pero está hecha en 2 archivos en 2 tamaños diferentes.
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;
}
Obtención e inserción de la firma: 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;
El manejo de las cuerdas puede ser más inteligente, pero esto funciona y me dio suerte de Dios.
Tengo una solución alternativa a este problema que vale la pena compartir y que está completa con el propósito de enviar un correo electrónico desde CUALQUIER cuenta de Outlook con el texto del correo electrónico combinado con CUALQUIER firma que pueda seleccionar.
Suposiciones
Ha agregado una referencia al HtmlAgilityPack que se usa para formatear el contenido HTML.
Como no pude encontrar ninguna forma (excepto a través del registro) para obtener la firma de la cuenta de correo electrónico, esto se pasa como un valor de texto y se puede configurar como un parámetro en el programa o mirando la configuración del registro para la Cuenta de Outlook.
La cuenta de origen es una cuenta de correo electrónico válida en el sistema. Outlook creó el archivo de firma utilizando el formato html.
Estoy seguro de que hay numerosas mejoras posibles para esto.
/// <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 "";
}
}