Monday, April 6, 2009

Ghost Instance Problem in office application

Hi All,

A number of office programmers face the Ghost Instance issue while developing office applications. The ghost instance is an instance of office application which is not closed properly. In this scenario, you will be able to see the application entry in the Porcess list of task manager but it will not be visible for the user. I will explain the context by using an example of powerpoint Addin(Obviously in dot net).

Q. How does it occur?

Ans. I create a PowerPoint(aka, PP)Addin, and in that PP Addin I try to create an excel(aka, XL) Application object. Now if I do extensive programming using XL objects(like Range, Shapes, Worksheet etc), these InterOP variables stay in Memory and not handled by the CLR. You will need to explicitly release every COM Object by using System.Runtime.InteropServices.Marshal.ReleaseCOMObject(theObjectToBeReleased) method. But, even after releasing the objects few of the instances keep on running in memory. So if the variables are running in the memory, and I try to close the excel, the excel gets closed but its process keeps on running in the task Manager List. When we hit close button(the cross button in TopLeftHand corner) in Excel, the CLR first closes all the AddIns opened, and then closes the excel window. If there is any COM running in the memory the AddIns get removed but the CLR is unable to close the Excel properly. The result is Ghost Instance. In case of Ghost Instance running in the task manager, if we open any Excel File by double clicking the file, it will open the file but it will Not load any Addins. Reason is barely simple, the Addins were already closed by CLR but not the Excel Application Instance. So the file is actually opened in the previous Excel Ghost Instance.

Q. What is the solution?
Ans. One solution to the problem is: Go to task Manager, Process Tab, and kill the Excel.EXE instance.
The other solution is to include the following approach in AddInShutDown event of your code. This work around uses the Process Class.

1. Try to get the list of Processes by GetProcessByName method :
Process[] processes = Process.GetProcessesByName("EXCEL")
2. Run through Each Process in the processes Array and check if process.MainWindowHandle.ToInt64() is equal to 0. If this is 0 then you will need to kill the process right away.
3. The only thing you will need to take care is, to create a time Lag so that all the AddIns should shut down first then you will need to call the above steps.
4. Creating a Time lag means, you can use a separate EXE, which will run the above steps say 5 seconds after the Excel Closing event was fired.

Hope this helps :)

Thanks,
Vikas

7 comments:

Anjum said...

Hi Vikas,
Thanks for the solution..Is there any way to do this in VBA????

Excel Noob said...

Hi Anjum,

No, it will not be effective as such. This code will need to be implemented to the Dot Net / Java code which is eventually creating the application object.

Thanks,
Vikas

Anjum said...

Hi Vikas,
Thanks for giving base for this solution. Somehow I tried to implement the same in VBA. Thanks once again.

Vikas Bhandari said...

Great!!!! but there is a problem if you try to achieve the same using VBA. If there is a ghost instance for word, and you double click any file, it will not load your java addin.

Thanks,
Vikas

jacks said...

hi! i like your blog.. Thanks for the sharing... easy to download

Archana said...

Hi Vikash,

It's really very helpfull. It sorted out my problem.

Thanks,
Archana

Vikas Bhandari said...

Hi Archana,

Glad it helped! but my name is Vikas and not vikash :)

Cheers!
Vikas