Доступ к переменным среды из служб Windows - PullRequest
22 голосов
/ 20 ноября 2008

Я пытаюсь написать службу Windows на C #. Мне нужно найти путь к определенному файлу, который хранится в переменной окружения. В обычном консольном приложении C # я могу добиться этого с помощью следующей строки:

string t = System.Environment.GetEnvironmentVariable("TIP_HOME");

Если я запишу это в консоль, то увижу, что она прошла успешно.

Теперь, если я попробую этот же код в службе Windows, строка t будет пустой.

Есть идеи почему?

Ответы [ 10 ]

30 голосов
/ 28 апреля 2010

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

Это делается через реестр.

Скажи, что ключом к твоему обслуживанию является ...

HKLM \ SYSTEM \ CurrentControlSet \ Services \ YourService

Создайте REG_MULTI_SZ с именем Environment.

Теперь вы можете добавлять записи, как ...

Var1=Value1
Var2=Value2

и они будут доступны для сервисного кода.

Если вы используете Windows Resource ToolKit для установки сценариев как службы (instsrv.exe и srvany.exe), то, опять же, у вас есть возможность установить переменные среды для службы, но, скорее всего, это неправильно один, как это было бы для srvany.exe.

Вместо этого вы используете ключ ...

HKLM \ SYSTEM \ CurrentControlSet \ Services \ YourService \ Parameters

и создайте REG_MULTI_SZ с именем AppEnvironment

Установите записи таким же образом.

А теперь у вашей службы сценариев есть собственные переменные окружения.

Я использую эти методы с PHP + WinCache, чтобы позволить мне установить APP_POOL_ID, уникальный для каждого сервиса, который позволяет WinCache совместно использовать центральный кеш (на основе APP_POOL_ID) для всех «потоков» (используя WShell для запуска неблокирования дочерние "потоки" и все еще используют тот же WinCache, что и модуль запуска, что позволяет упростить взаимодействие между процессами).

Во всяком случае. Надеюсь, это поможет.

Я думаю, что в основном вы не добавляете ненужные env_vars в глобальную среду. Вы можете сохранить их целевые и уникальные, если их больше 1.

С уважением,

Ричард.

18 голосов
/ 20 ноября 2008

Ваша проблема, кажется, что-то вроде того, что мы пережили, и может быть очень сложно выяснить, что происходит.

Что происходит, когда переменные среды добавляются / удаляются / изменяются, среда services не распознает это, пока не "перезапустится". Это связано с тем, что эти переменные среды хранятся в реестре, и этот реестр читается только один раз средой службы ... при запуске системы .

Это означает, что для того, чтобы служба подхватила изменение переменных среды, необходимо произвести перезагрузку системы.

Проверьте Microsoft KB на этом.

6 голосов
/ 20 ноября 2008

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

1 голос
/ 16 июня 2013

Вам необходимо проверить, как хранилась переменная. Существует метод перегрузки для Set / GetEnvironmentVariable:

Environment.GetEnvironmentVariable Method (String, EnvironmentVariableTarget)

Дело в том, что существует три типа хранения переменной среды ( EnvironmentVariableTarget ):

  • Машина (доступна для всех пользователей)
  • Пользователь (доступно для текущего пользователя)
  • Процесс (доступно только для текущего процесса [не рекомендуется)]

Если вы храните информацию как «Машина» или «Пользователь», вы можете проверить ее как выполняющуюся «Выполнить» (Win + R):% TIP_HOME%

Надеюсь, это поможет:)

1 голос
/ 15 октября 2009

попробуйте этот код строка getsyspath = System.Environment.GetEnvironmentVariable ("TIP_HOME", EnvironmentVariableTarget.Machine);

1 голос
/ 20 ноября 2008

Работаете ли вы под учетной записью локальной системы?

Перезагружали ли вы компьютер после добавления переменной TIP_HOME?

Службы, работающие в локальной системе, запускаются из службы services.exe, которая считывает свою среду только при запуске: http://support.microsoft.com/kb/821761

1 голос
/ 20 ноября 2008

Хорошо, я не совсем понимаю, но вот что я нашел ..

В том же сервисе я сначала пробую то, что описал ранее, и строка возвращает пустое.

Затем, если я перечислю все переменные окружения системного уровня, он найдет нужную переменную.

Вот фрагмент кода, слегка модифицированный из некоторого примера кода, найденного в MSDN:

foreach(DictionaryEntry de in Environment.GetEnvironmentVariables(tgt))
{
    key   = (string)de.Key;
    value = (string)de.Value;

    if(key.Equals("TIP_HOME") && value != null)
        log.WriteEntry("TIP_HOME="+value, EventLogEntryType.Information);
}
0 голосов
/ 21 марта 2015

Службы обычно работают под одной из трех учетных записей служб, Local Service Local System и Network Service. Для всех ваших типичных переменных среды будет null .


Для расследования


Я проверил, когда служба записывает запись в журнал событий и печатает то, что хранит в переменной HOMEPATH. Он вернулся пустым для служебных учетных записей. В C #:

protected override void OnStart(string[] args)
{
    EventLog.WriteEntry("The HomePath for this service is '" + Environment.GetEnvironmentVariable("HOMEPATH") + "'", EventLogEntryType.Information);
}

Возможные решения


Вы можете указать, какую учетную запись использует служба (например, учетную запись пользователя), в окне свойств службы или в конфигурации установки службы. Когда я тестировал с моей учетной записью пользователя, запись в журнале событий отображалась The HomePath for this service is '\Users\Admin-PC'. Если бы он использовал вашу учетную запись, он имел бы доступ ко всем переменным среды, к которым у вас обычно есть доступ.
enter image description here. enter image description here

0 голосов
/ 20 ноября 2008

Я изменил эту строку кода следующим образом:

string t = System.Environment.GetEnvironmentVariable ("TIP_HOME", EnvironmentVariableTarget.Machine);

Я могу просмотреть свой реестр и убедиться, что TIP_HOME установлен.

Это из MSDN: Машина: переменная среды сохраняется или извлекается из ключа HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment в реестре операционной системы Windows.

Пользовательские переменные хранятся в другом месте в реестре ..

Строка все еще отображается пустой, когда я запускаю службу с этим изменением.

0 голосов
/ 20 ноября 2008

Вам известны переменные окружения system и user ? Служба Windows по умолчанию работает под учетной записью system .

...