Добавить новую переменную среды в процесс, запущенный ProcessStartInfo.LoadUserProfile - PullRequest
0 голосов
/ 22 декабря 2010

Я зашел на свой компьютер с пользователем 'podosta'

Это нормально работает

ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe");
p.UserName = "myuser";
p.Domain = "mydomain";
p.Password = SecureString;
p.UseShellExecute = false;
p.LoadUserProfile = true;
Process.Start(p);

Переменные окружения процесса - это переменные окружения пользователя 'myuser'
Например:% USERPROFILE% указывает на профиль 'myuser'

Это не работает

ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe");
p.UserName = "myuser";
p.Domain = "mydomain";
p.Password = SecureString;
p.UseShellExecute = false;
p.LoadUserProfile = true;
p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT");
Process.Start(p);

Переменные окружения процесса - это переменные окружения моего 'подоста'
Например:% USERPROFILE% указывает на мой профиль 'podosta' Кстати,% MY_NEW_VARIABLE% создан

Почему это поведение?
Мне нужно запустить приложение с помощью RunAs, имеющего среду запущенного пользователя, и добавить в процесс некоторую дополнительную переменную среды.

Спасибо

1 Ответ

0 голосов
/ 04 апреля 2017

Поведение, которое вы видите - это документ MSDN для функции CreateProcessWithLogon Win32, которая работает в фоновом режиме при запуске процесса для другого пользователя (используя System.Diagnostics.Process):

Указатель на блок среды для нового процесса.Если этот параметр имеет значение NULL, новый процесс использует среду, созданную из профиля пользователя, указанного в lpUsername.

Так что, как только вы укажете одну переменную среды дляновый процесс, вам нужно указать их все.

Проблема теперь заключается в свойстве ProcessStartInfo.EnvironmentVariables.Как только вы обращаетесь к нему в первый раз (для данного экземпляра ProcessStartInfo), он будет автоматически заполнен полной средой для текущего пользователя ( ref ).

Взять эту строку, который запускается в контексте пользователя "podosta":

p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT");

Он делает две вещи:

  1. заполняет p.EnvironmentVariables средой "podosta" (включая "USERPROFILE = ... podosta ").
  2. Добавьте к этому новую переменную" MY_NEW_VARIABLE = SOME_TEXT ".

Этот объединенный набор затем передается процессу, запущенному как" myuser "и, таким образом, он получает «неправильное» (лучше: неожиданное) значение для «USERPROFILE».

Если вы хотите убедиться, что передали блок окружения NULL базовой функции Win32, чтобы получить поведениеописанный в приведенной выше цитате, вы никогда не сможете «дотронуться» до свойства EnvironmentVariables - даже не повторять и не выгружать его для целей ведения журнала.

Этого также недостаточно для EnvironmentVariables.Clear().Это не установит для внутреннего поля значение null, и функции CreateProcessWithLogon будет просто передан пустой блок окружения, но не нулевой.

Если вам не удастся сделать это, вы получите все виды смешныхповедения, например, тогда выполняющийся процесс будет иметь значение для USERPROFILE, то есть для пользователя, который запустил процесс, и т. д.

Вы можете обойти это, вызвав CreateEnvironmentBlock через p /invoke, добавьте переменные окружения по мере необходимости, затем вызовите CreateProcessAsUser (также через p / invoke), передав эту измененную среду.Это нелегкое дело, особенно если вам нужны все функции Process -класса, такие как перенаправление вывода и т. Д.

К сожалению, свойство ProcessStartInfo.EnvironmentVariables работает так же, как и оно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...