Domanda

L'utilizzo delle funzioni MAPI dal codice gestito non è ufficialmente supportato.Apparentemente, MAPI utilizza la propria gestione della memoria e si blocca e si brucia all'interno del codice gestito (vedi Qui E Qui)

Tutto quello che voglio fare è avviare il client di posta elettronica predefinito con soggetto, corpo, E uno o più allegati.

Quindi ho indagato MAPISendDocuments e sembra funzionare.Ma non sono riuscito a trovare il coraggio per utilizzare effettivamente la funzione nel codice di produzione.

Qualcuno ha utilizzato molto questa funzione?Hai qualche storia dell'orrore?

PS.No, non eseguirò shellExecute Outlook.exe con argomenti della riga di comando per gli allegati.

PPS.Il supporto per l'allegato è a Requisiti , quindi Mailto:le soluzioni non fanno al caso mio.

È stato utile?

Soluzione

Avere un EXE helper separato che accetta i parametri della riga di comando (o collega al suo StandardInput) che fa ciò che è richiesto e chiamalo dalla tua app principale.Ciò mantiene il materiale MAPI al di fuori dello spazio di elaborazione dell'app principale.OK, stai ancora mescolando MAPI e .NET ma in un processo di brevissima durata.Il presupposto è che MAPI e CLR inizino a causare problemi con processi di lunga durata.

Usiamo il superbo di Dmitry Streblechenko Oggetti dati di riscatto libreria che ci consente di scrivere tale codice "shim" in JScript e di invocarlo, mantenendo i mondi CLR e MAPI in processi separati, ma in modo supportato.

@Chris Fournier riguardo.scrivere una DLL non gestita.Questa operazione non funzionerà perché il problema riguarda la combinazione di MAPI e codice gestito nello stesso processo.

Altri suggerimenti

MAPISendDocuments è deprecato e potrebbe essere rimosso.Dovresti invece utilizzare MAPISendMail.Vedere MAPI semplice

Processo di chiamata. Inizia da Mailto:protocollo (come mostrato di seguito) ti fornirà le funzionalità di base ma non gli allegati.

Process.Start("mailto:name@domain.com?subject=TestCode&Body=Test Text");

Puoi eseguire questo approccio con i percorsi degli allegati, ma questa opzione funziona solo con alcune versioni precedenti di Outlook come 98.Presumo che ciò sia dovuto al potenziale rischio per la sicurezza.

Se qualcuno utilizza outlook.exe, verranno visualizzati avvisi di sicurezza in Outlook 2003 (e 2007 a seconda delle impostazioni).

Dovresti essere in grado di creare una DLL non gestita che esegua le operazioni desiderate utilizzando MAPI e quindi richiamare tale DLL dal codice gestito.Non scriverei un wrapper MAPI diretto, ma qualcosa che esegua tutte le funzionalità richieste da MAPI contenute in quella DLL non gestita.Questo sarebbe probabilmente il modo più sicuro per utilizzare MAPI dal codice gestito.

Potresti anche usare Riscatto di prospettiva, che è supportato dal codice gestito;Non sono immediatamente sicuro che abbia una semplice sostituzione MAPISendDocuments, ma Dmitry è utile se hai domande.

Per quanto riguarda "crash e ustioni", ecco un'altra citazione di un ragazzo dell'assistenza MS, Qui

È il genere di cose che per lo più funziona.Funzionerà mentre lo scrivi.Quindi funzionerà mentre lo stai testando.Funzionerà mentre il tuo cliente lo valuta.Quindi non appena il cliente lo distribuisce: BAM!È allora che deciderà di iniziare ad avere problemi.E Microsoft non ti aiuterà, dal momento che ti avevamo detto di non farlo fin dall'inizio.:)

L'ho fatto utilizzando la funzione MAPISendMail e diverse classi interne per racchiudere alcune delle altre strutture correlate a MAPI.Finché questo è l'unico utilizzo, è possibile, anche se non banale, eseguirlo in sicurezza in quanto richiede molta attenzione ai vari tipi di dati non gestiti, all'allocazione/deallocazione della memoria e al GC.Sebbene non sia ancora supportato, lo sto utilizzando nel codice di produzione (sebbene non sia ancora stato spedito).

Quando ho chiesto informazioni a Matt Stehle, la risposta che ho ricevuto è stata:

Davvero non conosco un modo migliore per farlo e qualsiasi problema riscontrato qui sarebbe probabilmente riproducibile in uno scenario supportato (ad es.VB6 o C++ non gestito).Sappi solo che se mai ti imbattessi in uno scenario in cui un problema fosse causato specificamente dalla chiamata di questa funzione da .NET, non avremmo nessun altro consiglio per te quindi di non utilizzare .NET.

Non è esattamente una benedizione usarlo, ma non dice nemmeno che ci siano altre opzioni per farlo effettivamente dal codice gestito.

Il codice seguente non utilizza MAPI in quanto tale, ma apre la finestra "Componi posta" con allegati arbitrari.

(in realtà non è stato testato del tutto, ma l'ho trovato in un'applicazione che credo abbia funzionato)

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

Per qualcuno esperto con MAPI, ci vorrebbe meno tempo per elaborare il codice per fare esattamente quello che vuoi dal codice non gestito (leggi:semplice C++) piuttosto che scrivere questo post e leggere la risposta (senza offesa).

Sei fortunato che le funzionalità di cui hai bisogno siano limitate.Tutto ciò di cui hai bisogno è una semplice utility C++ per prendere i parametri necessari sulla riga di comando ed eseguire le chiamate MAPI corrette.Quindi, ottieni tutta questa utilità dal tuo codice gestito proprio come faresti per eseguire qualsiasi altro processo.

HTH

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top