Я пишу DLL Win32 с функцией, которая добавляет каталог в переменную среды PATH Windows (для использования в установщике).Программно добавление каталога в переменную среды Windows PATH
Рассмотрение переменных среды в Regedit или панели управления после запуска DLL показывает мне, что моей DLL удалось добавить путь к HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
и HKEY_CURRENT_USER\Environment
.
Но когда я запускаю новую командную строку (после запуска библиотеки DLL), каталог, который я добавил, не отображается в выводе echo %PATH%
, и я не могу получить доступ к исполняемому файлу, который живет в этом каталоге, набрав его имя.
Я думаю, что моя программа не очень хорошо уведомляет систему о том, что PATH изменилась, или, может быть, она уведомляет их, прежде чем изменение полностью вступит в силу. Я прочитал article by 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 в строку «Окружающая среда». Хотя он не говорит об этом явно в документации Microsoft, которую я могу найти, LPARAM должен быть указателем на строку WCHAR (2-байтовые символы) в отличие от строки CHAR, что и компилятор Visual Studio по умолчанию когда я пишу строковый литерал. Решение моей проблемы состояло в том, чтобы изменить «Окружающая среда» на L «Окружающая среда». (Я думал, что я уже пробовал это, прежде чем публиковать этот вопрос, но, видимо, я не пробовал это правильно!) Но любой, кто хочет получить полное решение на C++ для этой задачи, должен посмотреть на ответ Дэна Молдинга.
Возможно, вы захотите ознакомиться с исходным кодом некоторых инсталляторов с открытым исходным кодом, например. NSIS или Inno Setup. Они делают это уведомление правильно. – bialix
Один маленький быстрый совет, вы можете показать содержимое PATH в командной строке, просто набрав «путь» и нажав enter. Сохраняет вам 7 нажатий клавиш на тест (9 отсчет смены)! – Todd
Ах, вы должны создать приложение Unicode, поэтому 'windows.h' вносит в Unicode версию API (' SendMessageTimeoutW'), для чего потребуется 'LPCWSTR' для' LPARAM' вместо 'LPCSTR'. Я думаю, что если вы хотите поддерживать как «ANSI», так и Unicode-сборки, тогда правильная вещь - использовать «LPCTSTR» (т. Е. С помощью макроса '_T()»). Возможно, моя библиотека могла использовать обновление, чтобы сделать его «Unicode aware». В настоящее время он поддерживает только настройку переменных среды с помощью «ANSI», что может быть проблематичным, если вам нужен каталог с, скажем, кириллическими символами на вашем пути. –