Get sent message in Outlook Addin - c#

I am facing some problems trying to get the sent message from an Outlook plugin.
In onItemSend event, I open a dialog where it shows some fields, with message information such as recipients, subject, etc and a button that will save these information into our DB. Another requirement is to save a copy of the sent message and this is where I got stuck...
I could save the message using the SaveAs method but the problem is when I open the message, it shows:
This message has not been sent. This message will be sent via
Microsoft Exchange
causing some problems with users, making them think that the message was not sent.
During my searches, I found this thread where another person had the same problem and the solution was to use the message as PostItem instead of MailItem, once the PostItem is created in sent state. Also, we should set the MessageClass property to IPM.Note and delete PR_ICON_INDEX
Here is the code that I am using to do the steps above. I found this code here and changed a little bit:
PostItem postItem = this._email.Application.CreateItem(OlItemType.olPostItem);
postItem.MessageClass = "IPM.Note";
PropertyAccessor pa = postItem.PropertyAccessor;
pa.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x10800003", -1);
postItem.Save();
NameSpace session = postItem.Session;
string postItemEntryID = postItem.EntryID;
Marshal.ReleaseComObject(postItem);
Marshal.ReleaseComObject(pa);
MailItem newMessage = session.GetItemFromID(postItemEntryID) as MailItem;
newMessage.BCC = this._email.BCC;
newMessage.Body = this._email.Body;
newMessage.BodyFormat = this._email.BodyFormat;
newMessage.CC = this._email.CC;
newMessage.HTMLBody = this._email.HTMLBody;
//Hard coded path just for illustration
newMessage.SaveAs("C:\\Temp\\MSG\test.msg", OlSaveAsType.olMSG);
The code above creates a postitem object, set some of the properties and save to the path correctly, but it has the following problems:
After executing postItem.save, to create the postitem message, it creates a read message in inbox folder
After saving the messages, I have compared the files and the size where significant, the original message size was 580kb and the postitem saved message was 52kb. It seems it did not make a copy of the message
It lost some of the of the images embedded in message, such as signature images, showing a red X in place.
How can I get/create a message, with the exact message content, recipients, attachments, properties, etc (clone kind) with sent state, without creating another message inside inbox folder?
Thank you

I would not do this to a message that Outlook is trying to send. You can
Process the Items.ItemAdd event on the Sent Items folder. By that time the message is sent and all the sender related properties are set.
You can "fix" the created MSG file by removing the unsent flag. You can do that using Redemption (I am its author) - call RDOSession.GetMessageFromMsgFile / RDOMail.Sent = true / RDOMail.Save. Keep in mind that the sender information might not yet be set.

i would not go that way with the "postitem" further, somehow it does not look the perfect way for me.
the Problem is that you are copying the item bevor it is sent. Therefore the copy says it has not been sent.
If you do not need the "normal" copy which is saved in the "sent items"-Folder, you could just Change the Folder where the item is saved with
Set mailitem.SaveSentMessageFolder = someother Folder '(which is defined as Outlook.folder)
if that is not possible, then I would make an inspection (in ThisOutlookSession) of the "sent items" Folder and make the copy-action for every new item in there. If you don't know how to let me know, then I copy you some code to bring you on the way.
another question just because Iam curious: why are you opening the form and waiting for someone to hit the ok-button, instead of saving the data into your db straight away?

Related

Getting the attachment contents of an rtf mail in vsto c#

