.net email pinvoke mapi

.net - ¿MAPI y experiencias de código administrado?



email pinvoke (8)

El uso de funciones MAPI desde dentro del código administrado no está respaldado oficialmente. Aparentemente, MAPI usa su propia administración de memoria y se cuelga y se quema dentro del código administrado (ver aquí y aquí )

Todo lo que quiero hacer es abrir el cliente de correo electrónico predeterminado con asunto, cuerpo y uno o más archivos adjuntos .

Así que he estado investigando MAPISendDocuments y parece funcionar. Pero no he podido reunir coraje para usar realmente la función en el código de producción.

Alguien ha usado mucho esta función? ¿Tienes alguna historia de terror?

PD. No, no ejecutaré Excepción de Outlook.exe con argumentos de línea de comandos para los archivos adjuntos.

PPS. El soporte de archivos adjuntos es un requisito , por lo que las soluciones de Mailto: no me lo cortan.


Para alguien con experiencia en MAPI, les tomaría menos tiempo generar el código para hacer exactamente lo que quieres del código no administrado (léase: C ++ normal) que escribir esta publicación y leer la respuesta (sin ofender).

Tienes suerte de que la funcionalidad que necesitas sea limitada. Todo lo que necesita es una sencilla utilidad C ++ para tomar los parámetros que necesita en la línea de comandos y emitir las llamadas MAPI correctas. Entonces, usted toda esta utilidad de su código administrado al igual que lo haría con cualquier otro proceso.

HTH


Proceso de llamada. Comience con el protocolo Mailto: (como se muestra a continuación) le dará funcionalidad básica pero no archivos adjuntos.

Process.Start("mailto:[email protected]?subject=TestCode&Body=Test Text");

Puede realizar este enfoque con rutas de acceso, pero esta opción solo funciona con alguna versión anterior de Outlook, como 98. Supongo que esto se debe al posible riesgo de seguridad.

Si alguien usa outlook.exe dará advertencias de seguridad bajo Outlook 2003 (y 2007 Depende de la configuración).


Debería poder crear una DLL no administrada que realice las operaciones que desea utilizando MAPI y luego invocar esa DLL desde su código administrado. No escribiría un contenedor MAPI directo, sino algo que realice todas las funcionalidades que necesita de MAPI contenidas en esa DLL no administrada. Esa sería probablemente la forma más segura de usar MAPI desde el código administrado.


También puede usar el canje de Outlook , que es compatible con el código administrado; No estoy seguro de inmediato si tiene un reemplazo simple de MAPISendDocuments, pero Dmitry es útil si tiene alguna pregunta.

En cuanto a "bloqueos y quemaduras", aquí hay otra cita de un chico de soporte de MS, aquí

Es el tipo de cosa que más funcionará. Funcionará mientras lo estás escribiendo. Entonces funcionará mientras lo estás probando. Funcionará mientras su cliente lo evalúa. Luego, tan pronto como el cliente lo despliegue, ¡BAM! Ahí es cuando decidirá comenzar a tener problemas. Y Microsoft no te ayudará con eso, ya que te dijimos que no lo hicieras en primer lugar. :)


Lo he hecho utilizando la función MAPISendMail y varias clases internas para ajustar algunas de las otras estructuras relacionadas con MAPI. Mientras este sea el único uso, es posible, aunque no trivial, hacerlo de forma segura, ya que requiere una atención muy cercana a los diversos tipos de datos no administrados y la asignación / desasignación de memoria y GC. Si bien aún no es compatible, estoy usando esto en el código de producción (aunque todavía no se ha enviado).

Cuando le pregunté a Matt Stehle sobre esto, la respuesta que recibí fue:

Realmente no conozco una forma mucho mejor de hacer esto y cualquier problema que encuentre aquí probablemente sea reproducible en un escenario compatible (es decir, VB6 o C ++ no administrado). Solo tenga en cuenta que si alguna vez se topa con un escenario donde un problema fue causado específicamente por esta función que se llama desde .NET, no tendríamos ninguna otra recomendación para usted y luego no usar .NET.

No es exactamente una bendición al usarlo, pero tampoco dice que haya otras opciones para hacerlo desde el código administrado.


Tenga un helper EXE separado que tome params de línea de comandos (o pipe a su StandardInput) que haga lo que necesita y llámelo desde su aplicación principal. Esto mantiene el material de MAPI fuera del espacio de proceso de su aplicación principal. OK, todavía estás mezclando MAPI y .NET pero en un proceso muy efímero. La suposición es que MAPI y CLR comienzan a causar problemas con los procesos de más larga ejecución.

Usamos la biblioteca de Redemption Data Objects de Dmitry Streblechenko, que nos permite escribir el código "shim" en JScript e invocarlo, lo que mantiene los mundos CLR y MAPI en procesos separados, pero de forma compatible.

@Chris Fournier re. escribiendo una DLL no administrada. Esto no funcionará porque el problema es mezclar MAPI y código administrado en el mismo proceso .


El siguiente código no usa MAPI como tal, pero sí abre la ventana "Redactar correo" con archivos adjuntos arbitrarios.

(en realidad, no está probado por completo, pero lo desenterré en una aplicación que creo que funcionó)

using Microsoft.Office; using Microsoft.Office.Core; ... Outlook.Application outlook = new Outlook.Application(); Outlook.MailItem mail = (Outlook.MailItem) outlook.CreateItem(Outlook.OlItemType.olMailItem); mail.BodyFormat = Outlook.OlBodyFormat.olFormatRichText; mail.HTMLBody = "stuff"; mail.Subject = "more stuff"; string file = File.ReadAllBytes(...); mail.Attachments.Add(file, Outlook.OlAttachmentType.olByValue, 1, file) mail.Display(false);


MAPISendDocuments está en desuso y podría eliminarse. Debería usar MAPISendMail en su lugar. Ver MAPI simple