c# Outlook Interop Not Closing

N

nickname

I am trying to automate outlook to save attachments to emails in a folder
c:\test and then move the emails from the inbox to a folder (in outlook)
called "Auto Processed Emails". I have got this to work, however outlook will
not close itself afterwards. The code i have written is below, can somebody
let me know what i have done wrong?

Outlook.Application app = new Outlook.Application();

Outlook.NameSpace ns = app.GetNamespace("MAPI");

ns.Logon("test", Type.Missing, Type.Missing, true);

//Fetch mail
ns.SendAndReceive(false);
//block 30seconds give time to process
System.Threading.Thread.Sleep(30);

Outlook.MAPIFolder inBox =
ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

Outlook.Items inboxItems = inBox.Items;
for (int i = 1; i <= inboxItems.Count; i++)
{
object item = inboxItems;

if (item is Outlook.MailItem)
{
Outlook.MailItem mailItem = (Outlook.MailItem)item;

//Check Drop Folder Exists
bool folderFound = false;

Outlook.MAPIFolder parentFolder =
(Outlook.MAPIFolder)inBox.Parent;
Outlook.Folders foldersCollection = parentFolder.Folders;

for (int j = 1; j <= foldersCollection.Count; j++)
{
Outlook.MAPIFolder currentFolder =
foldersCollection[j];

if (currentFolder.Name == "Auto Processed Emails")
{
folderFound = true;
}

Marshal.ReleaseComObject(currentFolder).ToString();
}

if (!folderFound)
{
return;
}

//Save Attachments
for (int j = 1; j <= mailItem.Attachments.Count; j++)
{
Outlook.Attachment oAttach = mailItem.Attachments[j];

oAttach.SaveAsFile(Path.Combine(@"c:\test",
oAttach.FileName));

Marshal.ReleaseComObject(oAttach).ToString();
}
}
Marshal.ReleaseComObject(item);
}
Marshal.ReleaseComObject(inboxItems);
Marshal.ReleaseComObject(inBox);
ns.Logoff();
Marshal.ReleaseComObject(ns);
app.Quit();
Marshal.ReleaseComObject(app);
GC.Collect();
GC.WaitForPendingFinalizers();
 
S

SvenC

Hi,
I am trying to automate outlook to save attachments to emails in a
folder c:\test and then move the emails from the inbox to a folder
(in outlook) called "Auto Processed Emails". I have got this to work,
however outlook will not close itself afterwards. The code i have
written is below, can somebody let me know what i have done wrong?

Outlook.Application app = new Outlook.Application();
Outlook.NameSpace ns = app.GetNamespace("MAPI");

Do you happen to run any additional MAPI software like PDA synchronizing
software?
 
W

Walter Wang [MSFT]

Hi,

Which Outlook version are you using?


It seems your code is doing everything correctly as following KB suggested:

#Office application does not quit after automation from Visual Studio .NET
client
http://support.microsoft.com/kb/317109



I'm currently consulting your question within our internal discussion list
to see if there's any known issue on this. I'll keep you posted.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi,

Please try following code to see if it works:

private void button2_Click(object sender, EventArgs e)
{
Application app = new Application();
NameSpace ns = app.GetNamespace("MAPI");
MAPIFolder inbox = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
MailItem o = (MailItem) inbox.Items.GetFirst();
MessageBox.Show(o.Subject);
o.Close(OlInspectorClose.olDiscard);
Marshal.ReleaseComObject(o);
o = null;
Marshal.ReleaseComObject(inbox);
inbox = null;
ns.Logoff();
Marshal.ReleaseComObject(ns);
ns = null;
app.Quit();
Marshal.ReleaseComObject(app);
app = null;

GC.Collect();
GC.WaitForPendingFinalizers();
}



This code works on my side on a Outlook 2000 system.



Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

nickname

I am using Outlook 2007 and the sample code works fine. However my code that
loops through messages does not. Do you have any ideas why?

Thanks
 
S

SvenC

nickname said:
I am trying to automate outlook to save attachments to emails in a
folder c:\test and then move the emails from the inbox to a folder
(in outlook) called "Auto Processed Emails". I have got this to work,
however outlook will not close itself afterwards. The code i have
written is below, can somebody let me know what i have done wrong?

