【问题标题】:Wait for a remote process to finish in .net等待远程进程在 .net 中完成
【发布时间】:2011-09-28 07:50:53
【问题描述】:

我们都知道并喜欢 Process.WaitForExit()。

给定远程机器上进程的 pid(由 WMI/psexec 创建),我如何等待它结束?

【问题讨论】:

    标签: .net remote-process waitforexit


    【解决方案1】:

    对我来说 Process.GetProcessByID() 只是没有工作(它声称它无法连接到机器)。这有效:

    public static bool WaitForProcess(int pid, string machine, TimeSpan timeout)
    {
      // busy wait
      DateTime start = DateTime.Now;
      while (IsAlive(pid, machine))
      {
        if (start.Add(timeout).CompareTo(DateTime.Now) <= 0)
          return false;
    
        Thread.Sleep(1000);
      }
      return true;
    }
    
    public static bool IsAlive(int pid, string machine)
    {
      // doesn't work for me (throws "The network path was not found" exception)
      //return Process.GetProcessById(pid, @"\\" + machine) != null;
      string user;
      string domain;
      GetProcessInfoByPID(pid, machine, out user, out domain);
      return !string.IsNullOrEmpty(user);
    }
    
    public static string GetProcessInfoByPID(int PID, string machine, out string User, out string Domain)
    {
      // copied from http://www.codeproject.com/KB/cs/processownersid.aspx?fid=323674&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2076667
      // with slight modifications
      ConnectionOptions connOptions = new ConnectionOptions();
      connOptions.Impersonation = ImpersonationLevel.Impersonate;
      connOptions.EnablePrivileges = true;
      ManagementScope manScope = new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", machine), connOptions);
      manScope.Connect();
    
      User = String.Empty;
      Domain = String.Empty;
      string OwnerSID = String.Empty;
      string processname = String.Empty;
      try
      {
        ObjectQuery sq = new ObjectQuery
          ("Select * from Win32_Process Where ProcessID = '" + PID + "'");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(manScope, sq);
        if (searcher.Get().Count == 0)
          return OwnerSID;
        foreach (ManagementObject oReturn in searcher.Get())
        {
          string[] o = new String[2];
          //Invoke the method and populate the o var with the user name and domain
          oReturn.InvokeMethod("GetOwner", o);
    
          //int pid = (int)oReturn["ProcessID"];
          processname = (string)oReturn["Name"];
          //dr[2] = oReturn["Description"];
          User = o[0];
          if (User == null)
            User = String.Empty;
          Domain = o[1];
          if (Domain == null)
            Domain = String.Empty;
          string[] sid = new String[1];
          oReturn.InvokeMethod("GetOwnerSid", sid);
          OwnerSID = sid[0];
          return OwnerSID;
        }
      }
      catch
      {
        return OwnerSID;
      }
      return OwnerSID;
    }
    

    【讨论】:

      【解决方案2】:
      Process.GetProcessById(processId, machineName).WaitForExit();
      

      【讨论】:

      • 不确定这怎么会是正确的答案。根据 doco msdn.microsoft.com/en-us/library/fb4aw7b8.aspx,当“您尝试为在远程计算机上运行的进程调用 WaitForExit() 时,将引发 SystemException。此方法仅适用于在本地计算机上运行的进程。”
      【解决方案3】:

      使用 SysInternals 的 PSLIST 轮询远程计算机。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-06
        • 2011-11-09
        • 2012-07-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多