簡體   English   中英

使用C ++在Windows中更新PATH環境變量

[英]Updating the PATH environment variable in Windows using C++

我正在嘗試從我當前的流程啟動一個新流程。 我正在使用CreateProcess()來啟動它。 問題是我需要在PATH中擁有某些目錄才能成功完成。 這是我當前的實現,但它不起作用。 我究竟做錯了什么?

// Environment variables
char *env = new char[2048];
char *ptr = env;

char temp[MAX_PATH] = "PATH=";
strcpy(ptr, strcat(temp, plugin_path));
ptr += strlen(ptr) + 1;

char  temp2[MAX_PATH] = "PATH=";
strcpy(ptr, strcat(temp, lib_path));
ptr += strlen(ptr) + 1;
*ptr = '\0';

 // Execute
STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

// error checking required
if(!CreateProcess(
    NULL,             // application name
    command_path,   // app.exe
    NULL,
    NULL,
    TRUE,
    0,
    env,           // environment
    NULL,
    &si,
    &pi)) {
    std::cout << GetLastError();
    return 1;
}

WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
std::cout << "Process Started!";

如果需要其他任何東西,請告訴我。

編輯:有人在下面提到我需要更具體一點。 它在環境變量未被傳遞的意義上不起作用。 它失敗,因為庫路徑不在PATH中。 但是createProcess確實會啟動它。

EDIT2:這是更新的代碼。 同樣的問題。 此外,CreateProcess拋出錯誤1087,這似乎不存在於文檔中。

// Environment variables
char env[2048];
char *ptr = env;
char *path_path = getenv("PATH");

// copy original path
memcpy(ptr, path_path, strlen(path_path));
ptr += strlen(ptr) + 1;
memcpy(ptr, ";", 1);
ptr++;

// copy plugin path
memcpy(ptr, plugin_path, strlen(plugin_path));
ptr += strlen(plugin_path) + 1;
memcpy(ptr, ";", 1);
ptr++;

// copy libpath
memcpy(ptr, lib_path, strlen(lib_path));
ptr += strlen(lib_path) + 1;
memcpy(ptr, ";", 1);
ptr++;

// double null terminated
memcpy(ptr, "\0\0", 2);

std::cout << "ENV : " << env << std::endl;

// error checking required
if(!CreateProcess(
    NULL,             // application name
    command_path,   // app.exe
    NULL,
    NULL,
    TRUE,
    0,
    env,           // environment
    NULL,
    &si,
    &pi)) {
    std::cout << GetLastError();
    return 1;
}

WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
std::cout << "Process Started!";

PATH變量是單個變量。 該變量中列出了不同的目錄,以分號分隔。 但是你試圖兩次定義變量。 那是錯誤的。

代碼應該是這樣的(假設你想擴展現有的路徑):

char *env = new char[2048]; // fingers crossed this is enough
strcpy(env, "PATH=");
strcat(env, getenv("PATH"));
strcat(env, ";");
strcat(env, plugin_path);
strcat(env, ";");
strcat(env, lib_path);
env[strlen(env)+1] = '\0';

雖然這個代碼(就像你的問題一樣)只是要求緩沖區溢出。

如果使用C ++工具來構建字符串會更容易。 例如:

std::stringstream ss;
ss << "PATH=" << getenv("PATH");
ss << ";" << plugin_path;
ss << ";" << lib_path;
ss << '\0';
std::string env = ss.str();

然后將env.c_str()傳遞給CreateProcess

這不僅使代碼更易於閱讀和驗證,而且您知道不會超出任何緩沖區。

我還注意到您傳遞的環境中只定義了一個變量,即PATH 如果從調用進程的環境開始,將額外的目錄添加到PATH ,然后將其作為新進程的環境傳遞,則可能會更好。

#include <iostream>
#include <windows.h>
#include <cstring>
#include "tchar.h"


void SetUserVariablePath(){
    HKEY hkey;
    long regOpenResult;
    const char key_name[] = "Environment";
    const char path[]="D:/custom_command";                                               //new_value path need to update 
    regOpenResult = RegOpenKeyEx(HKEY_CURRENT_USER,key_name, 0, KEY_ALL_ACCESS, &hkey);
    LPCSTR stuff = "VVS_LOGGING_PATH";                                                   //Variable Name 
    RegSetValueEx(hkey,stuff,0,REG_SZ,(BYTE*) path, strlen(path));
    RegCloseKey(hkey);
}



void GetUserVariablePath(){
    static const char path[] = "VVS_LOGGING_PATH" ;                                      //Variable Name 
    static BYTE buffer1[1000000] ;
    DWORD buffsz1 = sizeof(buffer1) ;
    {
        //HKEY_CURRENT_USER\Environment
        const char key_name[] = "Environment";
        HKEY key ;

        if( RegOpenKeyExA( HKEY_CURRENT_USER, key_name, 0, KEY_QUERY_VALUE, std::addressof(key) ) == 0 &&
            RegQueryValueExA( key, path, nullptr, nullptr, buffer1, std::addressof(buffsz1) ) == 0 )
        {
            std::cout << "The updated value of the user variable is :  " << reinterpret_cast<const char*>(buffer1) << '\n' ;
        }
    }
}

int main()
{   
    SetUserVariablePath();
    GetUserVariablePath();
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM