WMI 访问 UNC 路径
WMI access to UNC paths
我正在开发一个服务器 C# 应用程序,该应用程序通过不同客户端计算机上的本地域网络执行 .exe 文件。
我选择通过 WMI 执行此操作,并且当 .exe 路径在远程计算机本地时工作正常。在这里和其他论坛上搜索其他线程,我注意到 WMI 不支持 UNC 路径(这是我的问题)。
当我调用下面的方法来执行放在远程电脑桌面上的 .exe 时,它工作正常:
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\Documents and Settings\user1\Desktop\My_Setup.exe", @"domain\user", "mypass");
现在,当我尝试使用 UNC 路径时,我得到 退出代码 2:
var execResult = WmiExecuteRemoteProcess("XPSP3", @"\server\shared\My_Setup.exe", @"domain\user", "mypass");
WmiExecuteRemoteProcess
方法如下所示:
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;
}
}
鉴于这种情况,我决定通过如下解析 arguments
参数来 "cheat" 它:
var args = "cmd.exe /c \"pushd \"\"\\server\shared\"\" && My_Setup.exe && popd\"";
var execResult = WmiExecuteRemoteProcess("XPSP3",args,@"domain\user", "mypass");
我在这里尝试做的是使用 cmd.exe 命令 pushd
和 popd
将 UNC 路径映射到基于网络驱动器的路径,如 "Z:\shared".这样 WMI 和 cmd.exe 都不必处理 UNC 路径。
结果:同样,如果 .exe 是远程机器的本地文件,它工作得很好,但是当使用 UNC 路径时,只有 cmd.exe 进程出现。也许它在内部再次抛出退出代码 2,但我无法捕捉到它,甚至将 cmd 执行的输出重定向到日志文件。
也许在这种机制方面有经验的人可以对此有所启发。我不想为此开发一个完整的服务,或者使用 PsExec(也许这是最后的手段)。
如果我遗漏任何信息,请告诉我。任何意见将不胜感激。
此致。
编辑:我检查过,这与共享文件夹或文件的权限无关。
万一有人遇到这个或其他相关问题,我就是这样解决的:
问题不是 WMI 无法处理 UNC 路径,而是由于 Windows 中的安全限制,WMI 操作不允许访问网络资源。如果你映射路径并不重要,它只是没有被授权。在这种特殊情况下,我最终采用的解决方法是将 setup.exe 复制到远程计算机中的临时文件夹,最后通过 WMI 访问其本地路径来执行它,就像我之前所做的那样。
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\temp_folder\My_Setup.exe", @"domain\user", "mypass");
我正在开发一个服务器 C# 应用程序,该应用程序通过不同客户端计算机上的本地域网络执行 .exe 文件。 我选择通过 WMI 执行此操作,并且当 .exe 路径在远程计算机本地时工作正常。在这里和其他论坛上搜索其他线程,我注意到 WMI 不支持 UNC 路径(这是我的问题)。
当我调用下面的方法来执行放在远程电脑桌面上的 .exe 时,它工作正常:
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\Documents and Settings\user1\Desktop\My_Setup.exe", @"domain\user", "mypass");
现在,当我尝试使用 UNC 路径时,我得到 退出代码 2:
var execResult = WmiExecuteRemoteProcess("XPSP3", @"\server\shared\My_Setup.exe", @"domain\user", "mypass");
WmiExecuteRemoteProcess
方法如下所示:
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;
}
}
鉴于这种情况,我决定通过如下解析 arguments
参数来 "cheat" 它:
var args = "cmd.exe /c \"pushd \"\"\\server\shared\"\" && My_Setup.exe && popd\"";
var execResult = WmiExecuteRemoteProcess("XPSP3",args,@"domain\user", "mypass");
我在这里尝试做的是使用 cmd.exe 命令 pushd
和 popd
将 UNC 路径映射到基于网络驱动器的路径,如 "Z:\shared".这样 WMI 和 cmd.exe 都不必处理 UNC 路径。
结果:同样,如果 .exe 是远程机器的本地文件,它工作得很好,但是当使用 UNC 路径时,只有 cmd.exe 进程出现。也许它在内部再次抛出退出代码 2,但我无法捕捉到它,甚至将 cmd 执行的输出重定向到日志文件。
也许在这种机制方面有经验的人可以对此有所启发。我不想为此开发一个完整的服务,或者使用 PsExec(也许这是最后的手段)。
如果我遗漏任何信息,请告诉我。任何意见将不胜感激。
此致。
编辑:我检查过,这与共享文件夹或文件的权限无关。
万一有人遇到这个或其他相关问题,我就是这样解决的:
问题不是 WMI 无法处理 UNC 路径,而是由于 Windows 中的安全限制,WMI 操作不允许访问网络资源。如果你映射路径并不重要,它只是没有被授权。在这种特殊情况下,我最终采用的解决方法是将 setup.exe 复制到远程计算机中的临时文件夹,最后通过 WMI 访问其本地路径来执行它,就像我之前所做的那样。
var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\temp_folder\My_Setup.exe", @"domain\user", "mypass");