我需要在Windows下以提升模式(管理员权限)运行ruby脚本。有可能吗?
答案 0 :(得分:10)
这是怎么做的。最简单的方法是使用ShellExecute
以升级(管理员)权限重新启动可执行文件。
使用Ruby,你可以这样做:
require 'win32ole'
shell = WIN32OLE.new('Shell.Application')
shell.ShellExecute('path_to_ruby_program', nil, nil, 'runas')
如果您启用了Windows UAC,则会为您提供熟悉的Windows弹出对话框,该对话框会请求管理员权限。单击是后,您的流程将以管理员权限运行。
这里的秘诀是使用未记录的ShellExecute
操作参数runas
,这将提升请求的操作。
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
关于如何手动创建提升的命令提示符快捷方式的相关讨论(在某些情况下这可能是一个足够好的解决方案):
http://www.sevenforums.com/tutorials/3718-elevated-command-prompt-shortcut.html
答案 1 :(得分:2)
我要感谢Casper和thegreendroid这个修改后的解决方案。
我无法让他们的例子按原样运行,所以我将这些内容放在一起进行了更多的研究。我对execute_command
进行了一些搜索,因为我安装的ruby 1.9.3不知道如何处理它,我找不到任何东西,所以我使用了反引号。必须转义\
。 2>&1
位是如此ruby实际上获取输出而不是空字符串,如果该输出与Regexp /ERROR/
匹配,那么您没有管理员权限,所以我们希望它返回{{1 }}
这将使用管理权限重新启动,然后加载您在nil
中添加的任何内容以及之后的注释。
require
您可以删除require 'win32ole'
def running_in_admin_mode?
(`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil?
end
if running_in_admin_mode?
require './main.rb' # load the actual program here.
else
path = 'rubyw.exe ' + File.expand_path(__FILE__) # optionally 'ruby.exe '
shell = WIN32OLE.new('Shell.Application')
shell.ShellExecute(path, nil, nil, 'runas')
end
块并将def
语句更改为
if
为了简洁起见。你也可能丢失if (`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil?
变量:
shell
可能的问题:如果WIN32OLE.new('Shell.Application').ShellExecute(path, nil, nil, 'runas')
重复失败,这可能会无限循环,但它对我来说非常有效。
答案 2 :(得分:2)
感谢其他作者,我已经开始使用它了(在Windows 8上测试过):
在ruby脚本的顶部添加:
def running_in_admin_mode?
(`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil?
end
unless running_in_admin_mode?
require 'win32ole'
shell = WIN32OLE.new('Shell.Application')
shell.ShellExecute("ruby", File.expand_path(__FILE__), nil, 'runas')
exit
end
# admin rights ensured
do_something()
或者你可以只有一个包含
的launcher.cmdcd full\path
ruby myscript.rb
并使用管理员权限
启动此cmd文件一旦你用ruby测试过,你可以试试rubyw
答案 3 :(得分:1)
另一种方法是确保您不以非管理员模式运行脚本。我发现这个解决方案在我的经历中令人满意。
可以确定脚本是否在管理模式下运行 -
def running_in_admin_mode?
query_admin_mode_cmd = 'reg query "HKU\S-1-5-19"'
output, exit_status = execute_command(query_admin_mode_cmd)
exit_status == 0
end
感谢Peter McEvoy的回答here