C#检测关闭应用程序

Mát*_*rga 1 c#

我正在尝试创建一个任务栏替换,我希望每个正在运行的应用程序都有一个按钮.

public void AddBtn(string name) {
        Button newButton = new Button();
        this.Controls.Add(newButton);
        newButton.Location = new Point(count * 75, Screen.PrimaryScreen.Bounds.Height - 25);
        newButton.Text = name;
        newButton.Name = count.ToString();
        newButton.BringToFront();
        count++;
    }

    private void GetRunning()
    {
        Process[] processes = Process.GetProcesses();
        foreach (Process process in Process.GetProcesses().Where(p => !string.IsNullOrEmpty(p.MainWindowTitle)).ToList())
            AddBtn(process.ProcessName);
    }
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止,它为每个正在运行的应用程序创建一个按钮.我需要检测其中一个应用程序是否关闭,因此我可以删除与其对应的按钮.如果您认为有更好的方法,请告诉我.

sty*_*ybl 7

首先,最好将代码移动到其他位置,并仅用于GetRunning获取当前正在运行的进程.像这样修改它:

private List<Process> GetRunning()
{
    return Process.GetProcesses().Where(p => !string.IsNullOrEmpty(p.MainWindowTitle)).ToList();
}

private void AddButtons()
{
    for (var process in this.GetRunning())
    {
        AddBtn(process.ProcessName);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,关于您的问题,有两种解决方案:

解决方案1:使用事件

创建一个方法,HandleClosed该方法处理进程退出时需要完成的所有操作:

private void HandleClosed(Process sender, EventArgs e)
{
    // Stuff
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将它绑定到进程的Exited事件,如下所示:

private void BindProcesses()
{
    foreach (var process in this.GetRunning())
    {
        process.EnableRaisingEvents = true;
        process.Exited += this.HandleClosed;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,只要其中一个进程退出,HandleClosed就会被调用,并且关闭的进程将通过它传递给它sender.

解决方案2:自己管理

在您的班级中添加私人字段private List<Process> prevProcesses;.

然后创建一个新方法GetClosed:

private List<Process> GetClosed()
{
    var current = GetRunning();
    var result = this.prevProcesses.Except(current);
    this.prevProcesses = current;
    return result.ToList();
}
Run Code Online (Sandbox Code Playgroud)

这个方法的作用是获取当前正在运行的进程,然后将该枚举与之比较prevProcesses.进入prevProcesses但未进入的进程是current已关闭的进程.然后,它prevProcesses使用当前枚举进行更新.

最后,prevProcesses在构造函数中获取初始值,或者用于初始化的任何其他方法:

this.prevProcesses = this.GetRunning();