2008-12-14 113 views
1

我们都知道并且喜欢Process.WaitForExit()。等待远程进程完成.net

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

回答

0
Process.GetProcessById(processId, machineName).WaitForExit(); 
+4

不知道这是如何得到正确的答案。根据doco http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx当“您正尝试为在远程计算机上运行的进程调用WaitForExit()时,将引发SystemException。方法仅适用于在本地计算机上运行的进程。“ – Simon 2011-09-15 00:36:35

0

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

2

对于我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; 
}