Esecuzione di un programma Ruby come servizio di Windows?

È ansible eseguire un’applicazione ruby ​​come servizio di Windows? Vedo che esiste una domanda correlata che discute dell’esecuzione di un’applicazione Java come servizio Windows , come si può fare con un’applicazione Ruby?

Controlla la seguente libreria: Win32Utils . Puoi creare un servizio semplice che puoi avviare / interrompere / riavviare a tuo piacimento. Attualmente lo sto usando per gestire un’istanza di Mongrel per un’app Rails ospitata da Windows e funziona in modo impeccabile.

Quando si provano i Win32Utils è necessario studiare il documento e cercare la rete prima di trovare un semplice esempio di lavoro. Questo sembra funzionare oggi 2008-10-02:

gem install win32-service

Aggiornamento 2012-11-20: secondo https://stackoverflow.com/users/1374569/paul ora register_bar.rb dovrebbe essere

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' ) 

bar.rb

crea l’applicazione / demone

 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 è il servizio ma dobbiamo prima creare e registrare! questo può essere fatto con sc crea some_service

ma se useremo ruby ​​e win32utils dovremmo farlo a

register_bar.rb

  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' ) 

Nota, c’è uno spazio tra c: \ tmp \ bar.rb in ‘c: \ usr \ ruby ​​\ bin \ rubyw.exe -C c: \ tmp \ bar.rb’

Eseguire ruby register_bar.rb e ora è ansible avviare il servizio dal pannello di controllo del servizio di Windows o

 sc start some_service 

e guarda c: test.log essere riempito con Servizio in esecuzione Thu Oct 02 22:06:47 +0200 2008

Per la semplicità di avere qualcosa su cui lavorare è più facile rimuovere il registro di servizio e crearne uno nuovo invece di modificarne uno esistente

unregister_bar.rb

  require "rubygems" require "win32/service" include Win32 Service.delete("some_service") 

Crediti per le persone http://rubypane.blogspot.com/2008/05/windows-service-using-win32-service-and_29.html

http://rubyforge.org/docman/view.php/85/595/service.html

Ecco un modello di codice per fare 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 

È ansible scrivere (o scaricare) un servizio wrapper. Il wrapper può chiamare ruby.exe per eseguire il programma. Lo stesso trucco funziona per Java, VB, ecc.

Dovresti essere in grado di farlo in IronRuby dato che avresti il ​​framework .NET dietro di te.