通过Ruby持久化环境变量

9

我正在尝试在Ruby中设置DOS环境变量,并在脚本退出后使其保持。例如,如果我想要一个名为set_abc_env.rb的ruby脚本将环境变量'ABC'设置为'blah',我期望运行以下命令:

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

我该怎么做?

2个回答

25
你可以通过 Ruby ENV 对象访问环境变量:
i = ENV['ABC']; # nil
ENV['ABC'] = '123';
i = ENV['ABC']; # '123'

坏消息是,正如MSDN所说的那样,一个进程永远不能直接更改不是该进程的子进程的环境变量。因此,当脚本退出时,您将失去所有更改。

好消息是,微软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)  

1

对于其他寻找解决方案的人,如果你想要一个更加hack的解决方案而不需要登录或注销,我为类似问题想出了以下解决方案:

解决方案:

我的解决方案依赖于Ruby和一个名为SETENV.EXE的命令行实用程序,由Vincent Fatica开发。它已经超过十年了,但在Windows XP上运行良好(尚未在Windows 7下测试)。在我看来,它比MS提供的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 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接