【问题标题】:Getting Enviroment Variable with cpp使用 cpp 获取环境变量
【发布时间】:2021-08-09 21:02:48
【问题描述】:

所以我一直在试图弄清楚如何找到一个环境变量并用 c++ 在屏幕上打印出来 但在过去的 3 个小时左右,我一直被卡住。当我打印出 currentDesktop 变量时,它只打印出“/Desktop”。但我正在寻找的是它前面的用户名。 我一直在阅读 Microsoft 论坛上有关 GetEnviromentVariable 函数的文档,这就是我迄今为止想出的。 非常感谢您的帮助,因为我还没有那么有经验,Thx。

#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#define BUFSIZE 4096
using namespace std;
int main()
{
    LPCWSTR Env = L"%USERPROFILE";
    LPTSTR pszOldVal;
    string IPADD;
     pszOldVal = (LPTSTR)malloc(BUFSIZE * sizeof(TCHAR));
    if (NULL == pszOldVal)
    {
        printf("Out of memory\n");
        return FALSE;
    }
    string currentDesktop = GetEnvironmentVariable(Env,pszOldVal,BUFSIZE) + "\\Desktop";
    cout << currentDesktop;
    return 0;

}

【问题讨论】:

  • std::getenv 的文档有一个易于理解的示例。
  • 如果你想要用户,为什么不使用%USERPROFILE%
  • @CPPNEWBIE 仔细阅读您的代码。它包含什么,而不是你认为它做了什么。
  • 啊哈,在将"\\Desktop" 添加到返回的结果之前,您忘记将GetEnvironmentVariable(Env,pszOldVal,BUFSIZE) 转换为std::stringGetEnvironmentVariable 返回 char*,而不是 std::string
  • @NathanOliver "GetEnvironmentVariable 返回 char*" - 不,它需要 char[] 并且返回 i> 一个DWORD,指定将多少个字符复制到char[]。你正在考虑(std::)getenv()

标签: winapi visual-c++ environment-variables


【解决方案1】:

您误用了GetEnvironmentVariable() 函数。一方面,您缺少变量名称L"%USERPROFILE" 上的尾随%。另一方面,返回值是复制到提供的缓冲区中的字符数。您正在将该整数添加到字符串文字 "\\Desktop",这不是您想要的。

试试这个:

#include <iostream>
#include <string>
#include <windows.h>

std::wstring GetEnv(const std::wstring &varName)
{
    std::wstring str;
    DWORD len = GetEnvironmentVariableW(varName.c_str(), NULL, 0);
    if (len > 0)
    {
        str.resize(len);
        str.resize(GetEnvironmentVariableW(varName.c_str(), &str[0], len));
    }
    return str;
}

std::wstring GetUserDesktopPath()
{
    std::wstring path = GetEnv(L"%USERPROFILE%");
    if (!path.empty()) path += L"\\Desktop";
    return path;
}

int main()
{
    std::wstring currentDesktop = GetUserDesktopPath();
    std::wcout << currentDesktop;
    return 0;
}

话虽如此,如果您只想要用户名,请使用%USERNAME% 而不是%USERPROFILE%。或者更好的是,使用GetUserName() 而不是GetEnvironmentVariable()

#include <iostream>
#include <string>
#include <windows.h>

std::wstring GetUserName()
{
    std::wstring str;
    DWORD len = 0;
    if (!GetUserNameW(NULL, &len))
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
            str.resize(len);
            if (GetUserNameW(&str[0], &len))
                str.resize(len-1);
            else
                str = L"";
        }
    }
    return str;
}

int main()
{
    std::wstring currentUser = GetUserName();
    std::wcout << currentUser;
    return 0;
}

但是,正确获取用户桌面路径的方法是向 Windows 询问该特定路径,不要假设它位于用户的配置文件,或者命名为Desktop。对该查询使用SHGetFolderPath()SHGetKnownFolderPath(),例如:

#include <iostream>
#include <string>
#include <windows.h>
#include <shlobj.h>

std::wstring GetFolderPath(CSIDL folderID)
{
    WCHAR path[MAX_PATH] = {};
    SHGetFolderPathW(NULL, folderID, NULL, SHGFP_TYPE_CURRENT, path);
    return path;
}
/* or:
std::wstring GetFolderPath(REFKNOWNFOLDERID folderID)
{
    std::wstring str;
    PWSTR path = NULL;
    if (SHGetKnownFolderPath(folderID, 0, NULL, &path) == S_OK)
        str = path;
    CoTaskMemFree(path);
    return str;
}
*/

std::wstring GetUserDesktopPath()
{
    return GetFolderPath(CSIDL_DESKTOPDIRECTORY);
    // or: return GetFolderPath(FOLDERID_Desktop);
}

int main()
{
    std::wstring currentDesktop = GetUserDesktopPath();
    std::wcout << currentDesktop;
    return 0;
}

【讨论】:

  • 在测试 Shlobj 标头时,我遇到了一些错误。特别是在使用 GetFolderPath(CSIDL_DESKTOP, FOLDERID_Desktop) 时。错误说“没有构造函数的实例”。这是什么意思?
  • @CPPNEWBIE 请逐字提供确切错误消息,并指出错误所指的代码行。
  • 链接规范与之前的“SHGetKnownFolderPath”不兼容(在“C:/blah/blah/blaH/shlobj_core.h”的第1046行声明
  • 我尝试改用 SHGETKNOWNFOLDERPATH()。得到了这个错误,这超出了我的范围,我不知道我现在在做什么。
  • @CPPNEWBIE 好吧,现在您引用了一个完全不同的错误。你第一次提到的构造函数错误发生了什么?你让这很难帮助你。
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 2013-07-01
  • 2012-04-16
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
相关资源
最近更新 更多