代码之家  ›  专栏  ›  技术社区  ›  Kyle Burton

作为Windows服务运行Ruby程序?

  •  32
  • Kyle Burton  · 技术社区  · 16 年前

    是否可以将Ruby应用程序作为Windows服务运行?我看到有一个相关的问题讨论运行 Java Application as a Windows Service ,如何使用Ruby应用程序进行此操作?

    5 回复  |  直到 9 年前
        1
  •  25
  •   user229044    9 年前

    签出以下库: Win32Utils . 您可以创建一个简单的服务,您可以在空闲时启动/停止/重新启动。我目前正在使用它来管理一个Windows托管的Rails应用程序的Mongrel实例,它工作得非常完美。

        2
  •  16
  •   Community CDub    7 年前

    在尝试win32utils时,在找到一些简单的工作示例之前,您真的需要学习文档并查看网络。 这似乎在2008年10月2日起作用:

    gem安装win32服务

    2012-11-20更新: 根据 https://stackoverflow.com/users/1374569/paul 寄存器“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'       )
    

    巴尔RB

    创建应用程序/守护程序

    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来完成,创建一些\u服务

    但是如果我们要使用ruby和win32utils,我们应该

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

    注意,“c:\usr\ruby\bin\rubyw.exe-c:\tmp\bar.rb”中的c:\tmp\bar.rb之间有一个空格

    ruby register_bar.rb 现在可以从Windows服务控制面板或

    sc start some_service
    

    并观察c:test.log 服务于2008年10月2日星期四22:06:47+0200运行

    为了简单地使用某些东西,可以更容易地删除服务寄存器并创建新的服务寄存器,而不是修改现有的服务寄存器。

    注销_bar.rb

     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

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

        3
  •  4
  •   raubarede    12 年前

    这是一个代码模板,用于执行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
    
        4
  •  0
  •   Ken    16 年前

    您可以编写(或下载)包装服务。包装器可以调用ruby.exe来执行程序。同样的技巧适用于Java、VB等。

        5
  •  0
  •   GEOCHET S.Lott    16 年前

    您应该能够在IronRuby中完成这一点,因为您后面有.NET框架。