469,571 Members | 1,696 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,571 developers. It's quick & easy.

Office application does not quit

Max

I have the following code on a form that launches Microsoft Outlook and creates a new email message for the user:

Expand|Select|Wrap|Line Numbers
  1.  
  2. Outlook.Application oApp = new Outlook.Application();
  3. Outlook.MailItem oMail = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
  4. oMail.HTMLBody = "SOME HTML TEXT HERE";
  5. oMail.Display(oApp);
  6.  
  7. oMail.Close(Outlook.OlInspectorClose.olDiscard);
  8. NAR(oMail);
  9. oApp.Quit();
  10. NAR(oApp);
  11. GC.Collect();
  12. GC.WaitForPendingFinalizers();
  13.  
  14.  
where NAR(....) is defined as follows:

Expand|Select|Wrap|Line Numbers
  1.  
  2. private void NAR(object o)
  3. {
  4. try{ System.Runtime.InteropServices.Marshal.ReleaseComObject(o); }
  5. catch{}
  6. finally{ o = null; }
  7. }
  8.  
  9.  
Problem is that when the Outlook application created is closed, it still resides
in memory. A quick check in the task list shows OUTLOOK.EXE wasting memory
space. If I run this code 10 times it will waste 180-250MB of memory. The only
way to kill it is by going to the system tray and manually removing it. How can
I force OUTLOOK.EXE to die? The Garbage collector does not seem to be doing a
good job. In fact the above code works and kills OUTLOOK.EXE when
Expand|Select|Wrap|Line Numbers
  1.  oMail.Display(oApp); 
is not presend and the Outlook application is not
shown, but when it is shown to the user then it just lies in memory even after it was closed.

Nov 17 '05 #1
6 4982
This ...
oMail.Display(oApp);
instructs Outlook to switch to interactive mode, so...
the outlook server EXE is waiting for a "Send" command, that means you need
to press the Send button or you have to execute a oMail.Send(); instruction
in the client.

All this GC stuff and ReleaseComObject stuff is not required here, the GC
has nothing to do with all this.

Willy.
"Max" <ma******@yahoo.com> wrote in message
news:uY**************@tk2msftngp13.phx.gbl...

I have the following code on a form that launches Microsoft Outlook and
creates a new email message for the user:

