Доступ WMI к путям UNC

Я разрабатываю серверное приложение С#, которое выполняет файл .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 (может быть, этот в крайнем случае).

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

С Уважением.

Изменить: я проверил, и дело не в правах доступа к общей папке или файлу.


person Petaflop    schedule 19.05.2016    source источник
comment
Должна ли строка для var args = "cmd.exe... заключаться в @-кавычки?   -  person lit    schedule 19.05.2016
comment
Нет, на самом деле @ приведет к сбою команды при выполнении в cmd. Я использовал двойные \\ и \, потому что мне нужно было, чтобы они анализировались командой cmd, а не интерпретировались компилятором.   -  person Petaflop    schedule 19.05.2016
comment
Вы можете сопоставить каталог, если это целесообразно в вашей среде. net use поможет вам в этом.   -  person Amit Shakya    schedule 22.06.2016
comment
Это было первое, что я попробовал, используя pushd, который в основном работает так же, как net use, и не работает. Как я написал в своем ответе, даже если вы сопоставите путь с буквой диска, это не сработает, ресурсы все еще находятся в сети, и WMI не может получить к ним доступ.   -  person Petaflop    schedule 23.06.2016


Ответы (1)


Если кто-то столкнется с этой или другой связанной с этим проблемой, вот как я ее решил:

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

var execResult = WmiExecuteRemoteProcess("XPSP3", @"C:\temp_folder\My_Setup.exe", @"domain\user", "mypass");
person Petaflop    schedule 22.06.2016