如何仅终止由我的应用程序启动的进程

本文关键字:启动 进程 应用程序 我的 何仅 终止 | 更新日期: 2023-09-27 18:30:30

我正在应用程序中使用Selenium WebDriver,我有代码可以杀死Web驱动程序和浏览器实例。但是,我认为如果用户在运行应用程序之前打开了任何IE浏览器,则此代码不仅会杀死我的应用程序生成的IE进程,还会杀死用户在运行应用程序之前打开的IE实例。

有没有办法跟踪我的应用程序启动的进程,以便我可以过滤此方法以仅终止我的应用程序生成的 IE 进程,或者确定 IE 驱动程序和浏览器实例是由我的应用程序生成的,或者两者兼而有之?

public void KillAllBrowsersAndWebDrivers()
{
var webDrivers = Process.GetProcessesByName("IEDriverServer").Select(p => p.Id);
var browsers = Process.GetProcessesByName("iexplore").Select(p => p.Id);
var processIds = webDrivers.Concat(browsers);
// do some stuff with PID, if you want to kill them, do the following
foreach (var pid in processIds)
{
    try
    {
        Process.GetProcessById(pid).Kill();
        Logger.Log(Loglevel.Debug, "Kill Process:{0}", pid);
    }
    catch (Exception)
    {
        Logger.Log(Loglevel.Error, "Error killing process: {0}", pid);
    }
}

}

如何仅终止由我的应用程序启动的进程

> 您所要做的就是保留您创建的所有进程的列表。这是一个非常简单的进程管理器。此代码容易出错,并且没有异常处理

private static List<Process> processes = new List<Process>();
static void Main(string[] args)
{
    int PID = StoreProcess (yourProcess);
    KillProcess(PID);    
}
/// <summary>
/// Stores the process in a list
/// </summary>
/// <returns>The PID</returns>
/// <param name="prc">The process to be stored</param>
public static int StoreProcess(Process prc)
{
    int PID = prc.Id; // Get the process PID and store it in an int called PID
    processes.Add (prc); // Add this to our list of processes to be kept track of
    return PID; // Return the PID so that the process can be killed/changed at a later time
}
/// <summary>
/// Kills a process
/// </summary>
/// <param name="PID">The PID of the process to be killed.</param>
public static void KillProcess(int PID)
{
    // Search through the countless processes we have and try and find our process
    for (int i = 0; i <= processes.Count; i++) {
        if (processes [i] == null)
        {
            continue; // This segment of code prevents NullPointerExceptions by checking if the process is null before doing anything with it
        }
        if (processes [i].Id == PID) { // Is this our process?
            processes [i].Kill (); // It is! Lets kill it
            while (!processes [i].HasExited) { } // Wait until the process exits
            processes [i] = null; // Mark this process to be skipped the next time around
            return;
        }
    }
    // Couldn't find our process!!!
    throw new Exception ("Process not found!");
}

优点

  • 您可以跟踪已初始化的所有进程,并随时逐个终止它们

缺点

  • 我不相信有

另一种可能的解决方案是在生成任何新进程之前获取正在运行的进程的列表。然后只需杀死那些不在以前运行的进程列表中的进程。

public void KillOnlyProcessesSpawnedBySelenium()
{
    // get a list of the internet explorer processes running before spawning new processes
    var pidsBefore = Process.GetProcessesByName("iexplore").Select(p => p.Id).ToList();
    var driver = new Driver(Settings);
    var driver1 = driver.InitiateDriver(); // this method creates new   InternetExplorerDriver
    var driver2 = driver.InitiateDriver();
    var driver3 = driver.InitiateDriver();
    driver1.Navigate().GoToUrl("http://google.com");
    driver2.Navigate().GoToUrl("http://yahoo.com");
    driver3.Navigate().GoToUrl("http://bing.com");
    var pidsAfter = Process.GetProcessesByName("iexplore").Select(p => p.Id);
    var newInternetExplorerPids = pidsAfter.Except(pidsBefore);
     // do some stuff with PID, if you want to kill them, do the following
    foreach (var pid in newInternetExplorerPids)
    {
        Debug.WriteLine("Killing pid: {0}", pid);
        Process.GetProcessById(pid).Kill();
    }
    Assert.IsTrue(pidsBefore.Count > 0);
    // determine if each process before the drivers spawned are running
    foreach (var running in pidsBefore.Select(pid => Process.GetProcessById(pid).IsRunning()))
    {
        Assert.IsTrue(running);
    }
}

这是一个扩展方法,用于确定进程是否仍在运行...

public static bool IsRunning(this Process process)
{
    if (process == null) 
        throw new ArgumentNullException("process");
    try
    {
        Process.GetProcessById(process.Id);
    }
    catch (ArgumentException)
    {
        return false;
    }
    return true;
}