13

I am creating an excel application with c#. Since I will maintain the excel file in urgency I want to keep its handler open. I want to keep the excel process id so I will be able to kill it in case the system crashs.

How can I get the Excel Pid when creating it?

svick
  • 236,525
  • 50
  • 385
  • 514
yoavba
  • 401
  • 2
  • 6
  • 13

2 Answers2

45
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.Diagnostics;

class Sample
{
    [DllImport("user32.dll")]
    static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

    Process GetExcelProcess(Excel.Application excelApp)
    {
        int id;
        GetWindowThreadProcessId(excelApp.Hwnd, out id);
        return Process.GetProcessById(id);
    }
}
Nick Spreitzer
  • 10,242
  • 4
  • 35
  • 58
-1

Here's an example of how to open an Excel file using Excel-Interop, and properly disposing the instance (source: google)

    Application ExcelObj = new Application();
    Workbook WB = ExcelObj.Workbooks.Open(fileName,
        0, true, 5, "", "", true, XlPlatform.xlWindows, "\t",
        false, false, 0, true, false, false);
    Sheets sheets = WB.Worksheets;
    Worksheet WS = (Worksheet)sheets.get_Item(1);
    Range excelRange = WS.UsedRange;

        ... (DO STUFF?)

        // Get rid of everything - close Excel
        while (Marshal.ReleaseComObject(WB) > 0) { }
        WB = null;
        while (Marshal.ReleaseComObject(sheets) > 0) { }
        sheets = null;
        while (Marshal.ReleaseComObject(WS) > 0) { }
        WS = null;
        while (Marshal.ReleaseComObject(excelRange) > 0) { }
        excelRange = null;
        GC();
        ExcelObj.Quit();
        while (Marshal.ReleaseComObject(ExcelObj) > 0) { }
        ExcelObj = null;
        GC();

    public static void GC()
    {
        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();
        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();
    }
Shai
  • 25,159
  • 9
  • 44
  • 67
  • Probably downvoted because it doesn't answer the question! If Excel goes out to lunch, which it often does, releasing all your references to it is not going to kill it. You NEED the process id. – Noah Yetter Feb 29 '12 at 15:41
  • 5
    Yes, you do. Excel processes started through COM are not child processes of your process, they are children of svchost.exe. If Excel is performing a blocking operation such as QueryTable.Refresh(), and your process exits, excel.exe will not die. If you're doing those refreshes in threads or subprocesses, which you might need to terminate, you're doomed to accumulate zombie excel processes, UNLESS you can track their process id's and kill them. – Noah Yetter Mar 01 '12 at 16:47
  • @NoahYetter I've been working with Excel through COM for the past 3 years and have never had problems with zombie processes using this code. – Shai Mar 02 '12 at 11:06
  • 1
    Have you ever used QueryTable.Refresh()? Seriously, try it. Create a thread or subprocess, launch excel, load a workbook, start a long-running Refresh(), then terminate your thread/process. Instant zombie excel. – Noah Yetter Mar 02 '12 at 17:05