обновление значения переменных среды

В моем проекте Installscript мне нужна перезагрузка, чтобы зарегистрировать значения переменных среды. Но я хочу, чтобы это приложение устанавливалось без перезагрузки. Так есть ли способ обновить значения переменной Environment, чтобы мое приложение было зарегистрировано и перезагрузка не требовалась? Я уже использую следующую строку кода:

define WM_WININICHANGE 0x001A'
define HWND_BROADCAST 0xffff'
szEnv = "Environment";
pEnv = &szEnv;
SendMessage( HWND_BROADCAST, WM_WININICHANGE, 0, pEnv );`

Есть ли другой способ обновить значения переменных среды? Я запускаю это на Windows XP.


person nvivekgoyal    schedule 20.10.2011    source источник
comment
Если вы используете InstallShield 2010 или более позднюю версию, приведенный выше код не будет работать. См. здесь решение: пакетный файл не может сразу увидеть переменные среды, созданные installshield"> stackoverflow.com/questions/2103790/   -  person Derek W    schedule 04.12.2013


Ответы (2)


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

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

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

person cosmin    schedule 20.10.2011

Отправка сообщения WININICHANGE на широковещательный адрес является правильным решением. Однако не требуется, чтобы все запущенные процессы правильно подклассифицировали это сообщение и обновляли свои переменные среды для этого процесса. Должны, но не всегда. Самый известный пример — Service Control Manager. Вы должны перезагрузиться, чтобы SCM увидел новую переменную/значение.

Теперь, если вы спрашиваете: «Как мне заставить мой текущий запущенный процесс увидеть это значение?» (Космин, кажется, думает, что это то, о чем вы спрашиваете, но я не уверен, так это или нет), тогда ответ заключается в понимании того, что пространство среды имеет четыре коллекции:

Пользовательский машинный процесс Неустойчивый

http://msdn.microsoft.com/en-us/library/6s7w15a0(v=vs.85).aspx

Что делает ваш код, так это устанавливает переменную среды для SYSTEM. Это похоже на старые времена, когда вы добавляли строку в свой autoexec.bat ( SET FOO=BAR ) и перезагружались. Но вы также можете создать новое приглашение dos из окон и выполнить SET SOMETHING=ELSE, и оно будет видно только для жизни этого процесса и дочерних процессов, но не для других процессов. Это пространство «Процесс» и пространство «Система». Кроме того, если вы обновили AUTEXEC.BAT с новой переменной и создали новый процесс без перезагрузки, он не увидит новую переменную, но вы всегда можете установить ее самостоятельно и увидеть ее (хотя технически это не то же самое).

Я знаю, что с SendMessage вам не нужна перезагрузка, но, тем не менее, не все процессы получат сообщение.

Таким образом, если вам нужно, чтобы текущий процесс InstallScript также имел эту новую переменную, вы можете вызвать SetEnvironmentVariable, которая, согласно MSDN, "устанавливает содержимое указанной переменной среды для текущего процесса".

Интересно, что в InstallScript есть функция GetEnvVar, но нет функции SetEnvVar, поэтому вам придется прототипировать ее как внешнюю функцию, а затем вызывать.

Обсуждение с примерами можно найти здесь.

person Christopher Painter    schedule 20.10.2011