creating a new VSTO Word Application in almost all cases works. I use this line to create a new instance:
var wordApplication = new Application {Visible = false}
(Application is "Microsoft.Office.Interop.Word.Application")
We do this a lot in unit tests and in some automations. But once or twice in around 1000 calls, the initialization doesn't finalize and the process hangs. (Anyone know the reason?)
To solve this I wrap the instantiation into a timeout and try it again:
var wordApplication = Utilities.CallWithTimeout(
// stuff to do
() => new Application {Visible = false},
// error handler before the TimeoutException happens
() =>
{
var info = "Try to create a WordApplication failed after 15 seconds";
Tracer.TraceEvent(TraceEventType.Error, info, TraceCategory.Application);
KillWordApplicationOnError(before);
},
// timeout
TimeSpan.FromSeconds(15));
(CallWithTimeout: https://gist.github.com/JuergenGutsch/b4b72fcb6a06327a6a41 The retry is done with this method: https://gist.github.com/JuergenGutsch/219e9fe3e5aad1a098f3)
We are killing the Application, by identifying the word process and kill that process. Remember, because the instantiation is hanging, we don't have a Word application to use Quit(), but a winword.exe process is running and we need to kill it. (How we kill the process: https://gist.github.com/JuergenGutsch/92b64117cf51c15bab83)
This solves the problem with the hanging process and we get an new issue, which happens once or twice in around 3000 calls. The new Issue is an security issue, which disables one to all Word add-ins, also some custom dotm templates which contain VBA macros.
We don't get any Exception and we don't get any entries in the event log. Except this one right after killing the process:
An exception of type 'System.Runtime.InteropServices.COMException' occurred in BIS.MEDCS.Connectivity.Word.VSTO.dll but was not handled in user code
Additional information: Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
But this exception is handled with the retry and the instantiation works with the next try.
Does anyone of you know what is happening here?
In addition to @Eugene, Garbage Collection is not happening 'immediately' but on the 'best opportunity' and you may see a slow down in cleaning running instances (especially if the COM objects have not been released properly)
To force Garbage Collection to execute:
GC.Collect
GC.WaitForPendingFinalizers
GC.Collect
GC.WaitForPendingFinalizers
Just as a head up, the duplicate is not a mistake, it is done due to the way .NET objects are stored in memory so you need to exec the Collect and WaitForPendingFinalizers twice.
So first make sure you release your objects yourself and on a final resort collect the garbage.
You need to release underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release a Word object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article. The article is related to OUtlook, but the same rules can be applied to all Office applications including Word.
Leaving COM objects (not decreasing the reference counter) in memory may cause processes left running after the host is closed.
User contributions licensed under CC BY-SA 3.0