如何从 C# 控制台停止办公应用程序 [重复]
Posted
技术标签:
【中文标题】如何从 C# 控制台停止办公应用程序 [重复]【英文标题】:How to stop office application from C# console [duplicate] 【发布时间】:2014-08-05 14:10:32 【问题描述】:鉴于以下代码(控制台应用程序 C#),Word 应用程序在大约 300-400 毫秒后停止,但 Excel 应用程序继续运行。我找不到阻止它的方法(不终止进程)。
有什么建议吗?
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;
【问题讨论】:
您是否尝试单步执行代码以查看发生了什么? 是的,我做到了...进程不会终止/从进程列表中消失 我注意到您的代码中有catch
。这是一个很大的代码气味。您可能会在没有正确处理它们的情况下吞下异常。至少您应该将异常写入控制台。
Excel Introp 非常尴尬,如果你不清理使用 Dispose() 或 usings 引用的所有 COM 对象,那么当你告诉它时应用程序不会关闭
做。不是。双倍的。点。您在 excelApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet)
泄露了工作簿参考。
【参考方案1】:
所以我突然想到了一些事情。
-
您不会在 Excel 应用程序本身上调用 quit。这是它关闭的信号。
您还需要确保在工作簿上调用 Close。
确保在完成所有对象后将其关闭并设置为 null
我还发现,对我使用过的所有对象不仅调用
Marshal.ReleaseComObject
还调用 Marshal.FinalReleaseComObject
很有帮助。
你是双点,这意味着你泄露了一堆引用。不好的做法,会鼓励 Excel 闲逛
最后,为了真正确定我杀死 Excel,在完成上述所有操作后,我通过窗口句柄杀死进程。
public static bool 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);
【讨论】:
以上是关于如何从 C# 控制台停止办公应用程序 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C# Windows 应用程序控制 Windows 10 移动热点设置 [重复]
如何在 C# 的控制台应用程序中使用键盘输入停止正在运行的方法?