GetEnvironmentVariableA() usage

GetEnvironmentVariableA() usage

本文关键字:usage GetEnvironmentVariableA      更新时间:2023-10-16

我正在Windows 7上的Visual Studio 2012中的c++控制台应用程序上工作,我想从应用程序内获得一些环境变量的值。
以下是我到目前为止尝试过的-:

int main()
{
    char a[1000];
    int s=GetEnvironmentVariableA("HOME",a,1000);
}  

但是,我得到s的值为0,表示变量"HOME"不存在。
同样,getenv("HOME")也返回NULL
那么,正确的步骤是什么呢?

这个程序最有可能告诉您的是,您的进程环境不包含一个名为HOME的变量。注意,HOME不是一个您希望定义的变量,除非您已经采取了定义它的步骤。要么将其添加到系统环境中,要么在创建流程时指定一个定制的环境。

文档对返回值作了如下说明:

如果函数成功,返回值是字符数存储在lpBuffer所指向的缓冲区中,不包括终止空字符。

如果lpBuffer不够大,则返回值为保存字符串及其对应的对象所需的缓冲区大小,以字符为单位终止null字符和lpBuffer的内容是未定义的。

如果函数失败,返回值为零。如果指定在环境块中找不到环境变量,GetLastError返回ERROR_ENVVAR_NOT_FOUND.

因此,如果函数返回0,则按照文档说明执行。调用GetLastError找出函数调用失败的原因。

但是,正如我所说的,概率非常接近1,原因很简单,您的进程环境没有定义一个名为HOME的变量。

至于你如何前进,最有可能的是你正在寻找用户的个人资料中的位置。具体如何做到这一点取决于您希望在配置文件中存储/加载文件的位置。与CSIDL或已知文件夹id相关的api之一将满足您的需求。

关于你的问题,

那么,正确的操作步骤是什么呢?

Windows没有一个HOME标准变量。相反,在过去,有HOMEDRIVEHOMEPATH,显然是因为他们不知道,在Windows 95的Windows资源管理器中,有一个新的变量叫做USERPROFILE

<>之前用户(C: alfps_000]比;设置家HOMEDRIVE = C:HOMEPATH = alfps_000用户用户(C: alfps_000]比;设置用户列出了= FRIKADELLUSERDOMAIN_ROAMINGPROFILE = FRIKADELL用户名= alfps_000USERPROFILE = C: alfps_000用户用户(C: alfps_000]比;_之前

愚蠢的三个oh后缀(好像我比两个oh七更好)正是Windows 8.1认为适合给我的。要说服Windows做出合理的选择,工作量太大了。不仅是用户名,还有环境变量。

这是你的程序重写,使用Windows变量,模糊地对应于Unix-land HOME,即USERPROFILE:

#include <iostream>
#include <stdlib.h>     // getenv
using namespace std;
auto main() -> int
{
    cout
        << "User's profile directory: "
        << "[" << getenv( "USERPROFILE" ) << "]"
        << endl;
}

Windows环境变量是尴尬的,不保证,但仍然可用在脚本和非常简单的程序,如上面的一个。在更严肃的c++代码中,您可以使用SHGetKnownFolderPath API函数。在Visual c++中,它看起来像这样:

#undef UNICODE
#define UNICODE
#include <windows.h>
#include <shlobj.h>     // SHGetKnownFolderPath
#include <objbase.h>    // CoTaskMemFree
#include <iostream>     // std::wcout
#include <memory>       // std::unique_ptr
#include <stdexcept>    // std::runtime_error, std::exception
#include <stdlib.h>     // EXIT_FALURE, EXIT_SUCCESS
using namespace std;
void cotaskmem_free( wchar_t* p ) { CoTaskMemFree( p ); }
auto main() -> int
{
    using X = runtime_error;
    using String_deallocation = unique_ptr<wchar_t[], void(*)(wchar_t*)>;
    try
    {
        wchar_t* path;
        HRESULT const hr = SHGetKnownFolderPath(
            FOLDERID_Profile,       // REFKNOWNFOLDERID rfid -> %USERPROFILE%
            0,                      // DWORD dwFlags,
            0,                      // HANDLE hToken,
            &path                   // PWSTR *ppszPath
        );
        if( FAILED( hr ) ) { throw X( "SHGetKnownFolderPath failed" ); }
        String_deallocation const path_cleanup( path, cotaskmem_free );
        wcout << "User profile directory: [" << path << "]" << endl;
        return EXIT_SUCCESS;
    }
    catch( exception const& x )
    {
        wcerr << "!" << x.what() << endl;
    }
    return EXIT_FAILURE;
}

g++ (per version 4.8.2)还不支持Windows Vista及以后的API函数,至少一般不支持,所以如果你需要支持g++,请使用一些旧的函数。

注意:

无论您打算访问或放置在%HOME%中,最好是访问或放置在其他特殊用户目录中,也可以通过SHGetKnownFolderPath访问