Windows环境变量编程设定

来源:互联网 发布:淘宝违规下架的宝贝怎么上架 编辑:程序博客网 时间:2024/05/21 21:45

        本文由浅入深的讲解环境变量的定义、使用。对Win98WinMeNTXPWin2003的不同系统下的应用进行了全面的分析。并以编程方式实现设置Windows环境变量。这对于一般程序编制和软件安装程序编制都有重要的意义。

什么是用户环境变量、什么是系统环境变量:

环境变量的定义(参考msdn):环境变量是一个string组成的array它是计算机的一系列设置(setting,环境变量用以指定文件的搜索路径、临时文件目录、特定应用程序(application-specific)的选项和其他类似信息。默认情况下,每个进程(process)的环境变量拷贝自父进程。当然父进程也能够为子进程指定不同的环境变量。

环境变量控制着多种程序的行为。例如,TEMP环境变量指定程序放置临时文件的位置。任何用户都可以添加、修改或删除用户的环境变量。但是,只有管理员才能添加、修改或删除系统环境变量。使用"控制面板"中的"系统"可以自定义下列变量:(1)用于登陆用户名(logged_on_user_name用户环境变量;对于特定计算机的每个用户来说,用户环境变量是不同的。变量包括由用户设置的任何内容,以及由应用程序定义的所有变量,例如应用程序文件的路径。(2系统环境变量;管理员可以更改或添加应用到系统(从而应用到系统中的所有用户)的环境变量。安装期间,Windows安装程序配置默认的系统变量,例如 Windows 文件的路径。

用户环境变量的作用、系统环境的作用:

举例往往是说明一个问题的最好办法,在Win2000下,我们观察"PATH"这个环境变量,

PATH= %SystemRoot%/system32。但是 "SystemRoot"又是一个环境变量, SystemRoot =d:/winnt,所以环境变量"TMP"的最终表征的路径为"d:/winnt/SYSTEM32".如我们手动编辑系统环境变量PATH。修改后PATH=%SystemRoot%/system32;C:/ Program Files。然后设计一个代码,实现浏览器打开目录"C:/Program Files"。这仅涉及一个简单的ShellExecute API

ShellExecute(NULL, "explore", "Internet Explorer",NULL, "c://Program Files", SW_SHOWNORMAL);

等价于

ShellExecute(NULL,"explore","Internet Explorer",NULL,"%path%",

SW_SHOWNORMAL);

但是后者有很大的灵活性,不修改代码只修改环境变量path的就能完成新的功能。这对于软件安装程序有着很好的意义。熟练的应用环境变量,有助于写出灵活、模块化的软件。

以上虽然以Win2000为例讲解,但同样适用于其他Windows系统,只是win98系列设置环境变量的方式不同,详情见下节:设定环境变量的算法。

设定环境变量的算法:

对于对Win98WinMeNTXPWin2003一揽子操作系统,可以分为两类:win98系列,NT系列。它们设定系统环境变量有着本质的不同。但对于设置当前进程的环境变量是一样的。

A关于系统环境变量

1win98系列设定系统环境变量的算法:

熟悉win98的都清楚,在C盘一般都有一个"AutoExec.bat"文件,系统启动都要执行它,所以这里是设定系统环境变量的地方,添加一个环境变量只是添加一行

SET PATH=C:/FOLDER1/FOLDER2类似的语句。如果添加一个路径,那么就是类似的语句

SET PATH=C:/FOLDER1/FOLDER2;D:/FOLDER3。系统要重新启动更改才能有效。

2NT系列的设定系统环境变量的算法:

首先分析手动编辑环境变量的原理,通过阅读MSDN文档,发现系统其实在注册表

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager/Environment

保存系统环境变量,当手动修改完毕时,选择"确定"按钮退出,向系统所有上级窗口发送WM_SETTINGCHANGE消息。系统不需要重新启动。

[插曲]:如何向系统所有上级窗口发送WM_SETTINGCHANGE消息?我仔细观看MSDN代码也没有给出一个例子。只能自己想办法,我编写了一个程序专门接受发送给它的WM_SETTINGCHANGE的消息,代码如下:

OnSettingChange(UINT uFlags, LPCTSTR lpszSection){….}

然后手动修改系统环境变量,这是程序接收到消息,分析uFlags, lpszSection两个参数,得知uFlags=0, lpszSection="Environment";

然后模仿该消息,向系统所有上级窗口发送WM_SETTINGCHANGE消息。

B关于当前的进程的环境变量

这个范围的环境变量很简单,进程执行时该变量有效,退出时就失效。所涉及的API就限于GetEnvironmentVariableSetEnvironmentVariableGetEnvironmentStringsSetEnvironmentStrings等。

 

 

原文地址:http://blog.csdn.net/ace1985/article/details/5706087

《Windows API巡礼》---GetEnvironmentStrings和GetEnvironmentVariable

环境变量是进程中一组变量信息,环境变量分为系统环境变量、用户环境变量和进程环境变量。系统有全局的环境变量,在进程创建时,进程继承了系统的全局环境变量、当前登录用户的用户环境变量和父进程的环境变量。进程也可以有自己的环境变量。

设置和获取所在进程的环境变量使用API函数GetEnvironmentStrings、GetEnvironmentVariable和SetEnvironmentVariable:

1)GetEnvironmentStrings函数用于获取所有环境变量字符串

LPTCH WINAPI GetEnvironmentStrings(void);

返回值:

成功时,返回指向保存环境变量的缓冲区;

失败时,返回值为NULL。

2)FreeEnvironmentStrings函数用来释放由GetEnvironmentStrings返回的内存块:

BOOL WINAPI FreeEnvironmentStrings(

__in LPTCH lpszEnvironmentBlock

);

返回值:

成功时,返回非零值;

失败时,返回零值,可调用GetLastError()查看进一步错误消息。

3)GetEnvironmentVariable函数用于获取指定的环境变量:

