修改环境变量(GetEnvironmentVariable、SetEnvironmentVariable、GetEnvironmentStrings)

本文介绍了如何在Windows环境下管理和操作进程的环境变量,包括创建新的环境块、更改子进程环境变量的方法及示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



Each process has an environment block associated with it. The environment block consists of a null-terminated block of null-terminated strings (meaning there are two null bytes at the end of the block), where each string is in the form:

name=value

All strings in the environment block must be sorted alphabetically by name. The sort is case-insensitive, Unicode order, without regard to locale. Because the equal sign is a separator, it must not be used in the name of an environment variable.

Example 1

By default, a child process inherits a copy of the environment block of the parent process. The following example demonstrates how to create a new environment block to pass to a child process using CreateProcess.

This example uses the code in example three as the child process, Ex3.exe.

C++
#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("ex3.exe");
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    BOOL fSuccess; 
 
    // Copy environment strings into an environment block. 
 
    lpszCurrentVariable = (LPTSTR) chNewEnv;
    if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MySetting=A"))))
    {
        printf("String copy failed\n"); 
        return FALSE;
    }

    lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1; 
    if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MyVersion=2")))) 
    {
        printf("String copy failed\n"); 
        return FALSE;
    }
 
    // Terminate the block with a NULL byte. 
 
    lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1; 
    *lpszCurrentVariable = (TCHAR)0; 

    // Create the child process, specifying a new environment block. 
 
    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,   // new environment block
        NULL, &si, &pi); 
 
    if (! fSuccess) 
    {
        printf("CreateProcess failed (%d)\n", GetLastError());
        return FALSE;
    }
    WaitForSingleObject(pi.hProcess, INFINITE);
    return TRUE;
}


Example 2

Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process.

If you want the child process to inherit most of the parent's environment with only a few changes, retrieve the current values using GetEnvironmentVariable, save these values, create an updated block for the child process to inherit, create the child process, and then restore the saved values using SetEnvironmentVariable, as shown in the following example.

This example uses the code in example three as the child process, Ex3.exe.

C++
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUFSIZE 4096
#define VARNAME TEXT("MyVariable")

int _tmain()
{
    DWORD dwRet, dwErr;
    LPTSTR pszOldVal; 
    TCHAR szAppName[]=TEXT("ex3.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;
        }
    }
    else if(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("Test"))) 
    {
        printf("SetEnvironmentVariable failed (%d)\n", GetLastError()); 
        return FALSE;
    }
 
    // Create a child process. 

    SecureZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
 
#ifdef 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);
    
    return fSuccess;
}


Example 3

The following example retrieves the process's environment block using GetEnvironmentStrings and prints the contents to the console.

