Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何知道窗户是否已关闭?_C#_Windows - Fatal编程技术网

C# 如何知道窗户是否已关闭?

C# 如何知道窗户是否已关闭?,c#,windows,C#,Windows,我想知道我是否能得到任何消息说,一个特定的开放窗口已经消失了 Clearify:我打开一个记事本,输入一些文本,然后关闭它。我希望我的C#程序显示一条消息,说明我的窗口已关闭。我是C#新手,所以请建议一个或多个我可能需要研究的课程,或者最好提供一个简短的示例来演示主要任务。非常感谢您的帮助。您需要使用interop来完成此操作。创建一个计时器来调用 当它停止查找窗口时,窗口就消失了,正如@Richard指出的那样,您需要FindWindow()来查看任何窗口。在记事本的情况下,你可以做得更简单,

我想知道我是否能得到任何消息说,一个特定的开放窗口已经消失了


Clearify:我打开一个记事本,输入一些文本,然后关闭它。我希望我的C#程序显示一条消息,说明我的窗口已关闭。我是C#新手,所以请建议一个或多个我可能需要研究的课程,或者最好提供一个简短的示例来演示主要任务。非常感谢您的帮助。

您需要使用interop来完成此操作。创建一个计时器来调用


当它停止查找窗口时,窗口就消失了,

正如@Richard指出的那样,您需要
FindWindow()
来查看任何窗口。在记事本的情况下,你可以做得更简单,因为记事本进程会在窗口一离开就终止

您可以使用
Process.start()
启动记事本,并使用返回的
Process
对象上的
Exited
事件在记事本完成时运行代码:

Process notepad = Process.Start("Notepad", "c:\temp\text.txt");
notepad.Exited += MyExitEventHandler;

肮脏但有效的方法是使用计时器轮询当前正在运行的进程,将列表与上次轮询中运行的进程进行比较

首先,添加此类类成员以存储流程,以便以后进行比较:

List<string> lastRunningProcesses = new List<string>();
最后是轮询和比较代码:

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    List<string> currentlyRunningProcesses = System.Diagnostics.Process.GetProcesses().ToList().ConvertAll(p => p.ProcessName);
    if (lastRunningProcesses.Count > 0)
    {
        List<string> closedProcesses = lastRunningProcesses.FindAll(p => !currentlyRunningProcesses.Contains(p));
        if (closedProcesses.Count > 0)
            MessageBox.Show(string.Format("{0} process(es) have been closed:\n{1}", closedProcesses.Count, string.Join("\n", closedProcesses)));
    }
    lastRunningProcesses = currentlyRunningProcesses;
}
void timer\u已过(对象发送器,System.Timers.ElapsedEventArgs e)
{
列出currentlyRunningProcesses=System.Diagnostics.Process.GetProcesses().ToList().ConvertAll(p=>p.ProcessName);
如果(lastRunningProcesses.Count>0)
{
List ClosedProcess=lastRunningProcesses.FindAll(p=>!currentlyRunningProcesses.Contains(p));
如果(closedProcesses.Count>0)
MessageBox.Show(string.Format(“{0}进程已关闭:\n{1}”,closedProcess.Count,string.Join(“\n”,closedProcess));
}
lastRunningProcesses=currentlyRunningProcesses;
}

只要你的应用程序运行,它就会保持轮询。

忙等待是处理锁的一种非常糟糕的方式。谢谢你们的评论和建议suggestions@none锁?你指的是哪个锁?@richard如果你仔细想想,你打开的线程正在等待另一个进程完成,然后线程才能继续。这不是锁的定义吗?好吧,如果这是我所建议的,那么这将是一种非常昂贵的方法——但我不是这么说的。我说把它放在计时器上。计时器只是简单地启动(可能是线程池计时器或WM_计时器-OP不说明这是否从基于UI的应用程序运行)并检查窗口。如果窗口消失,则向应用程序的其余部分发送信号(设置手动重置事件(Slim)或触发.NET事件谢谢,但我不会从程序本身启动记事本,我的意思是检查所有打开的窗口,然后关闭的窗口就消失了。我认为您处理退出事件的解决方案看起来非常有希望。我会尝试一下,再次非常感谢Anders。如果您可以在进程级别上工作的话(这意味着当节目中的对话关闭时,您不想观看)您可以使用
Process.GetProcesses
获取当前运行的所有进程的列表。当然,这取决于进程只有一个窗口,因此窗口的关闭与进程的终止是同义的。但是,如果您能够保证,那么使用进程就更简单了
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    List<string> currentlyRunningProcesses = System.Diagnostics.Process.GetProcesses().ToList().ConvertAll(p => p.ProcessName);
    if (lastRunningProcesses.Count > 0)
    {
        List<string> closedProcesses = lastRunningProcesses.FindAll(p => !currentlyRunningProcesses.Contains(p));
        if (closedProcesses.Count > 0)
            MessageBox.Show(string.Format("{0} process(es) have been closed:\n{1}", closedProcesses.Count, string.Join("\n", closedProcesses)));
    }
    lastRunningProcesses = currentlyRunningProcesses;
}