How do I get the Process ID from a created "Excel.Application" object?
excel, vb.net
Solution
Actually never mind; I figured it out. This is a very clean, precisely targeted solution that kills the exact process that was started. It doesn't interfere with any other process or file that the user might have open. In my experience killing the process after closing files and quitting Excel is the fastest and easiest way to deal with Excel. Here is a knowledge Base article describing the problem and Microsoft's recommended solution.
Please note that this solution does NOT kill the Excel application. It only kills the empty process shell if any pointers have not been properly disposed. Excel itself DOES actually quit when we call `xlApp.quit()`. This can be confirmed by trying to attach the running Excel application which will fail because Excel is not running at all.
Many people don't recommend killing the process; See How to properly clean up Excel interop objects and Understanding Garbage Collection in .net
On the other hand many people don't recommend using GC.Collect. See What's so wrong about using GC.Collect()?
Be sure to Close any open workbooks, Quit the application, Release the xlApp object. Finally check to see if the process is still alive and if so then kill it.
Private Declare Auto Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Integer
Sub testKill()
'start the application
Dim xlApp As Object = CreateObject("Excel.Application")
'do some work with Excel
'close any open files
'get the window handle
Dim xlHWND As Integer = xlApp.hwnd
'this will have the process ID after call to GetWindowThreadProcessId
Dim ProcIdXL As Integer = 0
'get the process ID
GetWindowThreadProcessId(xlHWND, ProcIdXL)
'get the process
Dim xproc As Process = Process.GetProcessById(ProcIdXL)
'Quit Excel
xlApp.quit()
'Release
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
'set to nothing
xlApp = Nothing
'kill it with glee
If Not xproc.HasExited Then
xproc.Kill()
End If
End Sub
Once I realized that I could get the window handle from Excel, then I just needed the function to get the process ID from the window handle. Hence `GetWindowThreadProcessId` If anyone knows a vb.net way to get that I would be grateful.
Problem
How do I get the Process ID from a running object? ``` Dim xlApp As Object = CreateObject("Excel.Application") ``` I need to use late binding because I can't guarantee which version I will get so using `Microsoft.Office.Interop.Excel` won't work. ``` 'do some work with xlApp xlApp.Quit System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp) xlApp = nothing ``` At this point Excel is still running in the background. I am familiar with all the recommendations to use variables and release them then use: `System.Runtime.InteropServices.Marshal.ReleaseComObject(o)`. This does not work reliably. The work that I'm doing is very complicated. I use for each loops etc using multiple files. It is impossible to release all of the resources in Excel. I need a better option. I'd like to use `Process.Kill` on Excel but I don't know how to get the process from the xlApp object. I don't want to kill all Excel processes because the user might have a workbook open. I tried using `Dim xProc As Process = Process.Start(ExcelPath)` then using `xProc.Kill()` That works sometimes except it's a little tricky to get the correct Excel object using `XLApp = GetObject("Book1").Application` or `XLApp = GetObject("", "Excel.Application")` if the user already has Excel windows open. I need a better option. I can't use `GetActiveObject` or `BindToMoniker` to get the Excel object because they only work with work when using early binding. E.g. `Microsoft.Office.Interop.Excel` How do I get the Process ID from a running object? Edit: Actually I'm not really interested in a rehash on how to get Excel to nicely exit. Many other questions have addressed that. here and here I just want to kill it; cleanly, precisely and directly. I want to kill the exact process that I started and no other.