Я разрабатываю серверное приложение С#, которое выполняет файл .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
следующим образом:
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 (может быть, этот в крайнем случае).
Пожалуйста, дайте мне знать, если мне не хватает какой-либо информации. Любые комментарии будут высоко оценены.
С Уважением.
Изменить: я проверил, и дело не в правах доступа к общей папке или файлу.
var args = "cmd.exe...
заключаться в @-кавычки? - person lit   schedule 19.05.2016pushd
, который в основном работает так же, какnet use
, и не работает. Как я написал в своем ответе, даже если вы сопоставите путь с буквой диска, это не сработает, ресурсы все еще находятся в сети, и WMI не может получить к ним доступ. - person Petaflop   schedule 23.06.2016