0

我正在使用conquer.exe Form 应用程序,我想知道如果进程已关闭,我该如何退出环境。我在计时器中使用此代码,但如果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

4 回答 4

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 事件

于 2013-09-06T05:48:11.230 回答
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);
            }
        }

然后在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) ;
    }
于 2013-09-06T05:31:29.230 回答
0

Try this:

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.
}

I also agree with @Naren this code should be run in a background worker thread. You shouldn't need to run this in a timer, in fact you shouldn't. If you run this is a background worker thread the exe.WaitForExit(); call will suspend the background thread until the process has exited.

If the application you are running this code in is dependant on the conquer process then if it is not running on startup you could start it yourself and then wait for exit... Again this code should be run in a background thread.

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);
    }
}
于 2013-09-06T05:26:08.493 回答
0

It's not likely you'll be able to actually catch the process exiting if you are doing this in a timer. If you miss the process being exited, it won't be returned as a result of getting the running processes in your for loop. Because it never find it you will never find any process starting with "conquer".

A safer option is just to check if the process is in the list of running applications and exit if you can't find it.

using System.Linq;

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

Be careful of using StartsWith since you could mistakenly pick up other processes starting the with name "conquer".

于 2013-09-06T05:26:29.697 回答