dapanther Posted December 30, 2004 Posted December 30, 2004 Hi, I am having the same issues with MS Word running on XP with Office 2000 (and under XP, seperate test machine). I have the doc closed and nulled all references to Word and it is still keeping alive. There has to be a method that actually works other than the thread killing mentioned above. One note though is that the same code under VB.NET (converted of course) completes flawlessly. So, it leaves me to believe that it is an issue with either GC or how C# handles the COM objects. Anyone else have any thoughts? dapanther Quote
dapanther Posted December 30, 2004 Author Posted December 30, 2004 Oh, I made a mistake in the previous post. I am using Office 2003 running on XP and I am also compiling seperately on a XP machine running Office 2000. Both instances are having the same issues when trying to close Word under C#. dapanther Quote
Mike_R Posted December 30, 2004 Posted December 30, 2004 (edited) There really are only 3 basic mechanisms: (1) Use Marshal.ReleaseCOMObject() (2) Use GC.Collect() (3) Use Process.Kill or the like Version 3, using Process.Kill or the like is brutal, and I would never use it if at all possible. Version 1, using Marshal.ReleaseCOMObject() is, technically, the correct way to go, but it is almost impossible to use in practice. You must call it on absolutely every COM Object that you access. The problem is that it must be used on all COM Objects that you access, not just the COM Object Variables that you utilize. Technically, it is possible to do right, but the resultant code is very awkward and I feel that it is virtually impossible to make a medium-scale or larger project that does not have a mistake somewhere. And if you do, there is no way to track it down... :( Version two is the way to go. You call GC.Collect explicitly, but only after all your COM Object variables hove been set = 0, or have gone out of scope. So the end of your routine might look something like this: wdApp.Quit wdApp = Nothing GC.Collect If you have other Document Objects or the like, then you must set those variables = Nothing as well before calling GC.Collect. It is critical that all COM Object Variables are Set = Nothing before calling GC.Collect. The good news is that other routines using local object vars, will have had their local vars go out of scope already. So you don't have to worry about those. (Ignoring local-scoped objects in other routines is a luxury that you cannot afford if using the Marshal.ReleaseCOMObject approach.) Anyway, give the GC.Collect approach a try. I think it will work... Fingers crossed...! Edited December 30, 2004 by Mike_R Quote Posting Guidelines Avatar by Lebb
dapanther Posted January 3, 2005 Author Posted January 3, 2005 Mike, Thanks for your insight into this. I did find something out over the long weekend regarding this. Basically what I was trying to do was create an application that would take in data, do a mail merge on the doc and send the doc's through Outlook. Now, all that was relatively easy until I ran into the process not ending issue I had with Word. Anyhow, I had Outlook already running when I would debug the code and the default editor is Word, so take a guess why I could not kill Word. Anyhow, I appreciate all your effort into this. See you on the boards... dapanther There really are only 3 basic mechanisms: (1) Use Marshal.ReleaseCOMObject() (2) Use GC.Collect() (3) Use Process.Kill or the like Version 3, using Process.Kill or the like is brutal, and I would never use it if at all possible. Version 1, using Marshal.ReleaseCOMObject() is, technically, the correct way to go, but it is almost impossible to use in practice. You must call it on absolutely every COM Object that you access. The problem is that it must be used on all COM Objects that you access, not just the COM Object Variables that you utilize. Technically, it is possible to do right, but the resultant code is very awkward and I feel that it is virtually impossible to make a medium-scale or larger project that does not have a mistake somewhere. And if you do, there is no way to track it down... :( Version two is the way to go. You call GC.Collect explicitly, but only after all your COM Object variables hove been set = 0, or have gone out of scope. So the end of your routine might look something like this: wdApp.Quit wdApp = Nothing GC.Collect If you have other Document Objects or the like, then you must set those variables = Nothing as well before calling GC.Collect. It is critical that all COM Object Variables are Set = Nothing before calling GC.Collect. The good news is that other routines using local object vars, will have had their local vars go out of scope already. So you don't have to worry about those. (Ignoring local-scoped objects in other routines is a luxury that you cannot afford if using the Marshal.ReleaseCOMObject approach.) Anyway, give the GC.Collect approach a try. I think it will work... Fingers crossed...! Quote
Recommended Posts