Доступ к переменным среды от Windows Services

Неустранимая ошибка: не может использовать возвращаемое значение функции в контексте записи

Это обычно происходит при непосредственном использовании функции с empty.

Пример:

if (empty(is_null(null))) {
  echo 'empty';
}

Это связано с тем, что empty - это языковая конструкция, а не функция, она не может быть вызвана с выражением в качестве аргумента в версиях PHP до 5.5. До PHP 5.5 аргумент empty() должен быть переменной , но произвольное выражение (такое как возвращаемое значение функции) допустимо в PHP 5.5 +.

empty, несмотря на его имя, на самом деле не проверяет, является ли переменная «пустой». Вместо этого он проверяет, существует ли переменная, или == false. Выражения (например, is_null(null) в примере) всегда будут считаться существующими, поэтому здесь empty проверяет только, равен ли он false. Здесь вы можете заменить empty() на !, например. if (!is_null(null)), или явно сравнить с ложным, например. if (is_null(null) == false).

Вопросы, относящиеся

23
задан David d C e Freitas 26 September 2011 в 11:50
поделиться

10 ответов

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

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

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

Посмотрите Microsoft KB по этому вопросу.

19
ответ дан Scott Saad 29 November 2019 в 01:12
поделиться

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

6
ответ дан EBGreen 29 November 2019 в 01:12
поделиться

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

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

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

Вот фрагмент кода, немного измененный от некоторого примера кода, найденного на 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);
}
1
ответ дан Brian 29 November 2019 в 01:12
поделиться

Вы выполняете сервис в соответствии с Локальной Системной учетной записью?

Вы перезапустили машину после добавления переменной TIP_HOME?

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

1
ответ дан Michael Burr 29 November 2019 в 01:12
поделиться

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

Environment.GetEnvironmentVariable (String, EnvironmentVariableTarget)

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

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

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

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

1
ответ дан lucas 29 November 2019 в 01:12
поделиться

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

0
ответ дан Steve Dunn 29 November 2019 в 01:12
поделиться

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

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

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

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

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

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

0
ответ дан Brian 29 November 2019 в 01:12
поделиться

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


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


Я проверил, чтобы служба записала запись в журнал событий и напечатала то, что она хранит в переменной 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
ответ дан Joseph 29 November 2019 в 01:12
поделиться

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

1
ответ дан 29 November 2019 в 01:12
поделиться

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

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

Допустим, ключ к вашей службе ...

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.

С уважением,

Ричард.

31
ответ дан 29 November 2019 в 01:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: