繁体   English   中英

使用C#关闭应用程序

[英]Closing Application Using C#

我正在使用表单应用程序,我想知道如果进程conquer.exe关闭,我该如何退出环境。 我在计时器中使用此代码但是如果conquer.exe已关闭则没有任何反应。

foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses())
{
    if (exe.ProcessName.StartsWith("conquer"))
    {
        exe.WaitForExit();
        if (exe.HasExited)
        {
            Application.Exit();
            Environment.Exit(0);
        }
    }
}

正如@Steven Liekens所建议的那样,我们可以使用Process.Exited事件来跟踪应用程序状态。

创建一个列表以存储具有相同名称的所有进程。

List<Process> selectedProcesses = new List<Process>();

然后获取具有相同名称的所有进程。

        // Gets the processes with given name
        // If one or more instances are running
        foreach (Process exe in Process.GetProcesses())
        {
            if (exe.ProcessName.Contains("WINWORD"))
            {
                exe.Exited += exe_Exited;
                selectedProcesses.Add(exe);
            }
        }

然后在Exited事件中检查列表是否为空。

    void exe_Exited(object sender, EventArgs e)
    {
        // If all the procees have been exited
        if (selectedProcesses.Count == 0)
        {
            Environment.Exit(0);
        }
        // Else remove a process from the list
        selectedProcesses.RemoveAt(selectedProcesses.Count - 1) ;
    }

你可以尝试以下

private ManagementEventWatcher WatchForProcessEnd(string processName)
    {
        string queryString =
            "SELECT TargetInstance" +
            "  FROM __InstanceDeletionEvent " +
            "WITHIN  10 " +
            " WHERE TargetInstance ISA 'Win32_Process' " +
            "   AND TargetInstance.Name = '" + processName + "'";

        // The dot in the scope means use the current machine
        string scope = @"\\.\root\CIMV2";

        // Create a watcher and listen for events
        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
        watcher.EventArrived += ProcessEnded;
        watcher.Start();
        return watcher;
    }

    private void ProcessEnded(object sender, EventArrivedEventArgs e)
    {
        ManagementBaseObject targetInstance = (ManagementBaseObject) e.NewEvent.Properties["TargetInstance"].Value;
        string processName = targetInstance.Properties["Name"].Value.ToString();
        Console.WriteLine(String.Format("{0} process ended", processName));
    }

来源: 用于Process可执行启动的.NET事件

尝试这个:

Process exe = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.ToLower().Trim().StartsWith("conquer"));
if(exe != null)
{
    exe.WaitForExit();
    exe.refresh();
    if(exe.HasExited)
    {
        Application.Exit();
        Enviroment.Exit(0);
    }
}
else
{
    //Conquer process has already exited or was not running.
}

我也同意@Naren这个代码应该在后台工作线程中运行。 你不应该在计时器中运行它,事实上你不应该。 如果你运行这是一个后台工作线程exe.WaitForExit(); call将暂停后台线程,直到进程退出。

如果您运行此代码的应用程序依赖于征服过程,那么如果它在启动时没有运行,您可以自己启动它然后等待退出...再次,此代码应该在后台线程中运行。

Process exe = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.ToLower().Trim().StartsWith("conquer"));
if(exe == null)
{
    exe = new Process();
    exe.StartInfo.FileName = "conquer.exe"
    exe.Start();

    exe.WaitForExit();
    exe.refresh();
    if(exe.HasExited)
    {
        Application.Exit();
        Enviroment.Exit(0);
    }
}
if(exe != null)
{
    exe.WaitForExit();
    exe.refresh();
    if(exe.HasExited)
    {
        Application.Exit();
        Enviroment.Exit(0);
    }
}

如果您在计时器中执行此操作,则不太可能实际捕获正在退出的进程。 如果您错过了退出的进程,则不会因为在for循环中获取正在运行的进程而返回该进程。 因为它永远找不到它,你永远不会找到任何以“征服”开头的过程。

更安全的选择是检查进程是否在正在运行的应用程序列表中,如果找不到则退出。

using System.Linq;

if (!System.Diagnostics.Process.GetProcesses().Any(p => p.ProcessName.Equals("conquer.exe", System.StringComparison.OrdinalIgnoreCase)))
{
  Application.Exit();
}

小心使用StartsWith,因为你可能会错误地选择以名称“conquer”开头的其他进程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM