1. 程式人生 > >基於visual c++之windows核心程式設計程式碼分析(21)獲取和設定環境變數

基於visual c++之windows核心程式設計程式碼分析(21)獲取和設定環境變數

環境變數是一個具有特定名字的物件,它包含了一個或者多個應用程式所將使用到的資訊。例如path,當要求系統執行一個程式而沒有告訴它程式所在的完整路徑時,系統除了在當前目錄下面尋找此程式外,還應到path中指定的路徑去找。使用者通過設定環境變數,來更好的執行程序。
環境變數一般是指在作業系統中用來指定作業系統執行環境的一些引數,比如臨時資料夾位置和系統資料夾位置等。這點有點類似於DOS時期的預設路徑,當你執行某些程式時除了在當前資料夾中尋找外,還會到設定的預設路徑中去查詢。簡單地說這裡的“Path”就是一個變數,裡面儲存了一些常用命令所存放的目錄路徑。  

 環境變數相當於給系統或使用者應用程式設定的一些引數, 具體起什麼作用這當然和具體的環境變數相關. 比如path, 是告訴系統, 當要求系統執行一個程式而沒有告訴它程式所在的完整路徑時, 系統除了在當前目錄下面尋找此程式外, 還應到哪些目錄下去尋找; 再如tc或vc++中, set include=path1;path2; 是告訴編譯程式到哪裡去找.h型別的檔案; 當然不僅僅是指定什麼路徑, 還有其它的作用的, 如set dircmd=/4 設定一個環境變數的作用是在使用dir命令時會把/4作為預設的引數新增到你的dir命令之後, 就像你的每個命令都加了/4引數, 它實際上是給命令解釋程式command設定的一個環境變數, 並且是給dir這個內部命令設定的。  

 DWORD GetEnvironmentVariable(LPCSTR lpName, LPSTR lpBuffer, DWORD dSize), 引數lpName是你要求查詢的環境變數的名, lpBuffer是返回你所指定的環境變數的值的, dSize是告訴這個函式lpBuffer可以存放多少個位元組.   

分析本地故障時原因很可能就是因為環境變數中的預設路徑被刪除的結果,預設路徑一經設定,當前系統如有程式執行時需要某些DLL或EXE檔案,以及Active控制元件時就會到所有預設路徑中去查詢,如果在這些目錄中查詢到相應的程式則自動載入,查詢不到則報告缺少某某檔案的錯誤資訊。


環境變數的作用
解決雙系統的軟體共用問題
  很多朋友會在自己的計算機上安裝雙系統,例如C盤安裝Windows 98,D盤安裝Windows XP。可是某些軟體往往只在Windows 98系統中安裝,Windows XP系統中是無法正常使用的,比較麻煩卻有效的方法是再安裝一遍。當我們瞭解了環境變數中的用途後就可以很好解決雙系統的軟體共用問題。
解決系統執行問題
  為什麼在Windows 98中安裝了的軟體在Windows XP下無法執行呢(綠色軟體除外)?原因是安裝軟體時往往須要向系統目錄中複製某些檔案,而使用另外一個系統時會由於缺少這些檔案而無法執行。因此,我們可以通過設定環境變數的方法來解決這個問題。
編輯本段環境變數設定方法
  在windows作業系統中可以通過我的電腦-〉屬性-〉高階,來設定系統的環境變數,然而在此設定的環境變數是否在登錄檔中具有對應的項呢?答案是肯定的。而在.net 中提供了一個類來獲取系統的環境變數及其值。   環境變數分為兩類:使用者變數與系統變數,在登錄檔中都有對應的項。   其中使用者變數所在位置:   HKEY_CURRENT_USER\Environment;   系統變數所在位置為:\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001   \Control\Session Manager\Environment。   另外也可以右擊我的電腦——高階——環境變數——在系統變數裡有path選項——雙擊開啟——在原有變數的基礎上新增英文狀態下的分號——然後將路徑名輸入即可。(切記,不要刪除原先的系統變數,只要用分號隔開,然後新增)


  %ALLUSERSPROFILE% 區域性 返回所有“使用者配置檔案”的位置。  

 %APPDATA% 區域性 返回預設情況下應用程式儲存資料的位置。  

 %CD% 區域性 返回當前目錄字串。

  %CMDCMDLINE% 區域性 返回用來啟動當前的 Cmd.exe 的準確命令列。   

