2
votes

I am using the following code to open the signed/unsigned Outlook messages and I display the content in WebBrowser control.

Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
var item = app.Session.OpenSharedItem(msgfile) as Microsoft.Office.Interop.Outlook.MailItem;
string message = item.HTMLBody;
app.Session.Logoff();     

It is working fine for the first time the file is opening, but after closing the Outlook file trying to reopen the file it showing the following error:

"Cannot open file: C:\tion.msg. The file may not exist, you may not have permission to open it, or it may be open in another program. Right-click the folder that contains the file, and then click Properties to check your permissions for the folder."

After some time later it is opening fine. For this strange behavior what could be the reason and how to rectify the the error message?

5

5 Answers

4
votes

Would any combination of the Quit[1], Close[2] or ReleaseComObject[3] methods work for you? My code worked better but not perfect after I used them.[4]

using Outlook = Microsoft.Office.Interop.Outlook;

.
.
.

var app = new Outlook.Application();
var item = app.Session.OpenSharedItem(msgfile) as Outlook.MailItem;

//Do stuff with the mail.

item.Close(OlInspectorClose.olDiscard);
app.Quit();
Marshal.ReleaseComObject(item);

Another solution, according to Microsoft - Help and Support[5], is to delay the opening of the file. However, it doesn't sound like a good solution to me since, like @SliverNinja also said, you'll never know when Outlook releases its lock of the file.

Notes and references

  1. http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._application.quit.aspx, read 2014-10-14, 16:19.
  2. http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._mailitem.close%28v=office.15%29.aspx, read 2014-10-14, 16:19.
  3. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx, read 2014-10-14, 16:19.
  4. For example, if I had opened Outlook for som regular work, the Quit-method would close that window as well.
  5. http://support2.microsoft.com/kb/2633737, read 2014-10-08, 16:19.
3
votes

Outlook manages its own cache of items when you are opening and closing messages. Your best bet would be to use a randomly generated filename (i.e. Path.GetRandomFilename) when opening via OpenSharedItem so that you don't get issues. I would also use a temporary path instead of root c:\ (i.e. Path.GetTempPath).

You can try and free the MailItem reference (i.e. setting it to null), but there is no guarantee when Outlook will release the item from its cache.

0
votes

Hello you have two options .

  • set the Read-only attribute to the msg file

or

  • disable the following permissions for the users or usergroups to the parent folder:

    • Write Attributes
    • Write Extended Attributes

the msg file can now open multiple times but is write protect

0
votes

I had this problem, in my case it was the space in the file name

import win32com.client
import os
path = 'C:/testes/mail'
files = [f for f in os.listdir(path) if '.msg' in f]
for file in files:
    outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
    msg = outlook.OpenSharedItem(os.path.join(path, file))
    att=msg.Attachments
    for i in att:
        i.SaveAsFile(os.path.join('C:/testes/email_download', i.FileName))

I don't know if in your case the OpenSharedItem method can help ...

0
votes

Firstly, try to release the message as soon as you are done with it using Marshal.ReleaseComObject(). This may or may not help since Outlook likes to cache its last opened item.
Secondly, you are logging off from Outlook while it might still be running and visible to the user - Outlook is a singleton, so you will end up with the existing instance if it was already running. Either don't call Logoff at all, or check that there are no open inspectors and explorers.

You can also use Redemption for that - call RDOSession.GetMessageFromMsgFile.
If you need to release the message immediately after you are done, call Marshal.ReleaseComObject()
In case of Redemption, you can also cast RDOMail object to the IDisposable interface and call IDisposable.Dispose().