GetEnvironmentVariableA() usage
GetEnvironmentVariableA() usage
我正在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
标准变量。相反,在过去,有HOMEDRIVE
和HOMEPATH
,显然是因为他们不知道,在Windows 95的Windows资源管理器中,有一个新的变量叫做USERPROFILE
。
愚蠢的三个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
访问
- C++ Usage of AsyncCallback
- std::visit and std::variant usage
- QLoggingCategory::setFilterRules usage
- C++ std::initializer_list usage
- Direct3D typedef usage
- Windows SetupAPI DIF_REMOVE usage
- C++ unique_ptr() Usage
- c++14 static constexpr auto with odr usage
- The usage of snprintf
- pcre2 UTF32 usage
- Qt QProccess with ping utility usage
- Usage of InternetGetConnectedStateEx
- Usage of QOpenGLVertexArrayObject
- QtGstreamer camerabin2 usage
- pcl::PCLPointCloud2 usage
- Zlib usage - deflateEnd() error
- OpenCV C++ usage of cv::Moments
- libGL heap usage
- 为什么"find usage"不适用于不同子项目中的信号
- Qt connect() usage