%CMDEXTVERSION% 系統 返回當前的“命令處理程式擴充套件”的版本號。

  %COMPUTERNAME% 系統 返回計算機的名稱。  

 %COMSPEC% 系統 返回命令列直譯器可執行程式的準確路徑。  

 %DATE% 系統 返回當前日期。使用與 date /t 命令相同的格式。由 Cmd.exe 生成。有關 date 命令的詳細資訊,請參閱 Date。   

%ERRORLEVEL% 系統 返回最近使用過的命令的錯誤程式碼。通常用非零值表示錯誤。

  %HOMEDRIVE% 系統 返回連線到使用者主目錄的本地工作站驅動器號。基於主目錄值的設定。使用者主目錄是在“本地使用者和組”中指定的。

  %HOMEPATH% 系統 返回使用者主目錄的完整路徑。基於主目錄值的設定。使用者主目錄是在“本地使用者和組”中指定的。  

 %HOMESHARE% 系統 返回使用者的共享主目錄的網路路徑。基於主目錄值的設定。使用者主目錄是在“本地使用者和組”中指定的。   

%LOGONSEVER% 區域性 返回驗證當前登入會話的域控制器的名稱。

   %NUMBER_OF_PROCESSORS% 系統 指定安裝在計算機上的處理器的數目。  

 %OS% 系統 返回作業系統的名稱。Windows 2000 將作業系統顯示為 Windows_NT。  

 %PATH% 系統 指定可執行檔案的搜尋路徑。  

 %PATHEXT% 系統 返回作業系統認為可執行的副檔名的列表。  

 %PROCESSOR_ARCHITECTURE% 系統 返回處理器的晶片體系結構。值: x86,IA64。  

 %PROCESSOR_IDENTFIER% 系統 返回處理器說明。  

 %PROCESSOR_LEVEL% 系統 返回計算機上安裝的處理器的型號。

  %PROCESSOR_REVISION% 系統 返回處理器修訂號的系統變數。  

 %PROMPT% 區域性 返回當前解釋程式的命令提示符設定。由 Cmd.exe 生成。  

 %RANDOM% 系統 返回 0 到 32767 之間的任意十進位制數字。由 Cmd.exe 生成。   %SYSTEMDRIVE% 系統 返回包含 Windows XP 根目錄(即系統根目錄)的驅動器。  

 %SYSTEMROOT% 系統 返回 Windows XP 根目錄的位置。   

%TEMP% and %TMP% 系統和使用者 返回對當前登入使用者可用的應用程式所使用的預設臨時目錄。有些應用程式需要 TEMP,而其它應用程式則需要 TMP。  

 %TIME% 系統 返回當前時間。使用與 time /t 命令相同的格式。由 Cmd.exe 生成。有關 time 命令的詳細資訊,請參閱 Time。

  %USERDOMAIN% 區域性 返回包含使用者帳戶的域的名稱。  

 %USERNAME% 區域性 返回當前登入的使用者的名稱。  

 %UserProfile% 區域性 返回當前使用者的配置檔案的位置。  

 %WINDIR% 系統 返回作業系統目錄的位置。

在命令列中對環境變數進行編輯的方法
  檢視當前可用的所有環境變數(=系統變數+使用者變數)  

 set   檢視某個環境變數,如PATH   set PATH  

 新增環境變數,如xxx=aa   set xxx=aa   將環境變數(如xxx)的值置為空   set xxx=  

 在某個環境變數(如PATH)後新增新的值(如d:\xxx)   set PATH=%PATH%;d:\xxx   

