Reputation: 724
I'm developing a server C# application which executes a .exe file through a local domain network on different client computers. I've chosen to do it via WMI and works fine when the .exe path is local to the remote machine. Searching over other threads here and other forums I've noticed that WMI does not support UNC paths (here comes my problem).
When I call the method below to execute a .exe placed on the remote pc desktop, it just works fine:
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\Documents and Settings\user1\Desktop\My_Setup.exe", @"domain\user", "mypass");
Now, when I try to use UNC paths, I get the exit code 2:
var execResult = WmiExecuteRemoteProcess("XPSP3", @"\\server\shared\My_Setup.exe", @"domain\user", "mypass");
The WmiExecuteRemoteProcess
method looks like this:
public bool WmiExecuteRemoteProcess(string remoteComputerName, string arguments, string pUser, string pPassword)
{
try
{
ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Username = pUser;
connOptions.Password = pPassword;
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
ManagementScope manScope = new ManagementScope(string.Format(@"\\{0}\ROOT\CIMV2", remoteComputerName), connOptions);
manScope.Connect();
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))
{
return (uint)outParams["returnValue"] == 0;
}
}
}
}
catch (Exception ex)
{
Log.Error(ex.Message);
return false;
}
}
Given this situation I've decided kind of "cheat" it by parsing the arguments
parameter as follows:
var args = "cmd.exe /c \"pushd \"\"\\\\server\\shared\"\" && My_Setup.exe && popd\"";
var execResult = WmiExecuteRemoteProcess("XPSP3",args,@"domain\user", "mypass");
What I try to do here is to use the cmd.exe with the commands pushd
and popd
to map the UNC path into a network drive-based path like "Z:\shared". This way both WMI and cmd.exe don't have to deal with the UNC path.
Result: again, if the .exe is local to the remote machine, it works very well, but when using a UNC path, only the cmd.exe process appears. Maybe it's internally throwing the exit code 2 again, but I'm not able to catch it, even redirecting the output of the cmd execution to a log file.
Perhaps someone experienced in this kind of mechanics can throw some light on this. I'd prefer not to develop an entire service only for this, or to use PsExec (maybe this one as a last resort).
Please let me know if I'm missing any info. Any comments will be much appreciated.
Regards.
Edit: I checked and it's not a matter of permissions to the shared folder or file.
Upvotes: 1
Views: 2082
Reputation: 724
In case anyone faces this or other related issue, this is how I solved it:
The issue is not that WMI cannot deal with UNC paths, but WMI operations are not allowed to access network resources due to security restrictions in Windows. It doesn't matter if you map the paths, it's just not authorized. In this particular case the workaround I ended up with, was to copy the setup.exe to a temporary folder in the remote machine, and finally execute it through WMI by accessing its local path just like I was doing before.
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\temp_folder\My_Setup.exe", @"domain\user", "mypass");
Upvotes: 1