|
Fran?ois-Denis Gonthier
Posts: 14
Joined: 2009-10-21
|
This question is twofold.
I've built a Managed C++ wrapper for a few MAPI functions. It uses the .MAPIOBJECT properties of the Outlook COM object to access the several MAPI objects, mostly to obtain more properties for attachment in a way that is compatible with both Outlook 2003 and 2007. The wrappers are pretty simple. They work in a use-then-release fashion, and return managed object created from copying data. No reference to MAPI object is kept in the managed code.
Microsoft very clearly said that MAPI should be used out-of-process of managed code and that using it in-process would eventually make the program breaks. This puzzles me a bit since Add-In Express very obviously makes good money selling helpers to do just that. They reasons they provide are of course lacking in details and confusing.
What's the deal with that? Will doing that work or fail badly at the worse possible moment?
Second, I would like to know why some properties, exposed by MAPI and visible by OutlookSpy, aren't available when using ADXMAPIStoreAccessor? I'm thinking this is because the accessor creates another MAPI connection and that the information that is missing is only missing because it has not been commited to the store by Outlook. Is there a way to make it visible? |
|
Posted 21 Oct, 2009 09:18:44
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 19029
Joined: 2006-05-11
|
Hi Fran?ois-Denis,
MAPI Accessor is a .NET wrapper over an unmanaged core which deals with Extended MAPI. That's why it works. Accessing Extended MAPI in .NET will probably fail at the worst possible moment. I believe there's a way to make .NET work with Extended MAPI but it must be a complex one; I suppose that's why they prefer not to deal with that part and declared accessing Extended MAPI in .NET unwanted and unsupported. But that's my thoughts; I don't know a correct answer, sorry.
Second, I would like to know why some properties, exposed by MAPI and visible by OutlookSpy, aren't available when using ADXMAPIStoreAccessor?
What are those properties?
Andrei Smolin
Add-in Express Team Leader |
|
Posted 21 Oct, 2009 11:45:25
|
|
Top
|
|
Fran?ois-Denis Gonthier
Posts: 14
Joined: 2009-10-21
|
MAPI Accessor is a .NET wrapper over an unmanaged core which deals with Extended MAPI.
If someone can convince me that I must, I will do unmanaged DLL out of my current code without hesitation. My concern is that Microsoft actually actually suggests it must be [B]out-of-process[B] of the native code. An unmanaged DLL would still running inside a managed process. I don't think I'll be able to do an out-of-process COM object (or something else) with the code I currently have.
Another thing, if there is really a risk using MAPI in-process with managed code, then how Add-In Express manages that?
Second, I would like to know why some properties, exposed by MAPI and visible by OutlookSpy, aren't available when using ADXMAPIStoreAccessor?
I've devised a nasty way to obtain the size of an attachment that is portable to Outlook 2003 and Outlook 2007 by using an Exchange Client Extension (ECE). This extensions saves some properties in the MAPI object as provided by Outlook through the ECE interface but those information are invisible to ADXMAPIStoreAccessor at the time the ProcessAttachmentAdd event is called. In the other hand, that information is visible through MAPI. In this case, the property in question is PR_ATTACH_PATHNAME, but I believe no properties of the attachments are visible to ADXMAPIStoreAccessor until the MailItem is saved.
We don't want to save the attachments at that time because in case of IMAP or Exchange saving a mail might be very costly. |
|
Posted 21 Oct, 2009 12:17:05
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 19029
Joined: 2006-05-11
|
Hi Fran?ois-Denis,
My concern is that Microsoft actually actually suggests it must be out-of-process of the native code.
Extended MAPI is used in Outlook add-ins for years, maybe even decades.
I've devised a nasty way to obtain the size of an attachment...
Just today we published a post on our blog describing http://www.add-in-express.com/creating-addins-blog/2009/10/23/outlook-attachment-size/.
Andrei Smolin
Add-in Express Team Leader |
|
Posted 23 Oct, 2009 10:18:31
|
|
Top
|
|
Fran?ois-Denis Gonthier
Posts: 14
Joined: 2009-10-21
|
Hi Andrei
Extended MAPI is used in Outlook add-ins for years, maybe even decades.
That's enough for me. I've moved all the code that calls MAPI interface in unmanaged code, just to be sure.
Just today we published a post on our blog describing How to get the size of an attachment in Outlook 2000 ?Â?Ð?ã 2007.
I'll double check your code vs mine, but my preliminary tests, and Microsoft documentation, show that PR_ATTACH_SIZE is mostly meaningless if the PR_ATTACH_DATA_BIN property isn't stored. In that case, PR_ATTACH_SIZE is just the size of the data related to the attachment and doesn't include the attachment data itself.
To make matters worse for us, there is no property available on the IAttach object until the MailItem is saved, which is something we don't want to do. I'm allowed to check some property of the attachment because I cheat by using an Exchange Client Extension. |
|
Posted 26 Oct, 2009 10:27:12
|
|
Top
|
|
Dmitry Kostochko
Add-in Express team
Posts: 2887
Joined: 2004-04-05
|
Hello Fran?ois-Denis,
Yes, you are right, there is a little difference (100-200 bytes) between what is returned by the PR_ATTACH_SIZE property and what the PR_ATTACH_DATA_BIN property contains. But I have just re-tested the Attachment.Size property in Outlook 2007 and got the "wrong" value. Is it a bug in Outlook 2007 or is the attachment size perceived as that "wrong" value, i.e. the real file size plus some internal info?
In any case, thank you for your comment, we will try to play with the PR_ATTACH_DATA_BIN property and publish a new post on our blog if we get any results. |
|
Posted 27 Oct, 2009 06:24:30
|
|
Top
|
|
Robert Mondavi
Posts: 30
Joined: 2009-08-20
|
As far as I can tell, the code in the how-to CANNOT be used for emails not being sent yet.
I tried the sample project that I slightly modified by adding an Inspector command bar and running the following code in the button click:
private void adxCommandBarButton2_Click(object sender)
{
Outlook.Inspector activeInspec = OutlookApp.ActiveInspector();
if (activeInspec != null)
{
try
{
Outlook.MailItem item = activeInspec.CurrentItem as Outlook.MailItem;
if (item != null)
{
try
{
DoGetAttachmentSize(item);
}
finally
{
Marshal.ReleaseComObject(item);
}
}
}
finally
{
Marshal.ReleaseComObject(activeInspec);
}
}
}
The size of any attachment is always 0, unless item.Save() is called before the DoGetAttachmentSize(item) call, in which case a size that looks valid is retrieved.
Dmitry, can you confirm this behavior on your side as well? |
|
Posted 27 Oct, 2009 08:31:30
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 19029
Joined: 2006-05-11
|
Hello Robert,
Until the Outlook item is saved, no corresponding record exists in the message database. So, you can only use that code after the item is saved.
Andrei Smolin
Add-in Express Team Leader |
|
Posted 27 Oct, 2009 09:21:56
|
|
Top
|
|
Fran?ois-Denis Gonthier
Posts: 14
Joined: 2009-10-21
|
I echo Robert remark. Nor the Outlook Object model nor MAPI offers a way to obtain the size of the attachment before the full mail item is saved.
Yes, you are right, there is a little difference (100-200 bytes) between what is returned by the PR_ATTACH_SIZE property and what the PR_ATTACH_DATA_BIN property contains. But I have just re-tested the Attachment.Size property in Outlook 2007 and got the "wrong" value. Is it a bug in Outlook 2007 or is the attachment size perceived as that "wrong" value, i.e. the real file size plus some internal info?
Yes. The MSDN documentation says exactly that. PR_ATTACH_SIZE is sizeof(PR_ATTACH_DATA_BIN) + sizeof(SOME_DATA). I would not care very much about SOME_DATA since it gets small enough given a big attachment.
Quoting MSDN...
It is recommended that attachment subobjects expose the PR_ATTACH_SIZE property. The sum contained in PR_ATTACH_SIZE includes the size of the PR_ATTACH_DATA_BIN property. Accordingly, PR_ATTACH_SIZE is usually larger than the contents of the attachment alone.
The rest of my reply assumes that a call to IMAPIProp::ForceSave method was done on the IAttach interface before attachment data is used. AFAIK, this is not the same as saving the mail item. It puts just a bit of useful informations about the attachment in the MAPI table. It's also definitely less costly than saving the full mail item.
The problem is that Outlook won't put any data in PR_ATTACH_DATA_BIN until the mail is saved. So, at the time the mail is composed, the value of PR_ATTACH_SIZE only includes sizeof(SOME_DATA) which is borderline useless.
If anyone cares, when the PR_ATTACH_DATA_SIZE property is set, you can get the exact size of the property by doing the following
- Call OpenProperty on PR_ATTACH_DATA_BIN
- Obtain an IStream interface with the IUnknown returned by OpenProperty
- Call the Stat method on the IStream interface, which gives you a set of information on the attachment content
- Rejoice!
I can make a code example out of that once I receive ample payment in the form of booze and hookers... |
|
Posted 27 Oct, 2009 09:32:48
|
|
Top
|
|
Dmitry Kostochko
Add-in Express team
Posts: 2887
Joined: 2004-04-05
|
Hello Fran?ois-Denis,
Thank you for your comments. I think we will try to create a new sample and publish it on our blog. |
|
Posted 28 Oct, 2009 04:27:57
|
|
Top
|
|