RubyアプリケーションをWindowsサービスとして実行することは可能ですか? JavaアプリケーションをWindowsサービスとして の実行について説明している関連する質問があるようですが、どうすればよいですか? Rubyアプリケーションでこれを行いますか?
次のライブラリを確認してください: Win32Utils 。自由に開始/停止/再開できるシンプルなサービスを作成できます。私は現在、WindowsでホストされているRailsアプリのMongrelインスタンスを管理するためにそれを使用しており、問題なく動作します。
Win32Utilsを試すときは、簡単な実例を見つける前に、ドキュメントを調べてネットを調べる必要があります。これは今日はうまくいくようです2008-10-02:
gem install win32-service
アップデート2012-11-20: https://stackoverflow.com/users/1374569/paul によると、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はサービスですが、最初に作成して登録する必要があります。これはsccreatesome_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")
人々へのクレジット http://rubypane.blogspot.com/2008/05/windows-service-using-win32-service-and_29.html
これが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
ラッパーサービスを作成(またはダウンロード)できます。ラッパーはRuby.exeを呼び出してプログラムを実行できます。同じトリックがJava、VBなどでも機能します。
.NETフレームワークが背後にあるため、IronRubyでこれを実行できるはずです。