我正在使用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);
}
}
}
答案 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));
}
答案 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”命名的其他进程。