【问题标题】:How to kill only processes started by my application如何仅杀死由我的应用程序启动的进程
【发布时间】:2016-12-05 18:16:12
【问题描述】:

我在应用程序中使用 Selenium WebDriver,并且我有代码可以杀死 webdrivers 和浏览器实例。但是,我认为如果用户在运行应用程序之前打开了任何 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);
    }
}

}

【问题讨论】:

    标签: c# process


    【解决方案1】:

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

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

    优势

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

    缺点

    • 我不相信有任何

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • “哦,不!我的 SO 页面突然关闭了!” - 请记住,不建议这样做,因为它会杀死在您的应用程序运行后启动的任何进程。如果这是一台专用机器就可以了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多