본문 바로가기
C#

[C#] Interop 한 Excel API 가 정상적으로 종료 되지 않을 때 처리 방안

by Hwoarang757 2024. 9. 3.

[C#] Interop 한 Excel API 가 정상적으로 종료 되지 않을 때 처리 방안

 

WorkBook , WorkBooks 에 대하여 Close 메서드를 호출 하고

ExcelApp를 Quit 메서드를 호출 , 

Marshal.FinalReleaseComObject 를 호출 하여도 EXCEL.exe가 종료되지 않았습니다 .

 

도저히 방법이 없어 , GetWindowThreadProcessId WinAPI를 이용하여 PID를 획득한 후 Process를 Kill 처리 하였습니다.

 

[DllImport("user32.dll")]
public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

IntPtr ptr = new IntPtr(excelApp.Hwnd);
GetWindowThreadProcessId(ptr, out m_nPid);


// GetWindowThreadProcessId WINAPI 함수를 호출 하여 pid를 찾아 Kill 시도 진행 
if (m_nPid != 0)
	System.Diagnostics.Process.GetProcessById((int)m_nPid).Kill();

 

        private void CloseExcelAPI()
        {
            string methodName = MethodBase.GetCurrentMethod().Name;
            txtEventLog.Text = "EXCEL API를 종료 합니다.";
            WriteLog(txtEventLog.Text);
            try
            {
                IntPtr ptr = new IntPtr(excelApp.Hwnd);
                GetWindowThreadProcessId(ptr, out m_nPid);

                Marshal.FinalReleaseComObject(sheets);

                workBook.Close(false, Type.Missing, Type.Missing);
                Marshal.FinalReleaseComObject(workBook);

                excelApp.Workbooks.Close();
                Marshal.FinalReleaseComObject(excelApp.Workbooks);

                excelApp.Quit();
                Marshal.FinalReleaseComObject(excelApp);

                // Cleanup:
                GC.Collect();
                GC.WaitForPendingFinalizers();

            }
            catch (Exception exception)
            {
                Console.WriteLine(string.Format("{0} {1}", methodName, exception.ToString()));
                WriteLog(string.Format("{0} {1}", methodName, exception.ToString()));
                txtEventLog.Text = string.Format("{0} {1}", methodName, exception.ToString());
            }


            try
            {
                // GetWindowThreadProcessId WINAPI 함수를 호출 하여 pid를 찾아 Kill 시도 진행 
                if (m_nPid != 0)
                    System.Diagnostics.Process.GetProcessById((int)m_nPid).Kill();
            }
            catch (Exception exception2)
            {

            }

            Environment.Exit(Environment.ExitCode);
        }