We all know and love Process.WaitForExit().
Given a pid of a process on a remote machine (created by WMI/psexec), how do I wait for it to end?
Kent Boogaart
Process.GetProcessById(processId, machineName).WaitForExit();
For me Process.GetProcessByID() just didn't work (it claimed it couldn't connect to the machine). This worked:
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;
}
Poll the remote computer using SysInternals' PSLIST.
来源:https://stackoverflow.com/questions/366326/wait-for-a-remote-process-to-finish-in-net