Ruby で DOS 環境変数を設定しようとしていて、スクリプトが終了した後もそれを維持しようとしています。たとえば、Ruby スクリプトset_abc_env.rb
で環境変数 'ABC' を 'blah' に設定したい場合は、次のように実行する必要があります。
C:> echo %ABC%
C:> set_abc_env.rb
C:> echo %ABC% blah
どうすればいいですか?
Ruby で DOS 環境変数を設定しようとしていて、スクリプトが終了した後もそれを維持しようとしています。たとえば、Ruby スクリプトset_abc_env.rb
で環境変数 '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 と、 Vincent Fatica によって開発されたSETENV.EXEというコマンド ライン ユーティリティの組み合わせに依存しています。この時点で 10 年以上前のものですが、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