我的情况是,我正在开发一个启动Microsoft Office Excel应用程序实例的C#应用程序。
我更改了某些表单的函数,以便在我的表单被关闭时,实例化的Excel应用程序正在被杀死并从内存中清除。C#:关闭excel关闭事件的窗体表格
我想要做的是做相反的事情。我希望我的Excel实例在退出时关闭我的窗体窗体。
我的情况是,我正在开发一个启动Microsoft Office Excel应用程序实例的C#应用程序。
我更改了某些表单的函数,以便在我的表单被关闭时,实例化的Excel应用程序正在被杀死并从内存中清除。C#:关闭excel关闭事件的窗体表格
我想要做的是做相反的事情。我希望我的Excel实例在退出时关闭我的窗体窗体。
好吧,我还没有试过这个,所以我不知道这是否会工作,但你可以尝试沿着这些路线的东西:
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);
UPDATE
请尝试以下代码(它不漂亮):
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应用程序时的问题是,即使用户关闭它的主窗口,pr接下来将继续在后台运行。为了完全释放它,您必须致电Application.Quit
,但只有在检测到用户关闭窗口时才应该这样做,这正是您正在尝试解决的问题...您在此处有一个循环参考:D
锁定到相关的System.Diagnostics.Process
似乎也不起作用,因为Exited
事件不会被触发(即使您从任务管理器中终止后台进程也不会)。我的猜测是,这个事件只能通过process = Process.Start(...)
启动的进程触发。
所以我能看到的唯一解决方案是轮询Excel的主窗口是否可见。一旦不是这样,这可能意味着用户关闭了主窗口并且应用程序应该被终止(如果在某些情况下Excel的主窗口的可见性可能是错误的,而不是当用户想要终止该过程时,那么该解决方案不是有效)。从那里它非常简单。
这就是我为同样的场景所做的。
我创建的类
System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
然后委托内的进程,以封闭该应用
delegate void KillProcess();
KillProcess aKillProcess;
委托设置到应用程序关闭方法
aKillProcess = CloseApp;
此方法下面的代码写在按钮点击事件中 这会打开前CEL。这里认购过程
myProcess.StartInfo = new System.Diagnostics.ProcessStartInfo (@"D:\SomeExcel.xlsx");
myProcess.Start();
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(ProcessKilled);
的Exited事件在单击Excel中的关闭按钮,这个方法会被称为
private void ProcessKilled(object sender, EventArgs e)
{
if (this.InvokeRequired)
this.Invoke(aKillProcess);
else
this.Close();
}
void CloseApp()
{
this.Close();
}
这将关闭该应用程序。
希望这有助于
我在直接关闭表单后添加了委托,“跨线程操作无效:控制'Form1'从其创建线程以外的线程访问。”异常被抛出。 – 2012-01-18 10:25:40
您的解决方案的问题似乎是,我将无法使用我的应用程序和启动的进程之间的交互,因为它不是启动的“Microsoft.Office.Interop.Excel.Application”,而是一个简单的进程。目前我无法控制它... – Jsncrdnl 2012-01-18 11:00:53
你的第一次尝试会工作,只是需要enavle事件的筹措过程中,这是我做的钓推出的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);
调查运行进程,并简单地退出时,Excel进程结束? – CodingBarfield 2012-01-18 09:58:45
如果您使用的是Visual Studio 2008或2010,则可以完全绕过表单并创建Excel Addin - http://msdn.microsoft.com/zh-cn/library/cc668205.aspx – JMK 2012-01-18 10:00:49
我知道这不是我的应用程序的重点。我需要这样做。我不知道如何设置一个监听器,当C#的实例化应用程序正在退出时,它将关闭我的C#应用程序... – Jsncrdnl 2012-01-18 10:09:28