DWORD WINAPI GetEnvironmentVariable(

__in_opt LPCTSTR lpName,//环境变量名

__out_opt LPTSTR lpBuffer,//指向保存环境变量值的缓冲区

__in DWORD nSize//缓冲区大小(字符数)

);

返回值:

成功时,返回真实的环境变量值大小,不包括null结束符;

如果lpBuffer大小不足,则返回值是实际所需的字符数大小,lpBuffer内容未定义;

失败时,返回0;如果指定的环境变量找不到,GetLastError()返回ERROR_ENVVAR_NOT_FOUND。

4)SetEnvironmentVariable函数用于设置指定的环境变量:

BOOL WINAPI SetEnvironmentVariable(

__in LPCTSTR lpName,//环境变量名,当该值不存在且lpValue不为NULL时,将创建一个新的

__in_opt LPCTSTR lpValue//环境变量值

);

返回值:

成功时,返回非零值;

失败时,返回零值,调用GetLastError()查看具体的错误信息。

该函数对系统环境变量以及其他进程的环境变量不起作用!

 

 

实例一:调用GetEnvironmentStrings函数检索进程的环境变量内存块,并将其中内容打印到控制台:

#include<windows.h>

#include<tchar.h>

#include<stdio.h>

int _tmain()

{

LPTSTR lpszVariable;

LPTCH lpvEnv;

//获得环境变量内存块的指针

lpvEnv = GetEnvironmentStrings();

if(lpvEnv == NULL)

{

printf("GetEnvironmentStrins failed(%d)/n", GetLastError());

return 0;

}

//环境变量字符串是以NULL分隔的,内存块以NULL结尾

lpszVariable = (LPTSTR)lpvEnv;

while(*lpszVariable)

{

_tprintf(TEXT("%s/n"), lpszVariable);

lpszVariable += lstrlen(lpszVariable) + 1;//移动指针

}

FreeEnvironmentStrings(lpvEnv);

system("pause");

return 1;

}

实例二:默认情况下,子进程继承父进程环境变量内存块的一份拷贝;下面代码通过调用CreateProcess函数实现将一个环境变量块传递给子进程(asce.exe就是实例一编译链接得到的exe文件,因此,该代码的运行结果就是子进程打印从父进程继承而来的环境变量):

#include<Windows.h>

#include<tchar.h>

#include<stdio.h>

#include<strsafe.h>

#define BUFSIZE 4096

int _tmain()

{

TCHAR chNewEnv[BUFSIZE];

LPTSTR lpszCurrentVariable;

DWORD dwFlags = 0;

TCHAR szAppName[] = TEXT("asce.exe");

STARTUPINFO si;

PROCESS_INFORMATION pi;

BOOL fSuccess;

//将环境变量字符串拷贝到环境变量内存块中

lpszCurrentVariable = (LPTSTR)chNewEnv;

if(FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("AsceSetting=Luffy"))))

{

printf("String copy failed/n");

return FALSE;

}

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;

if(FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("AsceVersion=2.0"))))

{

printf("String copy failed/n");

return FALSE;

}

//使环境变量内存块以NULL结尾

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;

*lpszCurrentVariable = (TCHAR)0;

//创建子进程,指定一个新的环境变量内存块

SecureZeroMemory(&si,sizeof(STARTUPINFO));

si.cb =sizeof(STARTUPINFO);

#ifdef UNICODE

dwFlags = CREATE_UNICODE_ENVIRONMENT;

#endif

fSuccess = CreateProcess(szAppName, NULL, NULL, NULL,

TRUE, dwFlags, (LPVOID)chNewEnv,//新的环境变量内存块

NULL, &si, &pi);

if(!fSuccess)

{

printf("CreateProcess failed(%d)/n", GetLastError());

return FALSE;

}

WaitForSingleObject(pi.hProcess, INFINITE);

system("pause");

return TRUE;

}

 

实例三:在子进程创建过程中改变子进程的环境变量是一个进程改变另一个进程环境变量的唯一方式。一个进程绝不能直接改变另一个进程(非子进程)的环境变量。下面代码实现子进程继承符进程环境变量的方法:

#include<Windows.h>

#include<tchar.h>

#include<stdio.h>

#define BUFSIZE 4096

#define VARNAME TEXT("AsceVariable")

int _tmain()

{

DWORD dwRet, dwErr;

LPTSTR pszOldVal;

TCHAR szAppName[] = TEXT("asce.exe");

DWORD dwFlags = 0;

STARTUPINFO si;

PROCESS_INFORMATION pi;

BOOL fExist, fSuccess;

// Retrieves the current value of the variable if it exists.

// Sets the variable to a new value, creates a child process,

// then uses SetEnvironmentVariable to restore the original

// value or delete it if it did not exist previously.

pszOldVal = (LPTSTR)malloc(BUFSIZE*sizeof(TCHAR));

if(NULL == pszOldVal)

{

printf("Out of memory/n");

return FALSE;

}

dwRet = GetEnvironmentVariable(VARNAME, pszOldVal, BUFSIZE);

if(0 == dwRet)

{

dwErr = GetLastError();

if(ERROR_ENVVAR_NOT_FOUND == dwErr)

{

printf("Environment variable does not exist/n");

fExist = FALSE;

}

}

elseif(BUFSIZE < dwRet)

{

pszOldVal = (LPTSTR)realloc(pszOldVal, dwRet*sizeof(TCHAR));

if(NULL == pszOldVal)

{

printf("Out of memory/n");

return FALSE;

}

dwRet = GetEnvironmentVariable(VARNAME, pszOldVal, dwRet);

if(!dwRet)

{

printf("GetEnvironmentVariable failed(%d)/n", GetLastError());

return FALSE;

}

else

fExist = TRUE;

}

else

fExist = TRUE;

//Set a value for the child process to inherit

if(!SetEnvironmentVariable(VARNAME, TEXT("ASCE")))

{

printf("SetEnvironmentVariable failed(%d)/n", GetLastError());

return FALSE;

}

//Create a child process

SecureZeroMemory(&si,sizeof(STARTUPINFO));

si.cb =sizeof(STARTUPINFO);

#ifndef UNICODE

dwFlags = CREATE_UNICODE_ENVIRONMENT;

#endif

fSuccess = CreateProcess(szAppName, NULL, NULL, NULL,

TRUE, dwFlags, NULL,//inherit parent's environment

NULL, &si, &pi);

if(!fSuccess)

{

printf("CreateProcess failed(%d)/n", GetLastError());

}

WaitForSingleObject(pi.hProcess, INFINITE);

//Restore the original environment variable

if(fExist)

{

if(!SetEnvironmentVariable(VARNAME, pszOldVal))

{

printf("SetEnvironmentVariable failed(%d)/n", GetLastError());

return FALSE;

}

}

else

SetEnvironmentVariable(VARNAME, NULL);

free(pszOldVal);

system("pause");

return fSuccess;

}

原文出处:http://www.cnblogs.com/zuibunan/archive/2012/07/16/2592983.html