Подтвердить что ты не робот

Запуск другого процесса с повышением с использованием разных учетных данных пользователя

Я пытаюсь запустить процесс с невыполненным процессом, но мне также нужно указать имя пользователя и пароль для пользователя с учетными данными администратора. Я пробовал использовать метод "runas" для повышения, а также использовать манифест, но оба дают разные ошибки.

Например, если я делаю это (без использования манифеста, требующего повышения):

ProcessStartInfo info = new ProcessStartInfo(path);

info.UseShellExecute = false;
info.UserName = username;
info.Password = securePwd;
info.Domain = "MyDomain";
info.Verb = "runas";

var proc = Process.Start(info);

Процесс запускается без отображения диалогового окна подтверждения UAC и не удается выполнить команду, требующую прав администратора (я просто пытаюсь записать тестовый файл в каталог Program Files).

Если я добавлю манифест в целевое приложение, которое указывает, что для него требуется возвышение, я получаю Win32Exception, заявляя, что операция требует повышения.

Кажется, что проблема заключается в настройке UseShellExecute на false (поскольку оба подхода работают нормально, когда это не так), но я должен установить для него значение false, чтобы запустить процесс под другой учетной записью пользователя.

Как я могу запустить повышенный процесс из процесса без повышения и вручную указать имя пользователя и пароль?

BOUNTY EDIT: В то время как пользователю не требуется вводить учетные данные администратора, вполне возможно, что диалог UAC nag вполне допустим. Я не собираюсь обойти UAC здесь.

4b9b3361

Ответ 1

я был удивлен, что нет никакого способа сделать это, пока я не нашел запись в блоге Криса Джексона:

Почему я не могу повысить свое приложение для запуска от имени администратора при использовании CreateProcessWithLogonW?

Вам нужен начальный загрузчик. Некоторый процесс, который позволит вам выполнить переход к альтернативному пользователю, который может быть ответственным за запуск приложения requireAdministrator. Итак, вы можете создать что-то вроде этого:

enter image description here

Почему бы нам просто не создать API ShellExecuteWithLogonW? Я никогда не скажу никогда, и мы могли бы в какой-то момент. Но сегодня, варианты использования для этих API были вариантами использования, когда был альтернативный дизайн, который является превосходящим.

Наиболее распространенный запрос - для людей, пишущих собственное программное обеспечение для развертывания программного обеспечения, где они хотят кодировать учетные данные прямо в приложение и повышать свой собственный процесс. Реальная проблема здесь не в отсутствии API, а в том, что у вас есть учетные данные администратора, закодированные в вашем приложении, чтобы читатели могли их прочитать.

Таким образом, для решения требуется ShellExecute, единственное, кто знает, как вызвать диалог Согласие.

Это поднимает хороший вопрос: что вы уже делаете с паролем человека?

Бонусная болтовня

Там нет UAC на Server Core, потому что нет окон для отображения запроса на согласие.

Ответ 2

Из MSDN:

Вы не можете поднять уже запущенный процесс. Таким образом, вы должны реорганизовать ваше приложение для разделения на административные и неадминистративные операции - запуск приложения по умолчанию с обычными привилегиями и запуск другой повышенный процесс для каждой административной операции.

Позвольте работать с этим, если вы запрашиваете права администратора с самого начала на требуемые процессы. На основе контекста, который вы предоставили:

Кажется, что проблема заключается в установке UseShellExecute в false (поскольку оба подходы работают нормально, когда это не так), но я должен установить его на false, чтобы запустить процесс под другим пользователем счет.

Как вы упомянули, точно так же, как указано в документации для UseShellExecute:

UseShellExecute должен быть false, если свойство UserName не является Nothing или пустая строка, или исключение InvalidOperationException когда вызывается метод Process.Start(ProcessStartInfo).

Теперь мы знаем, что вы выполняете свою программу напрямую, а не с помощью оболочки. Это ценная информация.

Просматривая документацию, документы для ProcessStartInfo содержат следующее примечание по безопасности:

Этот класс содержит потребность в ссылке на уровне класса, которая применяется к все участники. Исключение SecurityException бросается, когда непосредственный вызывающий не имеет полного доверия. Подробнее о безопасности требования, см. Запрос связи.

Итак, у вас нет правильного запроса на связь. При попытке решить проблему с разрешениями вы случайно создали другую проблему с разрешениями.

Вы должны украсить свой метод вызова с помощью Требование безопасности, которое должно быть FullTrust. Вы можете сделать это декларативно или императивно в вашем коде.

(Дополнительное чтение)

Ответ 3

Если вы создаете приложение для Windows Installer (MSI) и обновляете его с помощью MSP, то установщик Windows имеет встроенную поддержку именно для вашего сценария: - проверьте Контроль учетных записей пользователей (UAC).

Он работает в основном так:

  • Когда вы создаете оригинальный MSI, вы создаете сертификат, и вы помещаете его открытый ключ (или что-то в этом роде) в MSI.
  • Администратор конечной машины устанавливает MSI на машине.
  • Вы публикуете обновление (MSP) и подписываете его с сертификатом.
  • Любой пользователь на целевом компьютере теперь может установить обновление. Установщик Windows проверит сертификат на открытый ключ в исходном MSI и соглашается установить, если это так. Я не думаю, что вы получите приглашение UAC вообще, хотя я не уверен.

Ответ 4

В соответствии с документацией MSDN:

Когда UseShellExecute является ложным, вы можете запускать только исполняемые файлы, используя объект "Процесс".

Я заметил, что ваша декларация var proc = Process.Start(info); не использует Process как тип класса.

Также убедитесь, что параметр path - это полный путь к исполняемому файлу. Например, "c:\\directory\\contains\\process_to_be_started\\executable.exe"

В соответствии с документацией MSDN это важно:

Свойство WorkDirectory должно быть установлено, если UserName и Password предоставлена. Если свойство не установлено, рабочим каталогом по умолчанию является % SYSTEMROOT%\system32.

Я бы попробовал ниже код для запуска целевого процесса с повышенными привилегиями (с правами администратора).

ProcessStartInfo info = new ProcessStartInfo(path);

info.UseShellExecute = false;
info.UserName = username;
info.Password = securePwd;
info.Domain = "MyDomain";
info.Verb = "runas";
info.WorkingDirectory = "c:\\directory\\contains\\process_to_be_started"

'var proc = Process.Start(info);

Process proc = Process.Start(info);

Ответ 5

ProcessStartInfo.Verb="runas" предназначен только для Windows Vista и выше, поэтому вы должны запросить системный уровень, а не делать возвышение для XP.

Я думаю, что если вы выберете ProcessStartInfo.Verb="runas", вы не должны указывать имя пользователя и пароль.

Если UAC имеет значение, значит, он все равно преуспел, это не должно быть проблемой.