跨语言共享环境变量
Posted
技术标签:
【中文标题】跨语言共享环境变量【英文标题】:Sharing environment variables across languages 【发布时间】:2020-02-26 17:14:01 【问题描述】:我正在编写一个由使用不同语言(即 Java、C#、C++)编写的多个模块组成的应用程序。 我遇到了一种奇怪的行为,我在一个模块(例如 C#)中设置的环境变量没有传播到其他模块。 据我了解,问题是由于 Windows 中的环境变量是通过运行时库中的 _environ 结构访问的,而不是通过进程描述符,因此使用不同运行时的库具有不同的环境变量。
特别是对于 C#,这个问题似乎只有在我在 Release 中编译和运行代码时才会出现,而在 Debug 中编译代码就可以了。
下面的代码使用 C# 和 C++ 编写的两个非常简单的模块重现了该问题。我用 VS2015 Professional 编译了代码。 C# 代码使用 runtime v4.0 和 .NET framework v4.5.2 编译
C# 可执行文件
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
class Program
[DllImport("cpp_lib.dll", CharSet = CharSet.Unicode)]
public static extern void print_path();
static void Main(string[] args)
var path = Environment.GetEnvironmentVariable("PATH");
path += ";D:\\Temp";
Environment.SetEnvironmentVariable("PATH", path);
// Print the path from C#
Console.WriteLine("Path from C#: " + Environment.GetEnvironmentVariable("PATH"));
// Print the path from c++
print_path();
C++ 库
#include <iostream>
#include <Windows.h>
extern "C"
__declspec(dllexport) void print_path()
std::cout << "PATH seen in C++: " << getenv("PATH") << std::endl;
如前所述,在 Debug 中运行代码会从 C# 和 C++ 打印相同的路径,但在 Release 中运行代码会导致从 c++ 打印的 PATH 缺少 D:\Temp 文件夹
【问题讨论】:
【参考方案1】:用户环境变量是每个进程的,更改不会传播到其他进程。
在您的示例PATH
中更改系统环境变量。您需要修改注册表项HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
下的值,然后广播WM_SETTINGCHANGE
消息。希望看到更改的应用程序必须处理广播。
来源:https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables
【讨论】:
是什么让您认为涉及多个流程? 这是一个单进程应用程序。 C# 应用程序导入 C++ dll。两者都生活在同一个进程中 @MarcoGiglio 对此感到抱歉。我认为这仍然适用:"...调用 SetEnvironmentVariable 对系统环境变量没有影响..." 事实上,我们正在更改进程环境变量。当然这不会影响其他进程和系统。【参考方案2】:事实证明,Windows 提供了更多获取环境变量的函数。 从文档 “getenv 和 _putenv 使用全局变量 _environ 指向的环境的副本来访问环境。” 而 GetEnvironmentVariable “从环境块中检索指定变量的内容调用进程。” 从这些陈述来看,GetEnvironmentVariable 看起来是最安全的选择,用 GetEnvironmentVariable 替换 getenv 确实可以解决问题。
参考资料:
https://social.msdn.microsoft.com/Forums/en-US/c27a6623-6f57-4c7e-be9b-6dd35d362872/sharing-environment-variables-across-languages?forum=windowsgeneraldevelopmentissues
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getenv-wgetenv?view=vs-2019
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getenvironmentvariable
【讨论】:
以上是关于跨语言共享环境变量的主要内容,如果未能解决你的问题,请参考以下文章