我正在使用将目录添加到Windows PATH环境变量(用于安装程序)的函数来编写Win32 DLL。以编程方式将目录添加到Windows PATH环境变量
在DLL运行后查看Regedit或控制面板中的环境变量,显示我的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前缀放在“Environment”字符串上。虽然它没有在Microsoft文档中的任何地方明确说明,但LPARAM需要是指向WCHAR字符串(2字节字符)的指针,而不是CHAR字符串,这是Visual Studio编译器默认生成的内容当我写一个字符串文字。解决我的问题的方法是将“环境”更改为L“环境”。 (我以为在发布这个问题之前我已经尝试过了,但显然我没有正确尝试!)但是任何想要完成此任务的C++解决方案的人都应该看看Dan Molding的答案。
你可能想看看一些开源安装程序的源代码,例如NSIS或Inno Setup。他们这样做是正确的。 – bialix
一个小巧的快速提示,只需输入“path”并按下回车即可在命令提示符下显示PATH内容。每次测试可以保存7次击键(9次计算Shift键)! – Todd
嗯,你必须建立一个Unicode应用程序,所以'windows.h'引入了API的版本('SendMessageTimeoutW'),这需要'LPCWSTR'来代替'LPCSTR'。我认为如果你想支持“ANSI”和Unicode编译,那么正确的做法是使用“LPCTSTR”(即通过'_T()'宏)。我的库可能可以使用更新来使其“Unicode意识到”。它目前仅支持使用“ANSI”设置环境变量,如果在路径中需要带有西里尔文字符的目录,则可能会产生问题。 –