0

I have a C# program saving attachments from unread emails from Outlook mail box to a folder and the below line of code breaks(first line) for attachment types that are of OLE type with the error "Outlook cannot perform this action on this type of attachment"(Where 'it' is of type MailItem).

string attachedfilename = it.Attachments[i].FileName;
it.Attachments[i].SaveAsFile("C:\\temp\\"+attachedfilename);

I have read articles on using http://www.dimastr.com/redemption/RDOMail.htm (library) to overcome this problem for Ole type attachments, but apart from this option can I make use of any other .NET Library to overcome this problem?
If yes, kindly share the code snippet in C#.

hg8
  • 982
  • 1
  • 13
  • 27
appootan
  • 19
  • 1
  • 11

2 Answers2

0

What is the actual argument passed to the SaveAsFile method of the Attachment class?

Note, the C: requires admin privileges for writing, I'd suggest choosing another drive or folder (in a user profile).

As a workaroud you may consider using a low-level API on which Outlook and Redemption are based on - Extended MAPI. You will need to open the PR_ATTACH_DATA_OBJ property using the IAttach::OpenProperty property and open the stream as IMessage.

Eugene Astafiev
  • 26,795
  • 2
  • 13
  • 31
  • The exception is thrown in the first line "string attachedfilename = it.Attachments[i].FileName;" for ole types. For regular mail attachments , those two lines of code work perfectly(I have write access to the C:\Temp folder). Can you share code or link on using the Extended MAPI with C#? Any way i can pass the MailItem.EntryId to this API to grab the OLE attachments and save them to a folder. – appootan May 15 '15 at 16:09
  • See [Opening an Attachment](https://msdn.microsoft.com/en-us/library/office/cc842411.aspx?f=255&MSPPError=-2147217396). – Eugene Astafiev May 15 '15 at 17:22
0

You would need to call IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IStorage, ...) then open a particular stream from IStorage that contains the data that you are after. Note that the stream and its format are specific to the application that created the OLE attachment. Redemption supports Word Pad, Paint Brush, Excel, Power Point, Word, Open Office, Acrobat, bitmap, metafile, etc. formats.

IAttach::OpenProperty is only available in Extended MAPI (C++ or Delphi), you cannot do that in C#.

To see the data stored in Outlook, take a look at the attachment with OutlookSpy: select the message, click IMessage button, go to the GetAttachmentTable tab, double click on the attachment, right click on the PR_ATTACH_DATA_OBJ property, select IMAPIProp::OpenProperty, select IStorage interface.

Dmitry Streblechenko
  • 56,873
  • 3
  • 44
  • 75
  • I decided to go with Redemption since it is a managed code. I followed the steps mentioned in the redemption tutorials to get the attachments. However the MAPIOBJECT seems to be deprecated in the latest Outlook API and i cannot get this to work. Can you help? Sample Code -> Application appobj = new Application(); RDOSession RDSObj = new RDOSession(); RDSObj.MAPIOBJECT = appobj.Session.MAPIOBJECT; //MAPIOBJECT not showing up in intellisense var MailObj = RDSObj.GetMessageFromID(it.EntryID); foreach(Attachment att in RDSObj.Attachments) { att.SaveAsFile("foldername"); } – appootan May 15 '15 at 20:12
  • Namespace.MAPIOBJECT is not deprecated: it returns IMAPISession Extended MAPI object, but since it is useless in VBA or ..Net languages, the type library marks it as hidden. If you don't want to reuse the existing Outlook session, you can call RDOSession.Logon instead. – Dmitry Streblechenko May 15 '15 at 20:14
  • I would prefer to re-use the existing outlook session. I have the Application and Namespace objects that i had created from Interop Outlook. Can you provide the line of code that i need to assign RDSObj.MAPIOBJECT with or sample code in C#? – appootan May 15 '15 at 20:23
  • RDSObj.MAPIOBJECT = appobj.Session.MAPIOBJECT; would work - even though Intelllisense does not show Namespace.MAPIOJECT, you can still use it in your code. – Dmitry Streblechenko May 15 '15 at 20:24
  • Perfect!! This works after some back and forth and referring your articles in social MSDN. Finally i got this to work :) One last last query ->The olOle Image that i got from the attachment is placed with name "Picture Device Independent Bitmap.bmp" and is not having a proper name. Any idea why is it happening? – appootan May 15 '15 at 21:32
  • There is no other display name set on the attachment, but you can name the file any way your want when you call SaveAsFile. – Dmitry Streblechenko May 15 '15 at 21:34
  • IAttach::OpenProperty is only available in Extended MAPI (C++ or Delphi), you cannot do that in C#. - That is not true. It can be implemented in C# as well. – Eugene Astafiev May 16 '15 at 11:59
  • Sure, if you convert the Extended MAPI headers to C#. There used to be MAPI33 library, but it is no longer being developed or supported. – Dmitry Streblechenko May 16 '15 at 16:28
  • It doesn't matter what should be declared or not, the truth is that can be implemented in C#. Saying "you cannot do that in C#" is a lie. – Eugene Astafiev May 17 '15 at 13:02
  • Watch your language. Are you having a religious argument here Eugene? Do you have a code snippet that the OP can use to implement a solution to his problem in 10 minutes or less? – Dmitry Streblechenko May 17 '15 at 18:02