Outlook.Application app = new Outlook.Application();

Outlook.NameSpace ns = app.GetNamespace("MAPI");

ns.Logon("test", Type.Missing, Type.Missing, true);

//Fetch mail
ns.SendAndReceive(false);
//block 30seconds give time to process
System.Threading.Thread.Sleep(30);

Outlook.MAPIFolder inBox =
ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

Outlook.Items inboxItems = inBox.Items;

This is good practice: you store the collection in a variable so you can
call ReleaseComObject. Later on with attachments you are not that careful.
for (int i = 1; i <= inboxItems.Count; i++)
{
object item = inboxItems;

if (item is Outlook.MailItem)
{
Outlook.MailItem mailItem = (Outlook.MailItem)item;

//Check Drop Folder Exists
bool folderFound = false;

Outlook.MAPIFolder parentFolder =
(Outlook.MAPIFolder)inBox.Parent;
Outlook.Folders foldersCollection =
parentFolder.Folders;


You are missing a ReleaseComObject(parentFolder) and (foldersCollection)
later on.
for (int j = 1; j <= foldersCollection.Count; j++)
{
Outlook.MAPIFolder currentFolder =
foldersCollection[j];

if (currentFolder.Name == "Auto Processed
Emails") {
folderFound = true;
}

Marshal.ReleaseComObject(currentFolder).ToString(); }

if (!folderFound)
{
return;
}

//Save Attachments

Use an extra variable for the attachments collection so you can call
ReleaseComObject on that variable.
for (int j = 1; j <= mailItem.Attachments.Count;
j++) {
Outlook.Attachment oAttach =
mailItem.Attachments[j];

oAttach.SaveAsFile(Path.Combine(@"c:\test",
oAttach.FileName));

Marshal.ReleaseComObject(oAttach).ToString();
}
}
Marshal.ReleaseComObject(item);
}
Marshal.ReleaseComObject(inboxItems);
Marshal.ReleaseComObject(inBox);
ns.Logoff();
Marshal.ReleaseComObject(ns);
app.Quit();
Marshal.ReleaseComObject(app);

GC.Collect();
GC.WaitForPendingFinalizers();

Those two should not be necessary with the correct ReleaseComObject calls.
 
W

Walter Wang [MSFT]

That's good. My simpler code snippet is to prove that there's no other
addin or apps are interfering with the normal cleanup routines.

As SvenC pointed out, you probably need to make sure every intermediate COM
object reference is released correctly using Marshal.ReleaseComObject(),
for example, the mailItem.Attachments should be used as how you used the
inboxItems.

Also, you may need to comment out some part of the code to see if it works
or not, this way you should be able to pin down to a single line of the
code that is causing the issue.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

nickname

Thank you for the reply, I have now got it working :) Had to be something
silly.

Do you happen to know why this causes outlook not to close:

Outlook.MAPIFolder parentFolder1 = (Outlook.MAPIFolder)inBox.Parent;
Outlook.Folders foldersCollection1 =
parentFolder1.Folders;

