How to get window or process handle of a certain Excel process?
How can we get the application window handle or process handle of the excel process which belongs to the excel application instance that we have created? We are using Interop.Excel.dll Version 1.3.0.0. The application class seem to have no HWnd property to call.
Note that it is no solution to simply find all processes with the name excel.exe because we have many excel instances running in parallel and we only want to close a certain instance.
Excel.Application app = new Excel.Application();
// .. do something with excel here
app.Quit();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
// this is in some cases still not enough to get excel killed
uint processID;
GetWindowThreadProcessId((IntPtr)hWnd, out pr开发者_运维知识库ocessID); // how to get HWnd from this Excel application?
Process.GetProcessById((int)processID).Kill();
The application class seem to have no HWnd property to call
The Excel.Application class does have a property Hwnd.
In response to the comment:
We are not using Microsoft.Office.Interop.Excel.dll but instead Interop.Excel.dll which lacks this property
I would generally recommending using the PIA (Microsoft.Office.Interop.Excel.dll). If you have a good reason for not wanting to do so, and the RCW you are using doesn't expose the property for some reason, an alternative would be to use late-binding, e.g.:
typeof(Excel.Application).InvokeMember("Hwnd", BindingFlags.GetProperty, null, app, null);
Although all the answers I got did not help, thanks for the answers anyway. I now found a workaround by myself:
I now created a worker process which periodically checks for excel processes which are older than one minute. Since my excel processing should never last longer than one minute, I can be sure that excel processes older than one minute are done, so I can kill this process.
An other way which comes now to my mind is to get a list of all excel processes before you instantiate your excel process. Then after instantiating you check again. The pid which is new, is the new excel process. Remember to put a lock statement around this to void multithreading issues.
You can use this construction for call Windows API function
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
IntPtr hWnd = FindWindow("XLMAIN", null);
But you must do it BEFORE any operations with Application object - create it, set Visible=true and with next line of code get handle
精彩评论