1

我有一个C++程序调用GetEnvironmentVariable()来获取'Path'变量信息。如果我正在运行我的程序,同时,我通过“我的计算机 - >属性 - >环境变量”更改我的'路径'变量?...是否完全不可能从GetEnvironmentVariable()检索更新的'路径'变量重新启动我的程序(和Visual Studio)。当我的电脑发生更改时更新环境变量

this postingAnders K提到:

“确保你重新启动应用程序,然后才能读取环境变量,如果你有一个控制台窗口打开并更改我的电脑环境变量同样的情况。这些在任何现有的控制台窗口中都没有记录,您需要重新启动它们以获取新环境变量的副本。“

这是否意味着有100%无法检索更新的“路径”变量?我不确定我是否浪费了我的时间。

此外,我试图像this,但没有成功。

谢谢。

+1

只是一个想法,而不是一个解决方案......但你可以尝试从你的程序中启动另一个(短命的)进程并使用它来读取环境变量 – andypaxo

+1

你应该看看CreateEnvironmentBlock(http:// msdn .microsoft.com/EN-US /库/窗/台式机/ bb762270%28V = vs.85%29.aspx)。我之前没有用过它,所以发布评论而不是答案,但看起来应该适合你。 –

+1

或者,为了回显@andypaxo,shell执行“cmd:ECHO%PATH%”,但一定不要将cmd进程创建为现有进程的子进程,否则它只会继承您的环境块。 –

回答

0

源自很有帮助响应的建议,我决定使用注册表项来获得更新的环境变量来代替。

假设:

DWORD BufferSize = 16383; 
    TCHAR pathVar[16383]; 

之前,我所做的:

GetEnvironmentVariable(_T("Path"),pathVar,16383); 

,从来没有给我更新Path环境变量,如果我通过我的电脑“属性更新。

现在,我做的:

DWORD dwRet = RegGetValue(HKEY_LOCAL_MACHINE, 
    _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"), 
    _T("Path"), RRF_RT_ANY, NULL, (PVOID)&pathVar, &BufferSize); 

    if(dwRet != ERROR_SUCCESS){ 
     GetEnvironmentVariable(_T("Path"),pathVar,16383); 
    } 

后者从注册表键的值。但是,如果由于某种原因RegGetValue()失败,它将通过GetEnvironmentVariable()获得该值,该值可能未完全更新,但至少我获得了可以使用的值。谢谢大家的建议。

3

好吧,不是100%不可能的。编辑这样的环境变量只能设置注册表项。您可以使用Regedit.exe查看它们,导航到HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet \ Control \ Session Manager \ Environment,您会看到在编辑框中看到的值列表。用户特定的存储在HKEY_CURRENT_USER \ Environment中。

然后键是进程开始使用这些值。这取决于,一个进程可以从启动它的进程继承环境,CreateProcess()的lpEnvironment参数决定了这一点。传递一个NULL并因此继承是非常普遍的,所以启动的进程不会看到这些变化,它从它的父节点获得了一个陈旧环境的副本。要真正确保唯一的办法就是注销并重新登录,所以你知道,这样的过程开始了与环境变化的事实。或者只是尝试一下,所以你知道。

不是100%不可能的角度是实际读取这些注册表项。不完全实用,当然也不完全不可移植。 PATH环境变量实际上仅在从shell启动程序时才有用。

2

如果你需要它在这种意义上是动态的,那么你正在使用错误的东西。不要使用环境变量,使用注册表项等。

1

环境变量不会直接从注册表传送到您的应用程序,它们只能由资源管理器读取一次,然后由其创建的任何子进程传递/继承。然而有一种机制,允许应用程序,当它改变了注册表值,告诉应用程序使用WM_SETTINGCHANGE广播消息lParam指向包含“环境”的字符串重新加载这些值。

通常,只有浏览器荣誉该消息,但你可以检测到它在自己的应用程序,并再次直接从注册表中读取的数据。