(注:在dos視窗中以命令列方式對環境變數的操作只對當前視窗的應用有效)

  1. /* 標頭檔案 */
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include "env.h"
  5. /* 預定義 */
  6. #define BUFSIZE 4096
  7. /************************************* 
  8. * DWORD WINAPI EnumEnvironmentVariables() 
  9. * 功能    顯示程序的所有環境變數 
  10. **************************************/
  11. DWORD WINAPI EnumEnvironmentVariables()  
  12. {  
  13.     // 獲取環境變數
  14.     PVOID pEv = GetEnvironmentStrings();  
  15.     LPSTR szEnvs;  
  16.     // 顯示
  17.     for (szEnvs = (LPSTR) pEv; *szEnvs;)   
  18.     {   
  19.         printf("%s\n",szEnvs);  
  20.         while (*szEnvs++);  
  21.     }  
  22.     // 釋放
  23.     FreeEnvironmentStrings(pEv);  
  24.     return 0;  
  25. }  
  26. /************************************* 
  27. * DWORD WINAPI ChangeEnviromentVariables(LPSTR szName,  
  28. LPSTR szNewValue,  
  29. DWORD dwFlag) 
  30. * 功能    改變環境變數 
  31. * 
  32. * 引數    LPSTR szName    需要改變的環境 
  33. *       LPSTR szNewValue    新的變數值 
  34. *       DWORD dwFlag    附加、重置還是清零,相關常量在env.h在定義 
  35. **************************************/
  36. DWORD WINAPI ChangeEnviromentVariables(LPSTR szName,   
  37.                                        LPSTR szNewValue,   
  38.                                        DWORD dwFlag)  
  39. {  
  40.     DWORD dwErr;  
  41.     PVOID szVal;  
  42.     DWORD dwReturn;   
  43.     DWORD dwNewValSize;  
  44.     // 如果標誌為附加則則先獲取,然後將szNewValue附加到末尾
  45.     if(dwFlag == VARIABLES_APPEND)  
  46.     {  
  47.         dwNewValSize = lstrlen(szNewValue)+1;   // 新變數值的大小
  48.         // 分配記憶體
  49.         szVal = HeapAlloc(GetProcessHeap(),0,BUFSIZE+dwNewValSize);  
  50.         // 獲取值
  51.         dwReturn = GetEnvironmentVariable(szName,szVal,BUFSIZE);  
  52.         if(dwReturn == 0)   // 出錯
  53.         {  
  54.             dwErr = GetLastError();  
  55.             if( ERROR_ENVVAR_NOT_FOUND == dwErr )  
  56.             {  
  57.                 printf("Environment variable %s does not exist.\n", szName);  
  58.             }  
  59.             else
  60.             {  
  61.                 printf("error: %d",dwErr);  
  62.             }  
  63.             return FALSE;  
  64.         }  
  65.         elseif(BUFSIZE < dwReturn)  // 緩衝區太小
  66.         {  
  67.             szVal = (LPTSTR) HeapReAlloc(GetProcessHeap(), 0,szVal, dwReturn+dwNewValSize);  
  68.             if(NULL == szVal)  
  69.             {  
  70.                 printf("Memory error\n");  
  71.                 return FALSE;  
  72.             }  
  73.             dwReturn = GetEnvironmentVariable(szName, szVal, dwReturn);  
  74.             if(!dwReturn)  
  75.             {  
  76.                 printf("GetEnvironmentVariable failed (%d)\n", GetLastError());  
  77.                 return FALSE;  
  78.             }  
  79.         }  
  80.         lstrcat(szVal,";");     // 分隔符
  81.         lstrcat(szVal,szNewValue);  // 附加
  82.         //設定
  83.         if(!SetEnvironmentVariable(szName,szVal))  
  84.         {  
  85.             printf("Set Value Error %d",GetLastError());  
  86.         }  
  87.         // 釋放記憶體
  88.         HeapFree(GetProcessHeap(),0,szVal);  
  89.         return TRUE;  
  90.     }  
  91.     // 如果是重置,則直接設定
  92.     elseif(dwFlag == VARIABLES_RESET)  
  93.     {  
  94.         if(!SetEnvironmentVariable(szName,szNewValue))  
  95.         {  
  96.             printf("Set value error %d",GetLastError());  
  97.         }  
  98.     }  
  99.     // 清零,忽略szNewValue
  100.     elseif(dwFlag == VARIABLES_NULL)  
  101.     {  
  102.         if(!SetEnvironmentVariable(szName,NULL))  
  103.         {  
  104.             printf("Set value error %d",GetLastError());  
  105.         }  
  106.     }   
  107.     return TRUE;  
  108. }