Expand|Select|Wrap|Line Numbers
  1.  Outlook.Application oApp = new Outlook.Application();
  2.  Outlook.MailItem oMail =
  3.  (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
  4.  oMail.HTMLBody = "SOME HTML TEXT HERE";
  5.  oMail.Display(oApp);
  6.  oMail.Close(Outlook.OlInspectorClose.olDiscard);
  7.  NAR(oMail);
  8.  oApp.Quit();
  9.  NAR(oApp);
  10.  GC.Collect();
  11.  GC.WaitForPendingFinalizers();
  12.  

where NAR(....) is defined as follows:

Expand|Select|Wrap|Line Numbers
  1.  private void NAR(object o)
  2.  {
  3.    try{ System.Runtime.InteropServices.Marshal.ReleaseComObject(o); }
  4.    catch{}
  5.    finally{ o = null; }
  6.  }
  7.  

Problem is that when the Outlook application created is closed, it still
resides in memory. A quick check in the task list shows OUTLOOK.EXE
wasting memory space. If I run this code 10 times it will waste 180-250MB
of memory. The only way to kill it is by going to the system tray and
manually removing it. How can I force OUTLOOK.EXE to die? The Garbage
collector does not seem to be doing a good job. In fact the above code
works and kills OUTLOOK.EXE when
Expand|Select|Wrap|Line Numbers
  1.  oMail.Display(oApp); 
is
not presend and the Outlook application is not shown, but when it is shown
to the user then it just lies in memory even after it was closed.

Nov 17 '05 #2
Max
Thanks for your reply Willy!

What if the user decides not to send this email and just presses the close button in Outlook.
Is there a way to know when the user does this so I can kill the Outlook process programatically
to remove it from memory?

Cheers,
Max

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message news:eg**************@TK2MSFTNGP12.phx.gbl...
This ...
oMail.Display(oApp);
instructs Outlook to switch to interactive mode, so...
the outlook server EXE is waiting for a "Send" command, that means you need
to press the Send button or you have to execute a oMail.Send(); instruction
in the client.

All this GC stuff and ReleaseComObject stuff is not required here, the GC
has nothing to do with all this.

Willy.
"Max" <ma******@yahoo.com> wrote in message
news:uY**************@tk2msftngp13.phx.gbl...

I have the following code on a form that launches Microsoft Outlook and
creates a new email message for the user:

Expand|Select|Wrap|Line Numbers
  1.  Outlook.Application oApp = new Outlook.Application();
  2.  Outlook.MailItem oMail =
  3.  (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
  4.  oMail.HTMLBody = "SOME HTML TEXT HERE";
  5.  oMail.Display(oApp);
  6.  oMail.Close(Outlook.OlInspectorClose.olDiscard);
  7.  NAR(oMail);
  8.  oApp.Quit();
  9.  NAR(oApp);
  10.  GC.Collect();
  11.  GC.WaitForPendingFinalizers();
  12.  

where NAR(....) is defined as follows:

Expand|Select|Wrap|Line Numbers
  1.  private void NAR(object o)
  2.  {
  3.    try{ System.Runtime.InteropServices.Marshal.ReleaseComObject(o); }
  4.    catch{}
  5.    finally{ o = null; }
  6.  }
  7.  

Problem is that when the Outlook application created is closed, it still
resides in memory. A quick check in the task list shows OUTLOOK.EXE
wasting memory space. If I run this code 10 times it will waste 180-250MB
of memory. The only way to kill it is by going to the system tray and
manually removing it. How can I force OUTLOOK.EXE to die? The Garbage
collector does not seem to be doing a good job. In fact the above code
works and kills OUTLOOK.EXE when
Expand|Select|Wrap|Line Numbers
  1.  oMail.Display(oApp); 
is
not presend and the Outlook application is not shown, but when it is shown
to the user then it just lies in memory even after it was closed.


Nov 17 '05 #3

"Max" <ma******@yahoo.com> wrote in message
news:eD*************@TK2MSFTNGP10.phx.gbl...
Thanks for your reply Willy!

What if the user decides not to send this email and just presses the close
button in Outlook. Is there a way to know when the user does this so I can
kill the Outlook process programatically
to remove it from memory?

Cheers,
Max


Well, there is something wrong with your scenario. You are using COM interop
to automate Outlook, but at the same time you are using Outlook in an
interactive fashion, these two don't go well together, whenever you switch
to interactive mode as by calling Display(), you put the responsabilty to
interact and exit the application in the hands of the interactive user, else
you don't show the UI and it's up to the .NET (well, COM) client to clean up
after it has done. In you scenario there is no way for the client
application to know whether the interactiv user doesn't want to send a mail
message.
Really, I wonder why you are doing this.
Willy.
Nov 17 '05 #4
Max
Good question.

I'm working on an application which manages information about units in the field
which could have problems. This requires that we have some kind of "generate a service call" option.
Basically when the user clicks the "Generate service call" button, the email client of choice, whether
it be MS Office 2000/2002/XP/2003 or Outlook Expressed is launched and information about the
deffective unit is dumped into the body of the email. The user then selects the recipient - ie some service
person who needs to go out in the field and fix the unit, and sends the email OR could technically just close
the Outlook window created.

I'm actually using late binding in my code, not the example I posted earlier. As it turns out when an instance
of Outlook is launched, even if the user clicks on the "Send" button in Outlook to send the message and
the window closes, if you check in the task manager OUTLOOK.EXE still hangs in memory. This also
happens even if the user just closes the Outlook window without sending any message.

I could just grab the address book from either program and create my own email window with the contacts
on one side and I won't have to worry about launching any Outlook or Outlook Express instance, but.... I
kind of wanted to just launch the email application of choice.

I suppose it's not possible to do all this in .NET?


"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message news:eG**************@TK2MSFTNGP12.phx.gbl...

"Max" <ma******@yahoo.com> wrote in message
news:eD*************@TK2MSFTNGP10.phx.gbl...
Thanks for your reply Willy!

What if the user decides not to send this email and just presses the close
button in Outlook. Is there a way to know when the user does this so I can
kill the Outlook process programatically
to remove it from memory?

Cheers,
Max


Well, there is something wrong with your scenario. You are using COM interop
to automate Outlook, but at the same time you are using Outlook in an
interactive fashion, these two don't go well together, whenever you switch
to interactive mode as by calling Display(), you put the responsabilty to
interact and exit the application in the hands of the interactive user, else
you don't show the UI and it's up to the .NET (well, COM) client to clean up
after it has done. In you scenario there is no way for the client
application to know whether the interactiv user doesn't want to send a mail
message.
Really, I wonder why you are doing this.
Willy.

Nov 17 '05 #5
Inline ***

Willy.

"Max" <ma******@yahoo.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
Good question.

I'm working on an application which manages information about units in the
field
which could have problems. This requires that we have some kind of
"generate a service call" option.
Basically when the user clicks the "Generate service call" button, the
email client of choice, whether
it be MS Office 2000/2002/XP/2003 or Outlook Expressed is launched and
information about the
deffective unit is dumped into the body of the email. The user then
selects the recipient - ie some service
person who needs to go out in the field and fix the unit, and sends the
email OR could technically just close
the Outlook window created.

I'm actually using late binding in my code, not the example I posted
earlier. As it turns out when an instance
of Outlook is launched, even if the user clicks on the "Send" button in
Outlook to send the message and the window closes, if you check in the
task manager OUTLOOK.EXE still hangs in memory. This also
happens even if the user just closes the Outlook window without sending
any message.

*** I understand, but you can't send a Quit command from the client as this
will interfere with the UI user do you?
This is what Outlook is waiting for to go away. What you should do is
communicate back to the client to signal that the UI user has done with it,
the COM client waits to receive an event after which he calls Quit to get
rid of the server (Outlook.exe). Another thing you could do is connect to a
running instance instead of creating a new instance of the Outlook app.
(Check the Marshall class for the GetActiveObject()). If Outlook is allready
running it connects to the running instance, otherwise it starts a new
instance.

I could just grab the address book from either program and create my own
email window with the contacts
on one side and I won't have to worry about launching any Outlook or
Outlook Express instance, but.... I kind of wanted to just launch the
email application of choice.

I suppose it's not possible to do all this in .NET?


"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:eG**************@TK2MSFTNGP12.phx.gbl...

"Max" <ma******@yahoo.com> wrote in message
news:eD*************@TK2MSFTNGP10.phx.gbl...
Thanks for your reply Willy!

What if the user decides not to send this email and just presses the
close button in Outlook. Is there a way to know when the user does this
so I can kill the Outlook process programatically
to remove it from memory?

Cheers,
Max


Well, there is something wrong with your scenario. You are using COM
interop to automate Outlook, but at the same time you are using Outlook
in an interactive fashion, these two don't go well together, whenever you
switch to interactive mode as by calling Display(), you put the
responsabilty to interact and exit the application in the hands of the
interactive user, else you don't show the UI and it's up to the .NET
(well, COM) client to clean up after it has done. In you scenario there
is no way for the client application to know whether the interactiv user
doesn't want to send a mail message.
Really, I wonder why you are doing this.
Willy.


Nov 17 '05 #6
Max
Thanks for your reply Willy.
*** I understand, but you can't send a Quit command from the client as this
will interfere with the UI user do you? No no, I am not using Quit() in my code, I'm just creating the instance and
giving it to the user. What I posted earlier was just me "experimenting" with early
binding to see how to kill the running instance with Quit() and it wasn't working :))
What you should do is communicate back to the client to signal that the UI user has
done with it, the COM client waits to receive an event after which he calls Quit to get
rid of the server (Outlook.exe). This is the part I don't get. I don't know how to communicate from the Outlook UI user
to the client. I don't have control of Outlook, the user does. I assume there is some way
I could wait for an event but I don't know what to wait for and how to wait for it.
After I use Display(....) the client application keeps running and does something else,
while the user looks at the message in Outlook and sends it (or closes it) whenever s/he
decides. What event(s) is(are) there to let the client know what Outlook did? Like
how do I know in the client when the user sends the message or closes Outlook so I can
call Quit() in the client? What event does the COM client wait for before calling Quit()?


"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message news:e3**************@TK2MSFTNGP15.phx.gbl... Inline ***

Willy.

"Max" <ma******@yahoo.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
Good question.

I'm working on an application which manages information about units in the
field
which could have problems. This requires that we have some kind of
"generate a service call" option.
Basically when the user clicks the "Generate service call" button, the
email client of choice, whether
it be MS Office 2000/2002/XP/2003 or Outlook Expressed is launched and
information about the
deffective unit is dumped into the body of the email. The user then
selects the recipient - ie some service
person who needs to go out in the field and fix the unit, and sends the
email OR could technically just close
the Outlook window created.

I'm actually using late binding in my code, not the example I posted
earlier. As it turns out when an instance
of Outlook is launched, even if the user clicks on the "Send" button in
Outlook to send the message and the window closes, if you check in the
task manager OUTLOOK.EXE still hangs in memory. This also
happens even if the user just closes the Outlook window without sending
any message.


*** I understand, but you can't send a Quit command from the client as this
will interfere with the UI user do you?
This is what Outlook is waiting for to go away. What you should do is
communicate back to the client to signal that the UI user has done with it,
the COM client waits to receive an event after which he calls Quit to get
rid of the server (Outlook.exe). Another thing you could do is connect to a
running instance instead of creating a new instance of the Outlook app.
(Check the Marshall class for the GetActiveObject()). If Outlook is allready
running it connects to the running instance, otherwise it starts a new
instance.

I could just grab the address book from either program and create my own
email window with the contacts
on one side and I won't have to worry about launching any Outlook or
Outlook Express instance, but.... I kind of wanted to just launch the
email application of choice.

I suppose it's not possible to do all this in .NET?


"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:eG**************@TK2MSFTNGP12.phx.gbl...

"Max" <ma******@yahoo.com> wrote in message
news:eD*************@TK2MSFTNGP10.phx.gbl...
Thanks for your reply Willy!

What if the user decides not to send this email and just presses the
close button in Outlook. Is there a way to know when the user does this
so I can kill the Outlook process programatically
to remove it from memory?

Cheers,
Max
Well, there is something wrong with your scenario. You are using COM
interop to automate Outlook, but at the same time you are using Outlook
in an interactive fashion, these two don't go well together, whenever you
switch to interactive mode as by calling Display(), you put the
responsabilty to interact and exit the application in the hands of the
interactive user, else you don't show the UI and it's up to the .NET
(well, COM) client to clean up after it has done. In you scenario there
is no way for the client application to know whether the interactiv user
doesn't want to send a mail message.
Really, I wonder why you are doing this.
Willy.

Nov 17 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by DC Gringo | last post: by
6 posts views Thread by Luke Vogel | last post: by
1 post views Thread by Alberto | last post: by
2 posts views Thread by ChrisFrohlich | last post: by
reply views Thread by suresh191 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.