【问题标题】:Persisting an environment variable through Ruby通过 Ruby 持久化环境变量
【发布时间】:2010-09-16 10:51:05
【问题描述】:

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

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

我该怎么做?

【问题讨论】:

    标签: windows ruby environment-variables dos


    【解决方案1】:

    您可以通过 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)  
    

    【讨论】:

      【解决方案2】:

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

      解决方法:

      我的工作依赖于 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 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-19
        • 1970-01-01
        • 1970-01-01
        • 2012-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多