如何尽可能干净地使用 VS C++ GetEnvironmentVariable?

2024-01-23

(这与其说是一个问题,不如说是一种迂腐的做法,所以就这样吧。)

我已经制作了一个很好的小程序,它是我的 Linux 操作系统本机的,但我认为它也足够有用,可以存在于我的 Windows 机器上。因此,我想访问Windows的环境变量,MSDN引用了这样的例子:

const DWORD buff_size = 50;
LPTSTR buff = new TCHAR[buff_size];

const DWORD var_size = GetEnvironmentVariable("HOME",buff,buff_size);

if (var_size==0) { /* fine, some failure or no HOME */ }
else if (var_size>buff_size) {

    // OK, so 50 isn't big enough.
    if (buff) delete [] buff;
    buff = new TCHAR[var_size];
    
    const DWORD new_size = GetEnvironmentVariable("HOME",buff,var_size);

    if (new_size==0 || new_size>var_size) { /* *Sigh* */ }
    else { /* great, we're done */ }
}
else { /* in one go! */ }

(对我来说)这并不像使用 getenv 并仅检查空指针那么好。我也不想动态分配内存,因为我只是想让程序在 Windows 和我的 Linux 操作系统上运行,这意味着这个 MS 代码必须与 nix 代码很好地配合。进一步来说:

template <class T> // let the compiler sort out between char* and TCHAR*
inline bool get_home(T& val) { // return true if OK, false otherwise
#if defined (__linux) || (__unix)
    val = getenv("HOME");
    if (val) return true;
    else return false;
#elif defined (WINDOWS) || defined (_WIN32) || defined (WIN32)
    // something like the MS Code above
#else
    // probably I'll just return false here.
#endif
}

所以,我必须在堆上普遍分配或者做一个#ifdef在调用函数中释放内存。不太漂亮。

当然,我可以首先在堆栈上分配“buff”,但随后我必须创建一个新的TCHAR[]如果我第一次调用 GetEnvironmentVariable 时“buff_size”不够大。更好,但是如果我是一个学究并且不想到处创建多余的数组怎么办?关于更美观的东西有什么想法吗?

我知识不多,所以有人会嫉妒我故意强迫 GetEnvironmentVariable 失败以获得字符串大小吗?有没有人看到以下问题:

const DWORD buff_size = GetEnvironmentVariable("HOME",0,0);
TCHAR buff[buff_size];
const DWORD ret = GetEnvironmentVariable("HOME",buff,buff_size);
// ...

还有其他想法或建议吗? (或者纠正明显的错误?)

更新: 下面有很多有用的信息。我认为我想做的最好的选择是使用static char[] like:

inline const char* get_home(void) { // inline not required, but what the hell.
#if defined (__linux) || (__unix)
    return getenv("HOME");
#elif defined (WINDOWS) || defined (WIN32) || defined (_WIN32)
    static char buff[MAX_PATH];
    const DWORD ret = GetEnvironmentVariableA("USERPROFILE",buff,MAX_PATH);
    if (ret==0 || ret>MAX_PATH)
        return 0;
    else
        return buff;
 #else
        return 0;
 #endif
 }

也许这不是最优雅的方法,但它可能是在 *nix 和 Windows 之间同步我想要做的事情的最简单方法。 (稍后我还会担心 Unicode 支持。)

感谢所有提供过帮助的人。


DWORD bufferSize = 65535; //Limit according to http://msdn.microsoft.com/en-us/library/ms683188.aspx
std::wstring buff;
buff.resize(bufferSize);
bufferSize = GetEnvironmentVariableW(L"Name", &buff[0], bufferSize);
if (!bufferSize)
    //error
buff.resize(bufferSize);

当然,如果你想要ASCII,替换wstring with string and GetEnvironmentVariableW with GetEnvironmentVariableA.

编辑:您还可以创建getenv你自己。这有效是因为

相同的内存位置可能会在后续调用 getenv 时使用,从而覆盖之前的内容。

const char * WinGetEnv(const char * name)
{
    const DWORD buffSize = 65535;
    static char buffer[buffSize];
    if (GetEnvironmentVariableA(name, buffer, buffSize))
    {
        return buffer;
    }
    else
    {
        return 0;
    }
}

当然,如果您想维护 unicode 支持,那么使用所有这些的宽字符版本可能是个好主意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何尽可能干净地使用 VS C++ GetEnvironmentVariable? 的相关文章

