Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the Process ID from a created "Excel.Application" object?

Tags:

excel

vb.net

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.

like image 669
D_Bester Avatar asked Jul 20 '13 05:07

D_Bester


People also ask

How do you find the PID in Excel?

CREATE "Excel. Application" hExcel. RUN GetWindowThreadProcessId (hExcel:Hwnd, OUTPUT processIdForExcel). DISPLAY processIdForExcel.

What is Application object in Excel?

The Application object contains: Application-wide settings and options. Methods that return top-level objects, such as ActiveCell, ActiveSheet, and so on.

How do you make an application object in Excel?

To create an ActiveX object, assign the object returned by CreateObject to an object variable. This code starts the application creating the object, in this case, a Microsoft Excel spreadsheet. After an object is created, you reference it in code by using the object variable you defined.


1 Answers

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.

like image 175
D_Bester Avatar answered Oct 12 '22 12:10

D_Bester