for (int j = 1; j <=
foldersCollection1.Count; j++)
{
Outlook.MAPIFolder currentFolder =
foldersCollection1[j];

if (currentFolder.Name == "Auto
Processed Emails")
{
mailItem.Move(currentFolder);
}


Marshal.ReleaseComObject(currentFolder);
}


Marshal.ReleaseComObject(foldersCollection1);
Marshal.ReleaseComObject(parentFolder1);


if i comment out the line:

mailItem.Move(currentFolder);

Outlook closes fine.

Any ideas?

Thanks

SvenC said:
nickname said:
I am trying to automate outlook to save attachments to emails in a
folder c:\test and then move the emails from the inbox to a folder
(in outlook) called "Auto Processed Emails". I have got this to work,
however outlook will not close itself afterwards. The code i have
written is below, can somebody let me know what i have done wrong?

Outlook.Application app = new Outlook.Application();

Outlook.NameSpace ns = app.GetNamespace("MAPI");

ns.Logon("test", Type.Missing, Type.Missing, true);

//Fetch mail
ns.SendAndReceive(false);
//block 30seconds give time to process
System.Threading.Thread.Sleep(30);

Outlook.MAPIFolder inBox =
ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

Outlook.Items inboxItems = inBox.Items;

This is good practice: you store the collection in a variable so you can
call ReleaseComObject. Later on with attachments you are not that careful.
for (int i = 1; i <= inboxItems.Count; i++)
{
object item = inboxItems;

if (item is Outlook.MailItem)
{
Outlook.MailItem mailItem = (Outlook.MailItem)item;

//Check Drop Folder Exists
bool folderFound = false;

Outlook.MAPIFolder parentFolder =
(Outlook.MAPIFolder)inBox.Parent;
Outlook.Folders foldersCollection =
parentFolder.Folders;


You are missing a ReleaseComObject(parentFolder) and (foldersCollection)
later on.
for (int j = 1; j <= foldersCollection.Count; j++)
{
Outlook.MAPIFolder currentFolder =
foldersCollection[j];

if (currentFolder.Name == "Auto Processed
Emails") {
folderFound = true;
}

Marshal.ReleaseComObject(currentFolder).ToString(); }

if (!folderFound)
{
return;
}

//Save Attachments

Use an extra variable for the attachments collection so you can call
ReleaseComObject on that variable.
for (int j = 1; j <= mailItem.Attachments.Count;
j++) {
Outlook.Attachment oAttach =
mailItem.Attachments[j];

oAttach.SaveAsFile(Path.Combine(@"c:\test",
oAttach.FileName));

Marshal.ReleaseComObject(oAttach).ToString();
}
}
Marshal.ReleaseComObject(item);
}
Marshal.ReleaseComObject(inboxItems);
Marshal.ReleaseComObject(inBox);
ns.Logoff();
Marshal.ReleaseComObject(ns);
app.Quit();
Marshal.ReleaseComObject(app);

GC.Collect();
GC.WaitForPendingFinalizers();

Those two should not be necessary with the correct ReleaseComObject calls.
 
W

Walter Wang [MSFT]

Hi,

Would you please test following code? It's working correctly on my side
with Vista and Outlook 2007:

(I don't need to login so I removed the call to ns.Login)


Outlook.MAPIFolder GetAutoProcessEmailsFolder(Outlook.MAPIFolder
inbox)
{
Outlook.MAPIFolder targetFolder = null;
Outlook.MAPIFolder parentFolder =
(Outlook.MAPIFolder)inbox.Parent;
Outlook.Folders foldersCollection = parentFolder.Folders;

for (int j = 1; j <= foldersCollection.Count; j++)
{
Outlook.MAPIFolder currentFolder = foldersCollection[j];

if (currentFolder.Name == "Auto Processed Emails")
{
targetFolder = currentFolder;
break;
}

Marshal.ReleaseComObject(currentFolder).ToString();
}
Marshal.ReleaseComObject(foldersCollection);
Marshal.ReleaseComObject(parentFolder);

return targetFolder;
}

private void button1_Click(object sender, EventArgs e)
{
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace ns = app.GetNamespace("MAPI");
Outlook.MAPIFolder inBox =
ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFold
erInbox);
Outlook.MAPIFolder target = GetAutoProcessEmailsFolder(inBox);

if (target != null)
{
Outlook.Items inboxItems = inBox.Items;
for (int i = 1; i <= inboxItems.Count; i++)
{
Outlook.MailItem mailItem = inboxItems as
Outlook.MailItem;
if (mailItem != null)
{
mailItem.Move(target);

Outlook.Attachments attachments =
mailItem.Attachments;
for (int j = 1; j <= attachments.Count; j++)
{
Outlook.Attachment oAttach = attachments[j];
oAttach.SaveAsFile(Path.Combine(@"c:\temp",
oAttach.FileName));
Marshal.ReleaseComObject(oAttach);
}
Marshal.ReleaseComObject(attachments);
Marshal.ReleaseComObject(mailItem);
}

}
Marshal.ReleaseComObject(inboxItems);
Marshal.ReleaseComObject(target);
}
Marshal.ReleaseComObject(inBox);
ns.Logoff();
Marshal.ReleaseComObject(ns);
app.Quit();
Marshal.ReleaseComObject(app);

GC.Collect();
GC.WaitForPendingFinalizers();
}


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi,

Is the issue solved now? Would you please reply here to let us know the
status of this post? Thanks.



Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top