通过Ruby持久化一个环境variables

我想在Ruby中设置我的DOS环境variables,并在脚本退出后保持它。 例如,如果我想要一个ruby脚本set_abc_env.rb将环境variables“ABC”设置为“blah”,我期望运行以下命令:

 C:> echo %ABC% C:> set_abc_env.rb C:> echo %ABC% blah 

我该怎么做呢?

您可以通过Ruby ENV对象访问环境变量:

 i = ENV['ABC']; # nil ENV['ABC'] = '123'; i = ENV['ABC']; # '123' 

坏消息是,正如MSDN 所说 ,一个进程永远不能直接改变另一个进程的环境变量,而这个进程不是这个进程的子进程。 所以当脚本退出时,你会失去所有的改变。

好消息是Microsoft Windows在注册表中存储了环境变量,并且可以将环境变量传播到系统。 这是一种修改用户环境变量的方法:

 require 'win32/registry.rb' Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_WRITE) do |reg| reg['ABC'] = '123' end 

该文档还说,您应该注销并重新登录或广播WM_SETTINGCHANGE消息,以使应用程序可以看到更改。 这是如何在Ruby中进行广播的:

 require 'Win32API' SendMessageTimeout = Win32API.new('user32', 'SendMessageTimeout', 'LLLPLLP', 'L') HWND_BROADCAST = 0xffff WM_SETTINGCHANGE = 0x001A SMTO_ABORTIFHUNG = 2 result = 0 SendMessageTimeout.call(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 'Environment', SMTO_ABORTIFHUNG, 5000, result) 

对于其他人寻找解决方案,寻找更多的不需要登录或注销的黑客,我想出了一个类似的问题的解决方案:

解决方法:

我的工作依赖于ruby和一个名为SETENV.EXE的命令行实用程序,由Vincent Fatica开发。 现在已经超过十年了,但在Windows XP中运行良好(尚未在Windows 7下测试)。 它比MS IMHO提供的setx工具更好。 以免删除东西。 确保setenv可以从命令行使用。 把它放在一些c:\ tools中,然后把c:\ tools放到PATH中。

这是一个使用它的方法的简短例子:

 def switch_ruby_env if RUBY_VERSION.match("1.8.7").nil? `setenv -m CUSTOM_PATH " "` else `setenv -m CUSTOM_PATH -delete` end end