我的情况是我正在开发一个C#应用程序,它正在启动一个Microsoft Office Excel应用程序的实例 我更改了Form的一些功能,以便在我的表单关闭时,实例化的Excel应用程序被杀死并从内存中清除。
我想要做的就是执行相反的操作。我希望我的Excel实例能够在退出时关闭我的窗体。
答案 0 :(得分:2)
这就是我为同一场景所做的。
我在班级
中创建了一个流程System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
然后是关闭应用程序的方法的委托
delegate void KillProcess();
KillProcess aKillProcess;
将代理设置为应用关闭方法
aKillProcess = CloseApp;
以下代码写在按钮点击事件中 这打开了excel。这里订阅流程的退出事件
myProcess.StartInfo = new System.Diagnostics.ProcessStartInfo (@"D:\SomeExcel.xlsx");
myProcess.Start();
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(ProcessKilled);
单击excel的关闭按钮时,将调用此方法
private void ProcessKilled(object sender, EventArgs e)
{
if (this.InvokeRequired)
this.Invoke(aKillProcess);
else
this.Close();
}
void CloseApp()
{
this.Close();
}
这将关闭应用程序。
希望这有帮助
答案 1 :(得分:1)
好吧,我甚至没有尝试过这个,所以我不确定它是否会起作用,但你可以尝试这些方法:
Microsoft.Office.Interop.Excel.Application excel = ...;
System.Diagnostics.Process excelProcess = null;
var processes = System.Diagnostics.Process.GetProcesses();
foreach (var process in processes)
{
if (process.Handle.ToInt32() == excel.Hwnd)
excelProcess = process;
}
excelProcess.Exited += new EventHandler(excelProcess_Exited);
<强>更新强>
尝试以下代码(不太漂亮):
Microsoft.Office.Interop.Excel.Application xlsApp;
Process xlsProcess;
Timer timer;
public Form1()
{
xlsApp = new Microsoft.Office.Interop.Excel.Application();
xlsApp.Visible = true;
foreach (var p in Process.GetProcesses()) //Get the relevant Excel process.
{
if (p.MainWindowHandle == new IntPtr(xlsApp.Hwnd))
{
xlsProcess = p;
break;
}
}
if (xlsProcess != null)
{
timer = new Timer();
timer.Interval = 500;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
}
void timer_Tick(object sender, EventArgs e)
{
if (xlsApp != null && !xlsApp.Visible)
{
//Clean up to make sure the background Excel process is terminated.
xlsApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp);
xlsApp = null;
}
if (xlsProcess.HasExited)
{
//The event is not fired but the property is eventually set once the process is terminated
this.timer.Dispose();
this.Close();
}
}
使用Excel应用程序时的问题是,即使用户关闭了它的主窗口,该过程也会继续在后台运行。为了完全释放它,你必须调用Application.Quit
但是你应该只在检测到关闭窗口的用户时才这样做,这正是你试图解决的问题...你在这里有一个循环引用:D
锁定到相关的System.Diagnostics.Process
似乎也不起作用,因为Exited
事件永远不会被触发(即使您从任务管理器终止后台进程)也是如此。我的猜测是,只有通过process = Process.Start(...)
启动的流程才会触发此事件。
所以我能看到的唯一解决方案是查看Excel的主窗口是否可见。一旦不是,这可能意味着用户关闭了主窗口并且应该终止Excel应用程序(如果在某些情况下Excel的主窗口的可见性可能是假的,除非用户想要终止该过程,那么此解决方案不是有效)。从那里它非常简单。
答案 2 :(得分:0)
你的第一次尝试是有效的,只需要为这个过程启动事件,这就是我为了启动visio退出或崩溃所做的。
foreach (var process in processes)
{
try
{
if (process.MainWindowHandle == new IntPtr(app.WindowHandle32))
visioProcess = process;
}
catch
{
}
}
visioProcess.EnableRaisingEvents = true;
visioProcess.Exited += new EventHandler(visioProcess_Exited);