Программное добавление каталога в переменную среды Windows PATH - PullRequest
15 голосов
/ 17 декабря 2009

Я пишу Win32 DLL с функцией, которая добавляет каталог в переменную среды Windows PATH (для использования в установщике).

Просмотр переменных среды в Regedit или на Панели управления после запуска DLL показывает, что моей DLL удалось добавить путь к HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment и HKEY_CURRENT_USER\Environment.

Но когда я запускаю новую командную строку (после запуска DLL), добавленный каталог не отображается в выводе echo %PATH%, и я не могу получить доступ к исполняемому файлу, который находится в этом каталоге, введя его имя .

Я думаю, что моя программа не выполняет хорошую работу по уведомлению системы об изменении PATH или, возможно, она уведомляет их до того, как изменение полностью вступит в силу. Я прочитал статью Microsoft , в которой говорится о передаче сообщения WM_SETTINGCHANGE после изменения переменной среды, и я делаю это с помощью следующего кода:

DWORD result2 = 0;
LRESULT result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
    (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &result2);
if (result == 0){ /* ... Display error message to user ... */ }

Порядок моих звонков: RegCreateKeyEx, RegSetValueEx, RegCloseKey, SendMessageTimeout

Если я нажму «ОК» в окне «Переменные среды» панели управления, изменения, внесенные моей DLL в PATH, появятся во вновь созданных командных приглашениях, поэтому панель управления что-то делает для распространения PATH изменения; Я хочу выяснить, что это такое, и сделать то же самое.

Кто-нибудь знает, что мне делать?

Я использую 64-разрядную версию Windows Vista, но хочу, чтобы она работала во всех операционных системах Windows XP, Vista и Windows 7.

Обновление: Проблема с кодом, который я разместил выше, заключается в том, что я не поместил префикс L в строку "Environment". Хотя это нигде не сказано явно нигде в документации Microsoft, которую я могу найти, LPARAM должен быть указателем на строку WCHAR (2-байтовые символы), а не строкой CHAR, которую по умолчанию генерирует компилятор Visual Studio. когда я пишу строковый литерал. Решением моей проблемы было изменение «Окружающая среда» на L «Окружающая среда». (Я думал, что уже пробовал это до публикации этого вопроса, но, видимо, я не пробовал правильно!) Но любой, кто хочет получить полное решение C ++ для этой задачи, должен посмотреть на ответ Дэна Молдинга.

Ответы [ 2 ]

11 голосов
/ 17 декабря 2009

Оказывается, на самом деле не ничего нового под солнцем. Это уже было сделано раньше, по крайней мере, один раз. Мной. Я создал DLL, очень похожую на то, что вы описываете, для той же цели (для использования при изменении пути из установщика NSIS). Он используется установщиком Visual Leak Detector .

DLL называется editenv.dll. Источник доступен на github. Я только что проверил установщик, и он обновил переменную среды system PATH, без проблем. Исходя из того, что вы написали, я не вижу ничего, что было бы неправильно. Я также не вижу ничего очевидного, чего не хватает. Но, возможно, стоит взглянуть на источник editenv.dll (вас больше всего заинтересуют EnvVar::set() в EnvVar.cpp и, возможно, pathAdd() и pathRemove() C API в editenv.cpp ).

0 голосов
/ 17 декабря 2009

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

Осторожно, как открывает командную строку.

Если вы откроете командную строку, выполнив следующее:

Start -> Run -> cmd.exe

тогда среда в приглашении показывает, что установлена ​​новая переменная.

Однако у меня также есть программируемая функциональная клавиша на клавиатуре, которую я настроил для запуска процесса cmd.exe. Если я открою командную строку с помощью этой функциональной клавиши и наберу env, переменная не будет показана как установленная.

Я не уверен, почему он работает по-другому, но он должен иметь какое-то отношение к способу запуска процесса cmd.exe (хотя оба запускаются под моим именем пользователя, а не SYSTEM).

Как вы открываете командную строку?

...