使用C#关闭应用程序

时间:2013-09-06 05:11:42

标签: 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);
        }
    }
}

4 个答案:

答案 0 :(得分:1)

正如@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);
            }
        }

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

    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) ;
    }

答案 1 :(得分: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));
    }

来源:.NET Events for Process executable start

答案 2 :(得分:0)

试试这个:

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();调用将挂起后台线程,直到进程退出。

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

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);
    }
}

答案 3 :(得分:0)

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

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

using System.Linq;

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

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