This week I spent quite sometime reading through articles and trying to understand how to run a process on a remote machine and also get the exit code of the process once it terminates. I ran into this issue after having used PSExec to do the same. While PSExec does a great job of executing a process, getting its StdOut and the exit code, while using it with .Net, I came across a bunch of issues. Ultimately I found a neat way to do it using nothing but WMI calls. The solution has multiple parts as follows,1. Start the remote process
2. Find if the remote process is running and if it does, start an event monitor to wait for it to exit
3. Once the process exits, retrieve its exit code Start the process using WMIConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
ManagementScope manScope = new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", remoteComputerName), connOptions); try
{
manScope.Connect();
}
catch (Exception e)
{
throw new Exception("Management Connect to remote machine " + remoteComputerName + " as user " + strUserName + " failed with the following error " + e.Message);
}
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
using (ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions))
{
using (ManagementBaseObject inParams = processClass.GetMethodParameters("Create"))
{
inParams["CommandLine"] = arguments;
using (ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null))
{ if ((uint)outParams["returnValue"] != 0)
{
throw new Exception("Error while starting process " + arguments + " creation returned an exit code of " + outParams["returnValue"] + ". It was launched as " + strUserName + " on " + remoteComputerName);
}
this.ProcessId = (uint)outParams["processId"]; }
}
} The above code snippet launches the process on a remote machine using the “Create” method in “Win32_Process” class. The create method returns a value that indicates if the process was launched successfully or not. If the process was launched successfully, it also returns the process id. Read more: Come n see what I'm upto...
2. Find if the remote process is running and if it does, start an event monitor to wait for it to exit
3. Once the process exits, retrieve its exit code Start the process using WMIConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
ManagementScope manScope = new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", remoteComputerName), connOptions); try
{
manScope.Connect();
}
catch (Exception e)
{
throw new Exception("Management Connect to remote machine " + remoteComputerName + " as user " + strUserName + " failed with the following error " + e.Message);
}
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
using (ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions))
{
using (ManagementBaseObject inParams = processClass.GetMethodParameters("Create"))
{
inParams["CommandLine"] = arguments;
using (ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null))
{ if ((uint)outParams["returnValue"] != 0)
{
throw new Exception("Error while starting process " + arguments + " creation returned an exit code of " + outParams["returnValue"] + ". It was launched as " + strUserName + " on " + remoteComputerName);
}
this.ProcessId = (uint)outParams["processId"]; }
}
} The above code snippet launches the process on a remote machine using the “Create” method in “Win32_Process” class. The create method returns a value that indicates if the process was launched successfully or not. If the process was launched successfully, it also returns the process id. Read more: Come n see what I'm upto...
0 comments:
Post a Comment