C++
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int _tmain()
{
    LPTSTR lpszVariable; 
    LPTCH lpvEnv; 
 
    // Get a pointer to the environment block. 
 
    lpvEnv = GetEnvironmentStrings();

    // If the returned pointer is NULL, exit.
    if (lpvEnv == NULL)
    {
        printf("GetEnvironmentStrings failed (%d)\n", GetLastError()); 
        return 0;
    }
 
    // Variable strings are separated by NULL byte, and the block is 
    // terminated by a NULL byte. 

    lpszVariable = (LPTSTR) lpvEnv;

    while (*lpszVariable)
    {
        _tprintf(TEXT("%s\n"), lpszVariable);
        lpszVariable += lstrlen(lpszVariable) + 1;
    }
    FreeEnvironmentStrings(lpvEnv);
    return 1;
}
<think>我们正在使用ECUTest进行测试用例编写,用户希望了解如何通过SetEnvironmentVariable函数设置环境变量,以实现全局变量的传递和影响。根据之前的回答,我们知道在ECUTest中,环境变量具有全局作用域,可以在所有Package中访问。 引用[1]提到在shell中,局部变量可以使用local命令定义,而环境变量则是全局的。引用[2]和[3]则说明了在Windows中设置全局环境变量的方法和原理。引用[4]则是一个环境变量未设置导致的错误示例。 因此,在ECUTest中,我们可以使用SetEnvironmentVariable函数来设置环境变量,这样设置的变量将在整个测试会话中全局可用,包括所有子Package。 具体步骤如下: 1. 在主Package(或任何需要设置全局变量的地方)使用SetEnvironmentVariable函数设置环境变量。 2. 在其他Package中,使用GetEnvironmentVariable函数来获取环境变量的值。 注意:环境变量在ECUTest中是字符串类型,如果需要传递其他类型(如整数、浮点数、布尔值等),需要自行进行类型转换。 示例代码: 在主Package中设置环境变量: ```python # 在主Package的某个测试步骤中 # 设置一个名为"GLOBAL_TIMEOUT"的环境变量,值为字符串"5000" SetEnvironmentVariable("GLOBAL_TIMEOUT", "5000") # 设置一个名为"GLOBAL_TEST_MODE"的环境变量,值为"DEBUG" SetEnvironmentVariable("GLOBAL_TEST_MODE", "DEBUG") ``` 在子Package中获取环境变量: ```python # 在子Package的测试步骤中 # 获取环境变量,并转换为整数 timeout_str = GetEnvironmentVariable("GLOBAL_TIMEOUT") if timeout_str is not None: timeout = int(timeout_str) # 转换为整数 else: timeout = 1000 # 默认值 # 获取另一个环境变量 test_mode = GetEnvironmentVariable("GLOBAL_TEST_MODE") if test_mode is None: test_mode = "RELEASE" # 默认值 ``` 另外,我们可以在主Package的OnStart事件处理函数中初始化全局环境变量,这样在测试开始前就已经设置好: ```python def OnStart(): # 初始化全局环境变量 SetEnvironmentVariable("GLOBAL_TIMEOUT", "5000") SetEnvironmentVariable("GLOBAL_TEST_MODE", "DEBUG") ``` 注意事项: 1. 环境变量名最好使用统一的前缀(如"GLOBAL_")以避免命名冲突。 2. 由于环境变量是全局的,所以在多个Package中修改同一个环境变量时需要注意同步问题(尤其是在并行测试时)。如果存在并发修改,建议使用锁机制(如LockResource和UnlockResource)来保护。 3. 环境变量在ECUTest测试会话结束后不会持久化(除非你显式地写入系统环境变量,但通常不推荐这样做,因为ECUTest的环境变量是进程内的)。 关于引用[3]提到的修改Windows系统环境变量并广播消息的方法,在ECUTest中通常不需要,因为ECUTest的SetEnvironmentVariable函数设置的是进程内的环境变量,不会影响系统环境变量。因此,我们只需使用ECUTest提供的API即可。 因此,总结如下: 使用SetEnvironmentVariableGetEnvironmentVariable函数可以方便地在ECUTest的不同Package之间传递全局变量。 下面,我们按照要求生成相关问题。</think>在ECUTest中使用`SetEnvironmentVariable`函数实现全局变量传递,可按照以下步骤操作: ### 一、函数基本用法 ```python # 设置环境变量 SetEnvironmentVariable("变量名", "值") # [^2] # 获取环境变量 value = GetEnvironmentVariable("变量名") # [^1] ``` ### 二、实现全局传递的步骤 1. **主Package初始化**(在`OnStart`事件中) ```python def OnStart(): # 设置全局配置 SetEnvironmentVariable("GLOBAL_TIMEOUT", "5000") # 超时时间(ms) SetEnvironmentVariable("TEST_MODE", "DEBUG") # 测试模式 SetEnvironmentVariable("RETRY_COUNT", "3") # 重试次数 ``` 2. **子Package调用**(任意测试步骤中) ```python # 获取全局变量并转换类型 timeout = int(GetEnvironmentVariable("GLOBAL_TIMEOUT")) mode = GetEnvironmentVariable("TEST_MODE") # 根据全局变量控制测试逻辑 if mode == "DEBUG": LogMessage("调试模式启用") SetTimeout(timeout * 2) # 调试模式延长超时 ``` ### 三、跨Package修改全局值 ```python # 子Package中更新全局变量 current_retry = int(GetEnvironmentVariable("RETRY_COUNT")) SetEnvironmentVariable("RETRY_COUNT", str(current_retry + 1)) ``` ### 四、最佳实践 1. **命名规范** 使用统一前缀(如`GLOBAL_`)避免命名冲突: ```python SetEnvironmentVariable("GLOBAL_API_ENDPOINT", "https://api.example.com") ``` 2. **类型安全处理** ```python try: timeout = int(GetEnvironmentVariable("GLOBAL_TIMEOUT")) except: timeout = 1000 # 默认值 LogWarning("全局超时变量无效,使用默认值") ``` 3. **作用域验证** ```python if VariableExists("GLOBAL_TIMEOUT"): # [^1] # 变量存在时才操作 ``` ### 五、注意事项 1. **变量类型** 环境变量始终存储为字符串,需自行转换类型(如`int()`, `float()`)[^1] 2. **生命周期** 环境变量在测试会话期间持续有效,重启ECUTest后失效 3. **并发安全** 多线程修改时需加锁: ```python LockResource("ENV_LOCK") # 修改环境变量操作 UnlockResource("ENV_LOCK") ``` > **实际应用示例**: > 当多个Package需要共享API端点时,主Package设置`GLOBAL_API_ENDPOINT`后,所有子Package通过`GetEnvironmentVariable`获取统一配置,修改时自动全局生效[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值