How to Export Environment Variable Permanently Using Ruby

Use Ruby to permanently (ie, in the registry) set environment variables?

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)

How do you update an environment variable using Ruby and Chef?

I found the answer:

   #Append notepad to user PATH variable
registry_key "HKEY_CURRENT_USER\\Environment" do
$path_name = ""
subkey_array = registry_get_values("HKEY_CURRENT_USER\\Environment", :x86_64)
subkey_array.each{ |val|
case val[:name].include?("PATH")
when true
$path_name = val[:data]
print "\n The User PATH is: #{$path_name}"
break
when false
print ':'
end
}
values [{
:name => "PATH",
:type => :string,
:data => "#{$path_name};D:\\Home\\Apps\\Notepad++\\Notepad++"
}]
action :create
#add a guard to prevent duplicates
not_if {
$path_name.include?("D:\\Home\\Apps\\Notepad++\\Notepad++")
}
end

This code when ran from the CMD line will print the current User PATH variables, then it will append D:/Home/Apps/Notepad++/Notepad++ IF it is not currently in the PATH. If it already exists then this will be skipped.

Ruby: Setting environment variables using system()

The reason they don't 'stick' is because when you run a shell command from Ruby it opens a new process. And that process, as a child to your current Ruby process is not persistent, as eventually it dies.

A good resource on this is Jesse Storimer's blog post, with much more information about environment and processes than I will type here.

Depending on your operating system, you can use Ruby to write to your 'rc' files, such as ~/.bashrc or on Windows change your registry, if you really want to have these be persistent over logins.

So the answer is, you ARE setting and exporting environment variables. They simply aren't surviving past the life of the child process.

How do I save changes to the system ENV from Ruby (NOT COMMAND SHELL)?

Unfortunately you cannot have a process directly save an environment setting, however you can check out this:

Persisting an environment variable through Ruby

To see how to take advantage of saving the values in registry and making it eventually make it to the environment variables.

fastlane: Ruby environment variable ENV['PWD'] return nil/empty path

After Quitting terminal and launching terminal again, it starts working!

Shell out from ruby while setting an environment variable

system({"MYVAR" => "42"}, "echo $MYVAR")

system accepts any arguments that Process.spawn accepts.

Is it possible to set ENV variables for rails development environment in my code?

[Update]

While the solution under "old answer" will work for general problems, this section is to answer your specific question after clarification from your comment.

You should be able to set environment variables exactly like you specify in your question. As an example, I have a Heroku app that uses HTTP basic authentication.

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate

def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
end
end
end

# config/initializers/dev_environment.rb
unless Rails.env.production?
ENV['HTTP_USER'] = 'testuser'
ENV['HTTP_PASS'] = 'testpass'
end

So in your case you would use

unless Rails.env.production?
ENV['admin_password'] = "secret"
end

Don't forget to restart the server so the configuration is reloaded!

[Old Answer]

For app-wide configuration, you might consider a solution like the following:

Create a file config/application.yml with a hash of options you want to be able to access:

admin_password: something_secret
allow_registration: true
facebook:
app_id: application_id_here
app_secret: application_secret_here
api_key: api_key_here

Now, create the file config/initializers/app_config.rb and include the following:

require 'yaml'

yaml_data = YAML::load(ERB.new(IO.read(File.join(Rails.root, 'config', 'application.yml'))).result)
APP_CONFIG = HashWithIndifferentAccess.new(yaml_data)

Now, anywhere in your application, you can access APP_CONFIG[:admin_password], along with all your other data. (Note that since the initializer includes ERB.new, your YAML file can contain ERB markup.)

How do I add Ruby to the PATH variable on Windows?

first, notice that this question is not really about Ruby, rather about how to set a path in windows (it work the same way if you want to add an executable different from Ruby)

second, you are not overwriting the PATH environment variable because you add the existing content of the same to the new one you are setting in:

set PATH=C:\Ruby200-x64\bin;%PATH%

the %PATH% is the current content of the PATH variable.

Consider using

 set PATH=%PATH%;C:\Ruby200-x64\bin

instead, this will make your OS search the original path before searching the ruby bin folder. Maybe it makes few difference on modern computers, but my old DOS days claim the second solution is better.

third and last point, in Windows you can set environment variables in control panel / system properties
How to get there depends on the version of your OS, but if you search for the ambient variables and system variables you should get there.



Related Topics



Leave a reply



Submit