打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
进程的环境变量
userphoto

2010.12.26

关注
 
要点描述:
1.调用GetEnvironmentStrings函数来获取完整的环境块。在GUI的环境下
2.在CUI的程序里,可以通过程序main入口点函数的TCHAR *en[]参数来接收环境变量。
3.使用SendMessage函数为应用程序即可更新环境变量。
4.使用 GetEnvironmentVariable 函数来 判断一个环境变量是否存在。
5.把环境变量替换成字符串 ExpandEnvironmentStrings 函数。
6.使用 SetEnvironmentVariable 来添加、删除、修改一个变量的值。
向像下面格式就为一个进程的环境变量。
=::=::\ ...
VarName1=VarValue1\0
VarName2=VarValue2\0
VarName3=VarValue3\0 ...
VarNameX=VarValueX\0
\0
在每个字符串第一部分:是环境变量的名称
然后等号后的部分乃是 希望赋给此变量的值。
但是在请注意 =::=::\ ... 是以等号开头的这种字符串,却不能作为环境变量。
如何获取环境变量呢?

第一种方法:我们可以调用GetEnvironmentStrings函数来获取完整的环境块。
下面乃一个实例程序:
==================================================
void DumpEnvStrings() {
   PTSTR pEnvBlock = GetEnvironmentStrings();
   // 解析块格式如下:
   //    =::=::\
   //    =...
   //    var=value\0
   //    ...
   //    var=value\0\0
   // 请注意,其他一些字符串的开始处可能会是这样的 '='.
   // 下面是当应用程序是从网络共享开始德一个例子.
   //    [0] =::=::\
   //    [1] =C:=C:\Windows\System32
   //    [2] =ExitCode=00000000
   //
   TCHAR szName[MAX_PATH];
   TCHAR szValue[MAX_PATH];
   PTSTR pszCurrent = pEnvBlock;
   HRESULT hr = S_OK;
   PCTSTR pszPos = NULL;
   int current = 0;
   while (pszCurrent != NULL) {
      // 跳过毫无意义的字符串:
      // "=::=::\"
      if (*pszCurrent != TEXT('=')) {
         // 查询 '=' 分离器.
         pszPos = _tcschr(pszCurrent, TEXT('='));
         // 现在点的值的第一个字符.
         pszPos++;
         // 复制的变量名.
         size_t cbNameLength = // 没有' ='
            (size_t)pszPos - (size_t)pszCurrent - sizeof(TCHAR);
           // 计算出字符串的长度(以字节为单位)
         hr = StringCbCopyN(szName, MAX_PATH, pszCurrent, cbNameLength);
         if (FAILED(hr)) { // 失败了则直接退出
            break;
         }
         // 复制到最后值要与空字符结尾
         // 当长度大于缓冲区时允许使用StringCchCopyN函数截断。
         hr = StringCchCopyN(szValue, MAX_PATH, pszPos, _tcslen(pszPos)+1);
         if (SUCCEEDED(hr)) { // 成功了 则执行下面语句。
            _tprintf(TEXT("[%u] %s=%s\r\n"), current, szName, szValue);
         } else // 当发生错误时,检查截断.
         if (hr == STRSAFE_E_INSUFFICIENT_BUFFER) {
            _tprintf(TEXT("[%u] %s=%s...\r\n"), current, szName, szValue);
         } else { // 这个应该永远不会发生.
            _tprintf(
               TEXT("[%u] %s=???\r\n"), current, szName
               );
            break;
         }
      } else {
         _tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);
      }
      // 下一个变量.
      current++;
      // 移动到字符串的末尾.
      while (*pszCurrent != TEXT('\0'))
         pszCurrent++;
      pszCurrent++;
      // 检查它是否是最后一个字符串.
      if (*pszCurrent == TEXT('\0'))
         break;
   };
   // 不要忘记释放内存.
   FreeEnvironmentStrings(pEnvBlock);
}
另一种方法是:
访问环境变量,它是CUI(控制台)程序专用的,可通过程序main入口点函数的TCHAR *en[]参数来接收。
env 是一个指针数组, 每个指针都指向一个不同的环境变量,而在最后一个环境变量指针后通常会带有一个NULL指针。
表明已经到达数组末尾了。
==================================================
代码所示:
void DumpEnvVariables(PTSTR pEnvBlock[]) {
   int current = 0;
   PTSTR* pElement = (PTSTR*)pEnvBlock;
   PTSTR pCurrent = NULL;
   while (pElement != NULL) { // 当到达NULL则表明已经到达指针数组末尾了。
      pCurrent = (PTSTR)(*pElement);
      if (pCurrent == NULL) {
         //没有更多的环境变量了.
         pElement = NULL;
      } else {
         _tprintf(TEXT("[%u] %s\r\n"), current, pCurrent);
         current++;
         pElement++;
      }
   }
}
另外请注意,等号开头的无效字符串在我们接收到env之前其实就被移除了,所以可以不用处理。
1.使用SendMessage函数为应用程序即可更新环境变量。
当我们通过应用程序或直接修改注册表的环境变量时,为了使其生效用户一般要注销或重启,
然后有些应用程序却可以通过主窗口接收到WM_SETTINGCHANGE消息,来使用新的环境变量。
这时,我们完全可以调用 SendMessage()函数来实现更新。
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) TEXT("Environment"));
另外父进程和子进程之间若有继承关系的话... 那么环境变量也可以继承,但他们是相互独立而不是共享使用的。
2.我们还可以使用 GetEnvironmentVariable 函数来 判断一个环境变量是否存在。
函数声明:
DWORD GetEnvironmentVariable(
   PCTSTR pszName, // 指向预期变量名称。
   PTSTR pszValue,     // 指向保存变量值的缓冲区
   DWORD cchValue // 缓冲区大小
   );
  
   变量名若没找到返回复制到缓冲区的字符数。
   如果在环境中美找到变量名,就返回0.
   函数需要调用两次,第一次向cchValue参数传入0,以返回所需字符数量,其中也包括了结束符NULL。
   函数使用示例
   void PrintEnvironmentVariable(PCTSTR pszVariableName) {
   PTSTR pszValue = NULL;
   // 获取足够的,所需要的存储缓冲区的大小值
   // 第一次调用 GetEnvironmentVariable 函数,最后一个参数传入0以获取足够缓冲区大小值。
   DWORD dwResult = GetEnvironmentVariable(pszVariableName, pszValue, 0);
   if (dwResult != 0) {
      // 分配好缓冲区以存储环境变量的值
      DWORD size = dwResult * sizeof(TCHAR);
      pszValue = (PTSTR)malloc(size);
      // 给变量分配好一个符号要求的内存空间
      // 第2次调用 GetEnvironmentVariable 函数 并获取环境变量。
      GetEnvironmentVariable(pszVariableName, pszValue, size);
      _tprintf(TEXT("%s=%s\n"), pszVariableName, pszValue);
      free(pszValue);
   } else {
     // 获取失败的提示语句
      _tprintf(TEXT("'%s'=<unknown value>\n"), pszVariableName);
   }
}
3.把环境变量替换成字符串 ExpandEnvironmentStrings 函数。
类似于 %USERPROFILE%\Documents 转换后为 C:\Users\jrichter\Documents.
其表示: %USERPROFILE% == C:\Users\jrichter\
函数声明:
DWORD ExpandEnvironmentStrings(
   PTCSTR pszSrc, // 参数是 "可替换环境变量的字符串"的一个字符串地址
   PTSTR pszDst,   // 用于接收扩展字符串的一个缓冲区地址
   DWORD chSize // 缓冲区所需的大小
   );
