簡體   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