如何停止从C#控制台的办公应用程序

给定以下代码(控制台应用程序C#)Word应用程序大约300-400毫秒后停止,但Excel应用程序继续运行。 我找不到一个方法来阻止它(不杀死进程)。

有什么build议么?

using System; using System.IO; using System.Text; using System.Threading; using System.Diagnostics; using Microsoft.Office.Interop.Word; using Microsoft.Office.Interop.Excel; using Microsoft.Office.Interop.PowerPoint; using System.Collections.Generic; namespace test { class Program { private static int GetProcessIdByWindowTitle(string AppId) { Process[] P_CESSES = Process.GetProcesses(); for (int p_count = 0; p_count < P_CESSES.Length; p_count++) { if (P_CESSES[p_count].MainWindowTitle.IndexOf(AppId) != -1) { return P_CESSES[p_count].Id; } } return Int32.MaxValue; } static void Excel() { // create the MS-Excel Application Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application(); // Set the appID string appID = "zizozazezu"; excelApp.Application.Caption = appID; excelApp.Application.Visible = true; // Excel needs a workbook to sete a caption visible... Microsoft.Office.Interop.Excel.Workbooks wbs = excelApp.Workbooks; Microsoft.Office.Interop.Excel.Workbook wb = wbs.Add(); // find the int processID = GetProcessIdByWindowTitle(appID); // verified this is the pid of MS-Excel Console.WriteLine(processID); // bailing out, no save object saveChanges = false; ((Microsoft.Office.Interop.Excel._Workbook)wb).Close(saveChanges); ((Microsoft.Office.Interop.Excel._Application)excelApp).Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(wb); wb = null; System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs); wbs = null; System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp); excelApp = null; Console.WriteLine("Excel is done..."); for (int i=0; i<100; i++) { // Patience.... Thread.Sleep(100); // still running??? bool isRunning = false; try { Process p = Process.GetProcessById(processID); if (!p.HasExited) { isRunning = true; } } catch (Exception ex) { Console.WriteLine("{0} Exception caught.", ex); } if (isRunning) { Console.Write("."); } else { Console.WriteLine("Excel done at i=" + i.ToString()); return; } } return; } static void Word() { // create the MS-Word Application Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application(); // Set a caption - find the right instance string appID = "ladadidada"; wordApp.Caption = appID; wordApp.Visible = true; // find the int processID = GetProcessIdByWindowTitle(appID); // verified this is the pid of MS-Word Console.WriteLine(processID); // Stop MS-Word object saveChanges = false; ((Microsoft.Office.Interop.Word._Application)wordApp).Quit(ref saveChanges); for (int i=0; i<100; i++) { // Patience.... Thread.Sleep(100); // still running??? bool isRunning = false; try { Process p = Process.GetProcessById(processID); if (!p.HasExited) { isRunning = true; } } catch (Exception ex) { Console.WriteLine("{0} Exception caught.", ex); } if (isRunning) { Console.Write("."); } else { Console.WriteLine("Word done at i=" + i.ToString()); return; } } return; } static int Main(string[] args) { Word(); Excel(); return -1; } } } 

所以有一些东西跳到我身上。

  1. 您不要在Excel应用程序本身上调用quit。 这是它closures的信号。
  2. 您还需要确保在工作簿上调用Close。
  3. 确保你完成所有的对象closures设置为null
  4. 我也发现不仅在所有我使用的对象上调用Marshal.ReleaseComObject而且还有Marshal.FinalReleaseComObject
  5. 你是双点,这意味着你泄漏了一堆参考。 不好的做法,并会鼓励Excel挂在身边
  6. 最后,要真正真的确保我杀了Excel,完成上述所有操作之后,我通过窗口句柄来终止进程。

    公共静态布尔TryKillProcessByMainWindowHwnd(int hWnd){

     uint processID; GetWindowThreadProcessId((IntPtr)hWnd, out processID); if (processID == 0) return false; try { Process.GetProcessById((int)processID).Kill(); } catch (ArgumentException) { return false; } catch (Win32Exception) { return false; } catch (NotSupportedException) { return false; } catch (InvalidOperationException) { return false; } return true; 

    }

为了完成上述工作,还需要确保包含Win32 API。

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