其中 chSize 不能小于 缓冲区大小,不然%%变量就不会被扩展,会被替换为空字符串。
所以,通常我们需要 调用两次 ExpandEnvironmentStrings 函数。
DWORD chValue =
   // 第一次调用 ExpandEnvironmentStrings 函数..其中最后参数为0自动获取大小。
   ExpandEnvironmentStrings(TEXT("PATH='%PATH%'"), NULL, 0);
   // 分配内存空间
   PTSTR pszBuffer = new TCHAR[chValue];
   // 第二次调用 ExpandEnvironmentStrings 函数.并且获取到可替换的字符串内容。
   chValue = ExpandEnvironmentStrings(TEXT("PATH='%PATH%'"), pszBuffer, chValue);
   _tprintf(TEXT("%s\r\n"), pszBuffer);
   delete[] pszBuffer;
4.可以使用 SetEnvironmentVariable 来添加、删除、修改一个变量的值
  
     BOOL SetEnvironmentVariable(
     PCTSTR pszName, // 为变量设为psazValue参数所标识的值。
     PCTSTR pszValue // 这个参数如果设置为NULL,就是表面要将环境块中删除变量
     );
     当 pszName 与 pszValue 参数一样时,要么就添加会修改一个变量。
         pszValue 设为 NULL则删除变量。
本文出自
映轩晓屋 - 资料库 - http://csw8923.vipkj.com/Html/?488.html
 
(#)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
WINCC脚本字符串处理总结
《windows核心编程系列》四谈谈进程的建立和终止
C语言面试题
「老叶PHP笔记」009PHP数据类型——资源和空值
shell常用命令
UNIX环境编程学习笔记(16)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服