我在调试窗口能看到,赋给PATH的字符串是正确的,
赋值成功后,右键我的电脑--高级--环境变量,也可以看到环境变量已经添加在path尾部。
但奇怪的是,依然不能使用,而且注销之后,连系统原来的环境变量像chkdsk, convert也不能使用了。
这是否涉及权限问题,求高人解释下。
HKEY hkResult;
if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
_T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"), 
0,
KEY_SET_VALUE | KEY_READ, 
&hkResult))
{
MessageBox(_T("访问注册表出错!"));
}

DWORD BufferSize = 8192;
DWORD cbData;
DWORD dwRet; VOID* PerfData = malloc( BufferSize );
cbData = BufferSize; dwRet = RegQueryValueEx( hkResult,
_T("Path"),
NULL,
NULL,
(LPBYTE) PerfData,
&cbData ); while (dwRet == ERROR_MORE_DATA)
{
BufferSize += 4096;
PerfData = realloc( PerfData, BufferSize );
cbData = BufferSize; dwRet = RegQueryValueEx( hkResult,
_T("Path"),
NULL,
NULL,
(LPBYTE) PerfData,
&cbData ); } MessageBox((LPCTSTR)PerfData); LPTSTR javaHome = _T(";%JAVA_HOME%\\bin;"); TCHAR *temp = new TCHAR[cbData+sizeof(javaHome)]; _tcscpy_s(temp, cbData, (LPTSTR)PerfData); LPTSTR path = _tcscat(temp, javaHome);         RegSetValueEx(hkResult, 
L"Path",        
0,                        
REG_SZ,                
(LPBYTE) path, 
_tcsclen(path)*sizeof(TCHAR))         DWORD dwResult; SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,LPARAM("Environment"), SMTO_ABORTIFHUNG, 5000, &dwResult);         delete temp;

解决方案 »

  1.   

    Path的键类型不是REG_SZ,是REG_EXPAND_SZ。用REG_SZ后,所有的%XXX%都不能被替换(在命令行运行path命令可以看到)。
      

  2.   

    回复1楼照你的做法,现在可以了,
    可是我在注册表看了,定义了REG_SZ类型还是REG_EXPAND_SZ,这个不明白
    现在还有一个问题,这个消息没成功啊
    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,LPARAM("Environment"), SMTO_ABORTIFHUNG, 5000, &dwResult);
    修改不能立即得到反映我打开环境变量修改那里,点一下确定就行了,说明这函数没执行吗?
      

  3.   

    当作REG_SZ写,注册表中还是REG_EXPAND_SZ的问题不知道为什么,我以前也遇到过你这个问题,当作REG_SZ写了,结果把所有的%XXX%路径都整的不能用了,很是郁闷。 另外,SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,LPARAM("Environment"), SMTO_ABORTIFHUNG, 5000, &dwResult);后应该是马上启效的,你再用path命令确认一下,实在不行的话我给你发个测试程序。
      

  4.   

    回复5楼,用PATH命令确实没有看到变化
    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,LPARAM("Environment"), SMTO_ABORTIFHUNG, 5000, &dwResult);
    没有效果,
    你给我发个测试程序吧,我不知道哪里写错了
      

  5.   

    REG_EXPAND_SZ(可扩充字符串值)    REG_EXPAND_SZ条目代表一个可扩展的字符串。该条目编辑器与标准REG_SZ条目编辑器看起来基本相同,只是在变量用法上有所差异。在REG_EXPAND_SZ条目编辑器中输入变量后,当激活该变量时,系统会用相应的文本替换该变量。    REG_EXPAND_SZ条目的一个典型应用就是经常用到的%SYSTEMROOT%变量,激活该变量后,会返回 Windows NT、Windows 2000或Windows xp文件所在的具体目录。%USERNAME%也作为变量使用,其具体数值就是已登录的用户名。    提示:在要求使用变量条目REG_EXPAND_SZ时,如果使用的是一个REG_SZ(字符串)条目,则注册表就不会用正确的信息替换该变量,它只是将实际的变量简单地作为文本来返回。
      

  6.   

    下面代码在VC6+XP SP2下测试通过, 执行后运行cmd进入命令行,用path命令可看到已经加上了. 注意,必须是程序执行后新开命令行窗口用path命令测试, 不能在原有命令行窗口中测试. #include <shlwapi.h>
    BOOL AddPath(LPCTSTR szPath)
    {
    CString strKey = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";

    HKEY hKey;
    RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0L, KEY_ALL_ACCESS, &hKey);

    DWORD dwType = 0, dw = 0;
    RegQueryValueEx(hKey, _T("Path"), NULL, &dwType, NULL, &dw); CString sPath;
    LPTSTR lpsz = sPath.GetBufferSetLength(dw);
    RegQueryValueEx(hKey, _T("Path"), NULL, &dwType, (BYTE*)lpsz, &dw);
    sPath.ReleaseBuffer();

    sPath = CString(szPath) + _T(";") + sPath;
    RegSetValueEx(hKey, _T("Path"), NULL, REG_EXPAND_SZ,
    (BYTE * const)(LPCSTR)sPath, (sPath.GetLength()+1)*sizeof(TCHAR));

    RegCloseKey(hKey); DWORD dwRet;
    SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,0,
    (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000,&dwRet);

    return TRUE;
    }//调用
    AddPath(_T("c:\\test2"));
      

  7.   

    直接用SetEnvironmentVariable()API.BOOL WINAPI SetEnvironmentVariable(
      __in      LPCTSTR lpName,
      __in_opt  LPCTSTR lpValue
    );
      

  8.   

    回复9楼你确定path命令之后是加上了吗?
    我这边SP3,没有加上。回复10楼
    你的方法绝对是不行的,MSDN有说。
      

  9.   

    我用MFC,unicode编译的,不知道有没有影响?帖子结了,问题留着,以后学着学着应该会找到答案的,谢谢iamshuke的解答。