we are trying to get the content of the attachment's of the in the rtf mail but I have tried to search using different terms but have not found any reliable solution . can someone please help me to get the source of the attachment's as we get them in the html format.
The Outlook object model doesn't provide any property or method for getting the attachment content. To get the file attached you need to save it to the disk and then read the content from the there.
Also you may consider using a low-level API on which Outlook is based on - Extended MAPI. It allows getting the binary data of the attached file. Try using the Attachment.PropertyAccessor.GetProperty method while passing in the value "http://schemas.microsoft.com/mapi/proptag/0x37010102" (PR_ATTACH_DATA_BIN).
set msg = Application.ActiveExplorer.Selection(1)
set attach = msg.Attachments(1)
set ps = attach.PropertyAccessor
v = ps.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x37010102")
debug.print ps.BinaryToString(v)
On the low level (Extended MAPI in C++ or Delphi), you need to open the PR_ATTACH_DATA_OBJ property as IStorage and extract the data from there (it depends on the actual type of the attachment). You can see the data in the streams in OutlookSpy (I am its author) - select the message, click IMessage button on the OutlookSpy ribbon, go to the GetAttachmentTable tab, double click on the attachment to open it, select the PR_ATTACH_DATA_OBJ property, right click, select IMAPIProp::OpenProperty, then IStorage. Raw data will be there as well as an image representing the attachment (so that Outlook won't have to start the host app when rendering the message).
If using Redemption is an option (I am also its author, it can be used from any language including C# and VBA), its version of RDOAttachment.SaveAsFile method handles OLE attachments for most popular formats (Word, Excel, bitmap, Power Point, Adobe PDF, etc.) - create an instance of the RDOSession object (using either CrealeOleObject or RedemptionLoader) and use RDOSession.GetRDOObjectFromOutlookObject method (pass either MailItem or Attachment object) to get back RDOMail or RDOAttachment object respectively.
i have been found a solution for getting the images content from the rtf mail directly whiteout hitting the low level api or anything.
the solution is not a straight forward one
save the mail to the disk using oDoc.SaveAs2(filepath, WdSaveFormat.wdFormatFilteredHTML);
after saving the mail you will get the folder which you save a .htm doc
now read the .htm doc
get the all the image nodes of the .htm doc
using the image nods you can get src attribute of the image node
using the src value of the image you get the image directly from the disk itself and you can use that image

determine if a message was sent or closed outlook

in c # I create a message m before sending it I show the user who can edit it and send or close it. How can I track the user closed this message or sent.
OutLookRef.Application oApp;
oApp = new OutLookRef.Application();
OutLookRef.MailItem mail = oApp.CreateItem(OutLookRef.OlItemType.olMailItem);
var pInspector = mail.GetInspector;
mail.Recipients.Add(address);
mail.Subject = subject;
mail.HTMLBody = body;
mail.Display();
All I got was to pause the code while this window is open
while (pInspector.CurrentItem is OutLookRef.MailItem)
{
System.Threading.Thread.Sleep(500);
}
also after sending, I would like to save this message to a disk, let's say mail.msg
It seems you are interested in the following properties:
MailItem.SendUsingAccount returns an Account object that represents the account under which the MailItem is to be sent.
MailItem.SentOnBehalfOfName returns a string indicating the display name for the intended sender of the mail message.
Namespace.CurrentUser returns the display name of the currently logged-on user as a Recipient object.
also after sending, I would like to save this message to a disk, let's say mail.msg
You may hook up to the ItemAdd event of the Items class which belongs to the Sent Items folder where you can save the item on the disk. The MailItem.SaveAs method saves the Microsoft Outlook item to the specified path and in the format of the specified file type. If the file type is not specified, the MSG format (.msg) is used.

c# open pop - save e-mail (HTML with inline attachements) to database

Found a problem with saving e-mail to database(as byte[] - already tried with various methods:
saving "RawMessage",
executing Message.
Load via "MemoryStream" etc..),
retrieving it and re sending.
When I send this saved e-mail, recipient does not see inline attached image (in place where image should be is information that picture was not found or couldn't be loaded).
My actual code version:
byte[] toDB = message.RawMessage; // then it goes to DB
//later in code
OpenPop.Mime.Message raw = new OpenPop.Mime.Message(fromDB, true);
//then I fill in new Message object with new values, only body remains the same:
mailMessage.Body = System.Text.Encoding.Default.GetString(raw.FindFirstHtmlVersion().Body);
Thanks :)

Body not shown in signed mail message

I have a programm, interpreting the attachement of incoming mails and writing the results of my findings in the body of the received email.
No problem at all so far...the problem comes with mails that are signed. I am able to get the attachements of the signed mail by interpreting the .p7m-File that is attached, and writing into the body of the message like this:
emailMessage.Body += string.Format("</br></br>Erste Abweichung ({0} Fahrplan):</br>{1} - {2}",
kind, pos.FromTime.ToString("dd.MM.yyyy HH:mm:ss"),
pos.ToTime.ToString("dd.MM.yyyy HH:mm:ss"));
emailMessage.Update(ConflictResolutionMode.AutoResolve);
I can see that the body property is set in Visual Studio, but in Outlook I don't see any body text. It works great when the message is not signed.
The problem now is that I don't know if this is a problem with outlook, or if I somehow have to sign the body text that I have created.
Any hint would be appreciated, thanks!
For the signed/encrypted messages, the body is always extracted from the p7m attachment. PR_BODY, PR_HTML or PR_RTF_COMPRESSED are not used.
Think about it - the whole pointy of signing a message is to prevent anybody from tampering with its contents. That is precisely what you are trying to do.
You can of course turn the signed/encrypted message into a regular message by setting the MessageClass property to "IPM.Note" and extracting the data from the p7m file, but I doubt your users will appreciate that.

Sending emails with signatures via C#

I have a the following setup to send emails from my c# Application :
SmtpClient (under System.Net.Mail namespace) to do the actual sending once everything is in place and set the 'IsBodyHtml' property of the Message object to True
Using the dll from Sautinsoft I convert a simple rtf file which contains the formatting of the email and convert it to a HTML string which I then use as the body of the mail.
It works great just as it is and I have sent a few test emails to myself and all the appropriate formatting is retained. However i am having a problem with images - The dll converts images to a img tag and uses the base 64 format of the image as the data source, this works fine if you view it as a html page, but sending it as the body of you email produces problems. Email clients such as Yahoo don't mind embedded images but Gmail does not play nice with this methodology. The only image that should appear in the emails I'm sending is the signature image located at the bottom of each email. Using signatures in the native Gmail client in your browser poses no problems since the image has a link to a actual file on a server somewhere, but sending emails with signatures via a C# Application seems to be a different story. Any suggestions?
Thank you for your time.
You may consider automating Outlook from a C# application. See How to automate Outlook and Word by using Visual C# .NET to create a pre-populated e-mail message that can be edited. Also you can find a sample code - C# app automates Outlook (CSAutomateOutlook).
If you are talking about RTF2HTML, you may add any images in a separate folder (no include in body of HTML):
string inpFile = #"..\..\..\..\example.docx";
string outFile = Path.GetFullPath(#"Result2.html");
string imgDir = Path.GetDirectoryName(outFile);
RtfToHtml r = new RtfToHtml();
// Set images directory
HtmlFixedSaveOptions opt = new HtmlFixedSaveOptions()
{
ImagesDirectoryPath = Path.Combine(imgDir, "Result_images"),
ImagesDirectorySrcPath = "Result_images",
// Change to store images as physical files on local drive.
EmbedImages = false
};
try
{
r.Convert(inpFile, outFile, opt);
}
catch (Exception ex)
{
Console.WriteLine($"Conversion failed! {ex.Message}");
}
As the result you will see HTML file with linked images in folder.

Categories

Resources