4

On Windows, how can I use Ruby to permanently set an environment variable? I know I need to change the registry (through the win32ole module?) but I am a novice with regard to scripting the registry.

I understand that I can say ENV['FOO'] = "c:\bar\baz" to set the environment variable FOO for the session. However, I am instead interested in setting environment variables globally and permanently.

I did find the patheditor gem, which works great for permanently altering the Windows PATH. But I want to set other environment variables, for example, JAVA_HOME.

Noah Sussman
  • 4,576
  • 2
  • 28
  • 25

3 Answers3

8

There is a past question about this. The basic gist is to set the variable in the registry via Win32::Registry (like runako said). Then you can broadcast a WM_SETTINGCHANGE message to make changes to the environment. Of course you could logoff/logon in between then too, but not very usable.

Registry code:

require 'win32/registry.rb'

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

WM_SETTINGCHANGE code:

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)

Thanks to Alexander Prokofyev for the answer.

Also see a good discussion on Windows environment variables in general, including how to set them for the entire machine vs. just the current user ( in HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\ Control\ Session Manager\ Environment)

Community
  • 1
  • 1
jmhmccr
  • 531
  • 4
  • 12
  • I was able to read but not write or create keys, even on the HKEY_CURRENT_USER, I got Access is denied. The [attached pastebin](http://pastebin.com/TSEKeqyb) shows the errors since they're a bit long to put here. I was able to read the key though. Is there away to get around the permissions error, or use elevated permissions then step back down? – FilBot3 Nov 06 '13 at 15:16
1

You're looking for Win32::Registry :

http://www.ruby-doc.org/stdlib/libdoc/Win32API/rdoc/classes/Win32/Registry.html

For reference, here's how I found it:

http://www.google.com/search?client=safari&rls=en-us&q=ruby+registry&ie=UTF-8&oe=UTF-8

Anyhow, then you will want to do something like:

registry.open("HKEY_WINDOWS_GUNK/path/to/your/key", Win32::Registry::KEY_WRITE) do |reg|
   reg[regentry, Win32::Registry::REG_DWORD]=value
end

You might have to create a key first, if it doesn't already exist.

runako
  • 6,132
  • 2
  • 25
  • 15
0

I am pleased to see such a comprehensive set of answers!

It should also be noted that when creating/writing to entries under reserved/system keys (such as HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node on 64-bit Windows operating system) using constant flags such as Win32::Registry::KEY_WRITE and Win32::Registry::KEY_ALL_ACCESS will not exhibit desired behaviour unless the MRI (the Ruby interpreter) instance is started from an "Administrator" kernel context. Starting cmd.exe (Windows shell program) by right-clicking the executable and selecting "Run as Administrator" allows this.