是否可以将ruby应用程序作为Windows服务运行?我看到有一个相关的问题讨论了运行Java Application as a Windows Service,你怎么能用Ruby应用程序来做呢?
答案 0 :(得分:25)
查看以下库:Win32Utils。您可以创建一个简单的服务,您可以在闲暇时开始/停止/重新启动。我目前正在使用它来管理Windows托管的Rails应用程序的Mongrel实例,它可以完美运行。
答案 1 :(得分:16)
在尝试使用Win32Utils时,确实需要研究文档并查看网络,然后才能找到一些简单的工作示例。 这似乎今天工作2008-10-02:
gem install win32-service
2012-11-20更新: 根据{{3}} register_bar.rb现在应该是
Service.create( :service_name => 'some_service',
:host => nil,
:service_type => Service::WIN32_OWN_PROCESS,
:description => 'A custom service I wrote just for fun',
:start_type => Service::AUTO_START,
:error_control => Service::ERROR_NORMAL,
:binary_path_name => 'c:\usr\ruby\bin\rubyw.exe -C c:\tmp\ bar.rb',
:load_order_group => 'Network',
:dependencies => ['W32Time','Schedule'],
:display_name => 'This is some service' )
LOG_FILE = 'C:\\test.log'
begin
require "rubygems"
require 'win32/daemon'
include Win32
class DemoDaemon < Daemon
def service_main
while running?
sleep 10
File.open("c:\\test.log", "a"){ |f| f.puts "Service is running #{Time.now}" }
end
end
def service_stop
File.open("c:\\test.log", "a"){ |f| f.puts "***Service stopped #{Time.now}" }
exit!
end
end
DemoDaemon.mainloop
rescue Exception => err
File.open(LOG_FILE,'a+'){ |f| f.puts " ***Daemon failure #{Time.now} err=#{err} " }
raise
end
bar.rb是服务,但我们必须先创建并注册! 这可以通过sc create some_service
来完成 require "rubygems"
require "win32/service"
include Win32
# Create a new service
Service.create('some_service', nil,
:service_type => Service::WIN32_OWN_PROCESS,
:description => 'A custom service I wrote just for fun',
:start_type => Service::AUTO_START,
:error_control => Service::ERROR_NORMAL,
:binary_path_name => 'c:\usr\ruby\bin\rubyw.exe -C c:\tmp\ bar.rb',
:load_order_group => 'Network',
:dependencies => ['W32Time','Schedule'],
:display_name => 'This is some service'
)
请注意,'c:\ usr \ ruby \ bin \ rubyw.exe -C c:\ tmp \ bar.rb'中的c:\ tmp \ bar.rb之间有空格
运行ruby register_bar.rb
现在可以从Windows服务控制面板或
sc start some_service
并观看c:test.log 服务正在运行Thu Oct 02 22:06:47 +0200 2008
require "rubygems"
require "win32/service"
include Win32
Service.delete("some_service")
对人们的信任 https://stackoverflow.com/users/1374569/paul
http://rubypane.blogspot.com/2008/05/windows-service-using-win32-service-and_29.html
答案 2 :(得分:4)
这是一个做firedeamon的代码模板:)
#####################################################################
# runneur.rb : service which run (continuously) a process
# 'do only one simple thing, but do it well'
#####################################################################
# Usage:
# .... duplicate this file : it will be the core-service....
# .... modify constantes in beginning of this script....
# .... modify stop_sub_process() at end of this script for clean stop of sub-application..
#
# > ruby runneur.rb install foo ; foo==name of service,
# > ruby runneur.rb uninstall foo
# > type d:\deamon.log" ; runneur traces
# > type d:\d.log ; service traces
#
#####################################################################
class String; def to_dos() self.tr('/','\\') end end
class String; def from_dos() self.tr('\\','/') end end
rubyexe="d:/usr/Ruby/ruby19/bin/rubyw.exe".to_dos
# example with spawn of a ruby process...
SERVICE_SCRIPT="D:/usr/Ruby/local/text.rb"
SERVICE_DIR="D:/usr/Ruby/local".to_dos
SERVICE_LOG="d:/d.log".to_dos # log of stdout/stderr of sub-process
RUNNEUR_LOG="d:/deamon.log" # log of runneur
LCMD=[rubyexe,SERVICE_SCRIPT] # service will do system('ruby text.rb')
SLEEP_INTER_RUN=4 # at each dead of sub-process, wait n seconds before rerun
################### Installation / Desintallation ###################
if ARGV[0]
require 'win32/service'
include Win32
name= ""+(ARGV[1] || $0.split('.')[0])
if ARGV[0]=="install"
path = "#{File.dirname(File.expand_path($0))}/#{$0}".tr('/', '\\')
cmd = rubyexe + " " + path
print "Service #{name} installed with\n cmd=#{cmd} ? " ; rep=$stdin.gets.chomp
exit! if rep !~ /[yo]/i
Service.new(
:service_name => name,
:display_name => name,
:description => "Run of #{File.basename(SERVICE_SCRIPT.from_dos)} at #{SERVICE_DIR}",
:binary_path_name => cmd,
:start_type => Service::AUTO_START,
:service_type => Service::WIN32_OWN_PROCESS | Service::INTERACTIVE_PROCESS
)
puts "Service #{name} installed"
Service.start(name, nil)
sleep(3)
while Service.status(name).current_state != 'running'
puts 'One moment...' + Service.status(name).current_state
sleep 1
end
while Service.status(name).current_state != 'running'
puts ' One moment...' + Service.status(name).current_state
sleep 1
end
puts 'Service ' + name+ ' started'
elsif ARGV[0]=="desinstall" || ARGV[0]=="uninstall"
if Service.status(name).current_state != 'stopped'
Service.stop(name)
while Service.status(name).current_state != 'stopped'
puts 'One moment...' + Service.status(name).current_state
sleep 1
end
end
Service.delete(name)
puts "Service #{name} stopped and uninstalled"
else
puts "Usage:\n > ruby #{$0} install|desinstall [service-name]"
end
exit!
end
#################################################################
# service runneur : service code
#################################################################
require 'win32/daemon'
include Win32
Thread.abort_on_exception=true
class Daemon
def initialize
@state='stopped'
super
log("******************** Runneur #{File.basename(SERVICE_SCRIPT)} Service start ***********************")
end
def log(*t)
txt= block_given?() ? (yield() rescue '?') : t.join(" ")
File.open(RUNNEUR_LOG, "a"){ |f| f.puts "%26s | %s" % [Time.now,txt] } rescue nil
end
def service_pause
#put activity in pause
@state='pause'
stop_sub_process
log { "service is paused" }
end
def service_resume
#quit activity from pause
@state='run'
log { "service is resumes" }
end
def service_interrogate
# respond to quistion status
log { "service is interogate" }
end
def service_shutdown
# stop activities before shutdown
log { "service is stoped for shutdown" }
end
def service_init
log { "service is starting" }
end
def service_main
@state='run'
while running?
begin
if @state=='run'
log { "starting subprocess #{LCMD.join(' ')} in #{SERVICE_DIR}" }
@pid=::Process.spawn(*LCMD,{
chdir: SERVICE_DIR,
out: SERVICE_LOG, err: :out
})
log { "sub-process is running : #{@pid}" }
a=::Process.waitpid(@pid)
@pid=nil
log { "sub-process is dead (#{a.inspect})" }
sleep(SLEEP_INTER_RUN) if @state=='run'
else
sleep 3
log { "service is sleeping" } if @state!='run'
end
rescue Exception => e
log { e.to_s + " " + e.backtrace.join("\n ")}
sleep 4
end
end
end
def service_stop
@state='stopped'
stop_sub_process
log { "service is stoped" }
exit!
end
def stop_sub_process
::Process.kill("KILL",@pid) if @pid
@pid=nil
end
end
Daemon.mainloop
答案 3 :(得分:0)
您可以编写(或下载)包装器服务。包装器可以调用ruby.exe来执行您的程序。同样的技巧适用于Java,VB等。
答案 4 :(得分:0)
你应该能够在IronRuby中完成这个任务,因为你将拥有.NET框架。