呵呵呵呵呵

萝莉有三好,柔体 轻音 易推倒。女神有三宝,干嘛 呵呵 去洗澡。宅男有三好:Dota 基友 破电脑。


windows 父进程 子进程 环境变量概念及示例程序源码

windows 父进程 子进程 环境变量概念及示例程序源码

环境变量有以下几种:系统环境变量、用户环境变量和进程环境变量(父进程的环境变量,进程自己的环境变量)

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

默认情况下,子进程继承父进程环境变量内存块的一份拷贝。

在子进程创建过程中改变子进程的环境变量是一个进程改变另一个进程环境变量的唯一方式。一个进程绝不能直接改变另一个进程(非子进程)的环境变量。

环境变量常用函数介绍:

设置和获取所在进程的环境变量使用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; 
        }   
    }

    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("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 parents 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;
}

 

更多内容:

CGI环境变量列表及示例
Windows 10如何关闭自动更新
win 10 任务管理器 显示句柄
BCB 使用CreateProcess同步执行其他程序
强大的命令行WMIC示例

本文链接地址:http://www.hehehehehe.cn/i/708.html