2016-05-19 3 views
0

Я разрабатываю серверное приложение C#, которое выполняет файл .exe через локальную сеть на разных клиентских компьютерах. Я решил сделать это через WMI и отлично работает, когда путь .exe локален для удаленной машины. Поиск по другим темам здесь и другим форумам Я заметил, что WMI не поддерживает UNC-пути (здесь возникает моя проблема).Доступ 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 (возможно, это в крайнем случае).

Пожалуйста, дайте мне знать, если мне не хватает информации. Любые комментарии будут высоко оценены.

С уважением.

Редактировать: Я проверил, и это не вопрос разрешений для общей папки или файла.

+0

ли строка для 'вар арг =«cmd.exe ... 'должны быть @ -quoted? – lit

+0

Нет, на самом деле @ сделал бы команду к сбою при выполнении в ЦМД. Я использовал double \\ и \ ", потому что мне нужно, чтобы они обрабатывались командой cmd, а не интерпретировались компилятором. – Petaflop

+0

Вы можете отобразить каталог, если это целесообразно в вашей среде. использование сети поможет вам там. –

ответ

0

В случае, если кто сталкивается с тем или другим связанным с этим вопросом, это то, как я ее решил:

Проблема заключается не в том, что WMI не может иметь дело с путями UNC, но операции WMI не могут получить доступ к сетевым ресурсам из-за безопасность ограничения в Windows. Неважно, если вы сопоставляете пути, это просто не разрешено. В этом конкретном случае обходной путь, с которым я столкнулся, заключался в том, чтобы скопировать файл setup.exe во временную папку на удаленной машине и, наконец, выполнить его через WMI, обратившись к его локальному пути, как и раньше.

var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\temp_folder\My_Setup.exe", @"domain\user", "mypass"); 
Смежные вопросы