随机推荐

  • 主线程上的 Okhttp 响应回调

    我创建了一个帮助程序类来处理我的应用程序中的所有 http 调用 它是 okhttp 的一个简单的单例包装器 如下所示 我省略了一些不重要的部分 public class HttpUtil private OkHttpClient clie
  • 在RelativeLayout中获取子视图

    我想在我的活动中添加一个按钮 该按钮将返回相对布局的所有子视图 如何获取相对布局视图的所有子视图 RelativeLayout延伸ViewGroup其中有getChildCount and getChildAt int index 方法 所
  • 使用命令行编译 C++ 代码

    我使用下面的命令来编译我的 C 代码 它使用 OpenCV 库 我的命令就像 opencv main cpp o binary name 其中 opencv 是一个别名命令 例如 alias opencv g pkg config cfla
  • 使用 YoutubeURL 获取 oembed 返回 403 Forbidden

    这几天 我突然收到来自 403 Forbidden 的回复https www youtube com oembed url youtubeURl 我检查了Youtube API的文档 但我找不到它对oembed有限制并且也有授权 我只能看到
  • 在 bash 中将 HH:MM:SS.mm 转换为秒

    我正在运行一些 gnu 时间脚本 它们会生成以下形式的输出 mm ss mm 分 秒和毫秒 例如 1 20 66 或 hh MM ss 小时 分钟和秒 例如 1 43 38 我想将其转换为秒 以便比较它们并将它们绘制在图形中 使用 bash
  • Silverlight:如何在代码后面更改AxisLabelStyle?

    在 xaml 文件中 我们可以通过执行以下操作来更改 AxisLabelStyle
  • Java Servlet API 向后兼容吗?

    我想编写一个使用 javax servlet API 的 JAR 文件 如果我针对 2 2 版本编写 是否意味着它可以在 2 3 2 4 和 2 5 版本上工作 Thanks 是的 它们是向后兼容的 甲骨文来源 http docs orac
  • 面向对象设计实践问题[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 过去几年我几乎只开发 C 代码 我目前正在寻求提高我的面向对象设计技能 任何人都可以推荐任何包含一系列简
  • 如何在 Kerberos 中“取消模拟”(取消委托?)

    我有一个使用 Kerberos 的 Web 应用程序来使用 ASP NET 3 5 和 IIS 访问外部资源 当用户连接到应用程序时 Kerberos 身份验证会自动允许我使用委派作为用户连接到外部资源 这并不容易做到 这很好 但我有一个问
  • .net 正则表达式用于超过 2 个连续字母

    我正在尝试为 2 个以上的连续字母编写 Net 正则表达式 aa fine Aa fine aaa not allowed Aaa not allowed 我是正则表达式的新手 但这是我到目前为止所拼凑的 if Regex IsMatch
  • uwp命令栏始终显示标签

    Answer 谢谢贾斯汀XL https stackoverflow com users 231837 justin xl我能够解决我的问题 我实现了他在下面的回答中提供的样式 并按照他的说法在 App xaml 中添加了这一点 我将高度更
  • 在 Android 上点击后退按钮时关闭应用程序

    所以我的登录活动是您看到的第一个屏幕 当您点击后退按钮时 它会退出应用程序 很好 所以我再次打开应用程序 登录后 我现在处于我的主要活动中 我该如何做到这一点 以便当我现在点击后退按钮时 它会退出应用程序而不是返回到登录活动 当您推送新活动
  • git分支、fork、fetch、merge、rebase和clone之间有什么区别?

    我想了解 Git 中分支 分叉和克隆之间的区别 同样 当我做一个时 这意味着什么git fetch与git pull 另外 什么是rebase与 相比 意味着merge 我怎样才能将个人的承诺压缩在一起 它们如何使用 为什么使用以及它们代表
  • 从另一个对象向 stdClass 对象添加属性

    我希望能够执行以下操作 obj new stdClass obj gt status success obj2 new stdClass obj2 gt message OK 如何扩展 obj 使其包含 obj2 的属性 例如 obj gt
  • 错误:未定义配置属性“mongoURI”

    我尝试启动一个项目 但是当我尝试将 mongo 连接到服务器时 我遇到一个错误 显示连接不起作用 因为它找不到连接字符串所在的文件夹 我的数据库文件 const mongoose require mongoose const config
  • Roslyn 实际上允许您操作 CSharp 项目的 TreatWarningsAsErrors 吗?

    我正在尝试检索设置 TreatWarningsAsErrors 但无法为我加载的解决方案的项目找到它 我想要完成的是从项目文件中获取设置 并将其设置为true 如果还没有的话 接下来 我想让 Roslyn 使用新设置进行编译 这样我就可以检
  • 替换 html 标签中没有的所有引号

    目前我正在用特殊引号替换文本中的所有引号 但是我如何更改我的正则表达式 只替换文本中的引号 而不替换 html 标记中使用的引号 text preg replace w raquo text text preg replace lt w l
  • 使用 Swift 3 和 Alamofire 4 获取客户端证书以进行相互身份验证

    我试图弄清楚如何使用 Alamofire 4 0 和 Swift 3 0 将 p12 如果需要 我也有 PEM 证书和密钥 发送到网站进行身份验证 我看到的所有示例都是针对 Swift 2 0 的 并不完全是我想要的 在我的 mac 上的
  • 录制 mp3 而不是 caf 文件

    我正在看这个例子 https developer apple com library ios samplecode SpeakHere Introduction Intro html https developer apple com li
  • 如何尽可能干净地使用 VS C++ GetEnvironmentVariable?

    这与其说是一个问题 不如说是一种迂腐的做法 所以就这样吧 我已经制作了一个很好的小程序 它是我的 Linux 操作系统本机的 但我认为它也足够有用 可以存在于我的 Windows 机器上 因此 我想访问Windows的环境变量 MSDN引用