Пользователь Redmon как пользователь не загружает переменные среды пользователя - PullRequest
3 голосов
/ 21 мая 2010

Я пытаюсь использовать Redmon http://www.winimage.com/misc/redmon/ для отправки заданий на печать в пользовательское приложение C #. Redmon «запускается» (фактически «Диспетчер очереди печати») как SYSTEM, но имеет опцию «Запуск от имени пользователя», позволяющую запускать ваше приложение под пользователем, который распечатал задание. Проблема в том, что он не загружает среду пользователя. Поэтому вызов функций, таких как Path.GetTempPath (), указывает на \ windows \ temp вместо пользователя. Также при попытке запустить Outlook 2007+ через вызовы MAPI (для добавления вложений) он сообщает об ошибках формы из-за, я думаю, расположения временной папки.

Есть ли способ "перезагрузить" профиль или, по крайней мере, получить переменные среды в приложении Олицетворенного? Единственные идеи, которые у меня были до сих пор, - это перестраивать vars непосредственно из реестра, но я хочу избежать этого, так как это является хакерской атакой (избегая деталей реализации и всего этого). Или создание программы-заглушки, которую Redmon вызывает, которая затем запускается как пользователь с полным профилем пользовательского приложения.

Любые другие предметы или хитрости?

Ответы [ 2 ]

7 голосов
/ 13 июня 2010

Я закончил тем, что нашел способ загрузить EnvironmentBlock пользователя, извлечь каждую переменную и загрузить их в мою существующую среду. Основано на коде и идеях с нескольких страниц:

Извините, мой код C #, любые изменения приветствуются:

[DllImport("userenv.dll", SetLastError = true)]
private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit); 

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, ref IntPtr TokenHandle); 
private const uint TOKEN_QUERY = 0x0008; 

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);

private static void ReloadEnviroVars()
{
  IntPtr hToken = IntPtr.Zero;
  IntPtr envBlock = IntPtr.Zero;

  //Load this user's environment variables
  OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, ref hToken);
  bool retVal = CreateEnvironmentBlock(ref envBlock, hToken, false);

  //Extract each environment variable from the envroblock and add it to
  // our running program's environment vars
  int offset = 0;
  while (true) {
    //EnviroBlock is an array of null-terminated unicode strings
    IntPtr ptr = new IntPtr(envBlock.ToInt64() + offset);
    string Enviro = Marshal.PtrToStringUni(ptr);
    offset += Encoding.Unicode.GetByteCount(Enviro) + 2;
    if (string.IsNullOrEmpty(Enviro))
      break;
    string EnviroKey = Enviro.Substring(0, Enviro.IndexOf("="));
    string EnviroValue = Enviro.Substring(Enviro.IndexOf("=") + 1,  Enviro.Length - 1 - Enviro.IndexOf("="));
    Environment.SetEnvironmentVariable(EnviroKey, EnviroValue);
  }

  CloseHandle(hToken);
}
0 голосов
/ 20 июня 2018

У меня была такая же проблема в Windows 10.

Я заметил, что если в файле .exe приложения установлен флаг «Запуск от имени администратора», то он будет запускаться от имени пользователя System. Снятие этого флага заставило мое приложение работать с привилегиями пользователя и переменными среды, и это было то, что мне было нужно.

...