核心编程学习笔记5——进程的环境变量[通俗易懂]

核心编程学习笔记5——进程的环境变量[通俗易懂]转载自http://hi.baidu.com/csw8923/blog/item/c401baa293d1cda4cbefd082.html要点描述:1.调用GetEnvironmentStrings函数来获取完整的环境块。在GUI的环境下2.在CUI的程序里,可以通过程序main入口点函数的TCH

大家好,欢迎来到IT知识分享网。

转载自http://hi.baidu.com/csw8923/blog/item/c401baa293d1cda4cbefd082.html

要点描述:
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则删除变量。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29333.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信