通过Ruby持久化环境变量

时间:2008-10-10 04:54:45

标签: windows ruby environment-variables dos

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

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

我该怎么做?

2 个答案:

答案 0 :(得分:25)

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

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

坏消息是,作为MSDN says,进程永远不能直接更改另一个进程的环境变量,而该进程不是该进程的子进程。因此,当脚本退出时,您将失去它所做的所有更改。

好消息是Microsoft Windows在注册表中存储环境变量,并且可能为系统提供propagate个环境变量。这是一种修改用户环境变量的方法:

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 :(得分:1)

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

解决方法:

我的工作依赖于ruby和Vincent Fatica开发的名为SETENV.EXE的命令行实用程序的组合。它已经超过十年了,但在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