Ruby
Windows
AdventCalendar
開発環境

Windows環境でRuby1.9.3+RsenseをWindowsサービスに >> 失敗orz

More than 5 years have passed since last update.

はじめに

RSenseと本記事の目的

  • ご存じの通り、高機能テキストエディタに特化したRubyのための開発援助ツールです。世の中にはWindowsしか使えない使わないにもかかわらず、Rubyに手をかける方も多くいらっしゃいます。
  • そんな方の手助けになればと思いましたが、おかしなところで時間がかかり、WindowsにおいてRubyを使っていく上の面倒なところばっかりにひっかかってしまい、未完です。随時追記していきますorz

手元の環境を確認

>ruby -v
ruby 1.9.3p125 (2012-02-16) [i386-mswin32_100]

> systeminfo.exe
OS 名: Microsoft Windows 7 Professional
OS バージョン: 6.1.7601 Service Pack 1 ビルド 7601
OS 製造元: Microsoft Corporation
(snip)
システムの種類: x64-based PC
プロセッサ: 1 プロセッサインストール済みです。
[01]: Intel64 Family 6 Model 42 Stepping 7 GenuineIntel~3301 Mhz

まずはRSense のダウンロード

  • 公開先からダウンロード
  • z:/tmp/20120711/rsense-0.3 に解凍したとして進めます

ここで大きな過ち

RSenseをサービスとして登録し、敷居を低くしようと思ったところが大きな過ちでした。

まず、rsense ユーザーズマニュアルに沿って作業します。

gem のインストール

> gem install win32-service
Fetching: win32-api-1.4.8.gem (100%)
Building native extensions. This could take a while...
ERROR: Error installing win32-service:
ERROR: Failed to build gem native extension.

    C:/App/ruby_1_9_3_p125/bin/ruby.exe extconf.rb

checking for strncpy_s()... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
--with-opt-dir

ああ、そうでしたそうでした。コンパイル環境がありませんでした。

そこで、Microsoft公開先から vc_web.exeをダウンロードし、Visual C++ 2010 Express をインストールします。そこそこ時間を要します。途中で寝てました。

[Microsoft Visual Stdio 2010 Express]-[Visual Studio コマンドプロンプト]を起動します。

Setting environment for using Microsoft Visual Studio 2010 x86 tools.

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>
cd c:\App\ruby_1_9_3_p125\bin>
c:\App\ruby_1_9_3_p125\bin>gem install win32-service
Building native extensions. This could take a while...
Fetching: windows-api-0.4.1.gem (100%)
Fetching: windows-pr-1.2.1.gem (100%)
Fetching: win32-service-0.7.2.gem (100%)
Building native extensions. This could take a while...
Successfully installed win32-api-1.4.8
Successfully installed windows-api-0.4.1
Successfully installed windows-pr-1.2.1
Successfully installed win32-service-0.7.2
4 gems installed
Installing ri documentation for win32-api-1.4.8...
Installing ri documentation for windows-api-0.4.1...
Installing ri documentation for windows-pr-1.2.1...
Installing ri documentation for win32-service-0.7.2...
Installing RDoc documentation for win32-api-1.4.8...
Installing RDoc documentation for windows-api-0.4.1...
Installing RDoc documentation for windows-pr-1.2.1...
Installing RDoc documentation for win32-service-0.7.2...

無事成功です。Windows環境においてextconf.rb関連で失敗する場合は大抵これで何とかなると思います。でもnokogiriはcygwinかmingwでしかダメっぽいです。

Windowsのサービスに登録

> ruby bin\rsense service create
C:/App/ruby_1_9_3_p125/lib/ruby/gems/1.9.1/gems/windows-pr-1.2.1/lib/windows/err
or.rb:435:in `strip': invalid byte sequence in US-ASCII (ArgumentError)
from C:/App/ruby_1_9_3_p125/lib/ruby/gems/1.9.1/gems/windows-pr-1.2.1/li
b/windows/error.rb:435:in `get_last_error'
from C:/App/ruby_1_9_3_p125/lib/ruby/gems/1.9.1/gems/win32-service-0.7.2
/lib/win32/service.rb:368:in `initialize'
from bin/rsense:228:in `new'
from bin/rsense:228:in `exec_command'
from bin/rsense:288:in `process'
from bin/rsense:297:in `<main>'

windows-pr-1.2.1/lib/windows/error.rbを見ると、1.9系のエンコードぽいエラーが出ている様子。ここで目的を見失いながら適当に対処。

windows-pr-1.2.1/lib/windows/error.rb
def get_last_error(err_num = GetLastError.call)
  buf   = 0.chr * 260
  flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY
  FormatMessageA.call(flags, 0, err_num, 0, buf, buf.size, 0)
  #buf.strip
  buf
end

サービスの登録に失敗しているのはUAC関連だろうと考え、管理者権限で起動したcmd.exeから実行したところ成功です。

> ruby bin\rsense service create
>sc query rsense

SERVICE_NAME: rsense
TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
WIN32_EXIT_CODE : 1077 (0x435)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

でも起動しない。

net start RSense
システム エラー 2 が発生しました。

指定されたファイルが見つかりません。

まずはWindowsサービスのプロパティから、コマンドライン引数を確認。

rubyw.exe z:/tmp/20120711/rsense-0.3/bin/rsense --config=C:\home\tamoot/.rsense

rubyw.exeがフルパスではない+PATHが通っていないため、rubyw.exeが見つからず失敗していました。

ソースからも確認しました。

win32-service-0.7.2/lib/win32/service.rb
when 'create'
  path = Pathname.new(@rsense_home).realpath
  command = Shellwords.unshellwords %W(rubyw.exe #{path}/bin/rsense --config=#@config service daemon)
  Win32::Service.create(:service_name       => SERVICE_NAME,
                        :service_type       => Win32::Service::WIN32_OWN_PROCESS,
                        :description        => 'RSense Service',
                        :start_type         => Win32::Service::DEMAND_START,
                        :binary_path_name   => command,
                        :display_name       => 'RSense')

rubyw.exeについてとりあえずフルパス記載し、再度サービス登録・起動は成功しました!(長かった)

ではここで焦らず、開いているポートを確認します。

z:\tmp\20120711\rsense-0.3>tasklist /v | findstr rubyw
rubyw.exe 3332 Services 0 10,184 K Unk
nown NT AUTHORITY\SYSTEM 0:00:02 N/A
z:\tmp\20120711\rsense-0.3>netstat -aon | findstr 3332
TCP 127.0.0.1:11831 0.0.0.0:0 LISTENING 3332

あれ?11831ポートが開いている。ソースを見ても、11831という指定は無いな・・・案の定クライアント側からつながっていない様子。

とここで体力が切れました。今後追記していきます。

ここまでのまとめ

  • RSense自体は簡単
  • Ruby 1.9.3 + Windowsでサービス登録しようと思うとちょっと面倒

説明してないところ

WindowsでRSenseを利用可能なエディタ達

RSense導入の敷居を下げて、社内で使ってもらえればコピペ全盛期の現在よりはマシになるのになーと思っております。