読者です 読者をやめる 読者になる 読者になる

Growl がうらやましかったので伺か引っ張り出してきた

ここのところ、Growl という、Mac上でいろんなポップアップメッセージを出すものがちょこちょこ見かけて、うらやましくなってたところ。

僕もこんなのやりたくなった。VisualStudio でビルドしたときに NUnit の結果を表示させたい。しかしこちとら開発のメインは Windows。Growl はない。

とりあえずぱっとおもいついたのは Agent という、Windows XP に標準で入ってて、Excelのイルカとか出したりするフレームワーク。Windows に最初から入ってて簡単に使えそうというのが第一印象だった。

COMインターフェイス叩くものらしいので、Ruby on Windows を参考にとりあえず簡単なサンプル書いてみた。

require "win32ole"

# Agent を初期化
agent = WIN32OLE.new("Agent.Control")
agent.connected = true
agent.characters.load("Merlin", "C:/WINDOWS/msagent/chars/merlin.acs")
merlin = agent.characters.character( "Merlin" )

# イベント処理を定義
event = WIN32OLE_EVENT.new(agent, nil)
event.on_event do |*e|
  # 待機状態に入ったら止める
  if e[0] == "IdleStart" && e[1] == "Merlin"
    merlin.hide
    exit
  end
end

# キャラクターのアクションをセット
merlin.show              # 表示
merlin.moveTo(200, 200)  # 位置を動かす
merlin.play("Greet")     # アクション
merlin.speak "テスト。"  # 吹き出し

# メッセージループ開始(これがないと表示されない)
loop do
  WIN32OLE_EVENT.message_loop
end


・・・なんかこれ、めんどくね? それにキャラクターが必要になるけど、デフォルトで入ってるキャラってのがマーリンっていうオッサン魔法使いキャラ。かわいくない。

どうせキャラつくんなら、もっとかわいいのがいい。そう思ってぐぐったけど、Agentのキャラでよさそうなのはいまいちみつからず。仕方ないので他の方法を考えてたら伺かを思い出した。

伺かというものが流行したのは何年も前なので解説しておくと、Windows向けのデスクトップアクセサリで女の子とそのお供がニュース読んでくれたりする。
伺かにはWindows系プログラマが燃えるような通信仕様が多数あるのですが、その中に SSTP という機能では、TCPソケット越しにHTTP風のメッセージを送ることによりキャラクタを喋らせたりできたりします。

探してみると、Rubyでは 伺かIO というものでメッセージを送れるらしい。しかも、IO から派生してるので基本的に write 呼ぶだけでお手軽に使える。

# nunit_ukagaka.rb
require 'ukagaka_io'

NUNIT_PATH    = 'C:/Program Files/NUnit 2.4.6/bin'
NUNIT_CONSOLE = NUNIT_PATH + '/nunit-console.exe'

UKAGAKA_ADDR = '127.0.0.1'
UKAGAKA_PORT = 9801

# 引数処理
if ARGV.length == 0
  puts "usage: $0 TestTargetAssembly"
  exit 1
end

# 伺かへの接続を初期化
uio = UkagakaIO.open(UKAGAKA_ADDR, UKAGAKA_PORT)

# 開始メッセージ出す
#script = '\0\s[0]NUnit テスト開始。\e'
#uio.write(script, true)
#uio.flush

# nunit実行
result = `#{NUNIT_CONSOLE} "#{ARGV[0]}" /nologo`
puts result

# 結果のパース・Script 作成・結果送信
if result =~ /^Tests run: (\d+), Failures: (\d+), Not run: (\d+)/
  runs     = $1.to_i
  failures = $2.to_i
  not_runs = $3.to_i
  if failures > 0
    script = '\1\s[10]\0\s[4]\_q' + "#{runs}つ実行、#{failures}つ失敗。" + '\_q\n\n\e'
  else
    script = '\1\s[10]\0\s[5]\_q' + "#{runs}つ実行、エラーなし。" + '\_q\w9やったねっ!\e'
  end
  uio.write(script, true)
  uio.flush
  uio.close
end

これができたら、VisualStudio でテストケースの入ってるプロジェクトのプロパティのビルドタブへ行って、ビルド後に実行するコマンドラインのところにこういうコマンドラインをかき、おもむろにビルドする。プロジェクトテンプレート化しておいてもいいかもしれない。

Rubyのパス> -I<ukagaka_io.rbのあるディレクトリ> <nunit_ukagaka.rbのパス> "$(TargetDir)$(TargetFileName)"
# 例
C:\Commands\bin\ruby.EXE -IZ:\development\misc\halca_scripts\ Z:\development\misc\halca_scripts\nunit_ukagaka.rb "$(TargetDir)$(TargetFileName)"

こんな感じで、テスト結果のサマリをしゃべってくれる。テスト失敗したときはVisualStudioの出力ウィンドウから確認できる。

成功したときの笑顔見たさにコーディングがはかどりそう。てかSSPってほーんと初期しか使ってなかったんですが、いまのエミリは強烈にかわいいですね!