2013/08/04(日) [n年前の日記]
#2 [ruby] RubyからWSHを呼び出して結果を受け取るソレ
先日、RubyからWSHを呼び出してフォルダ選択ダイアログを開いて結果を受け取る、というやり方を試してみたわけだけど。このやり方は問題があることが分かってしまって。
コマンドプロンプト上から hoge.rb を呼び出して、その中からWSHを呼び出した時しか、標準出力に出てきた結果を受け取れない模様。また、wscript.exe を使えばおそらくコマンドプロンプトは開かないけど、標準出力は利用できなくなるそうで。つまり、CUIで作業してるときは問題ないけど、GUIアプリでやろうとすると、これではいかんなあ、と。
どうやって結果を受け取ればいいのか悩んだけど。クリップボード経由ではどうだろうかと思いついたり。以下のような感じにしてみたけれど…。
select_open_folder.vbs
select_folder_use_vbs.rb
これでどや!? と思ったけど、ダメだった。なんか知らんけど、上手く行く時と、Rubyスクリプトが固まる時がある…。
キャンセルを押したときに正常動作しないことにも気付いたり。おそらく、"" をクリップボードに入れようとした際には、クリップボード内容を更新しない、という仕組みになってそうな気がする。何かしらの文字列を無理矢理にでも投入してやらないといかんらしい。
日本語フォルダを選択した時にエラーが発生することにも気付いたり。 win32-clipboard は英数字しか扱えないそうで。かなり致命的。 _cygwin ruby1.9.3 と win32-clipboard-0.5.2 - 世界はアルゴリズムでできている。 によると、パッチを当てれば日本語も通るようになるらしいけど…。標準では日本語文字列が使えないのって、やっぱり厳しい気がする。
- ocra --windows hoge.rb で作った exe から呼び出すと、WSH(cscript.exe)を呼んだタイミングでコマンドプロンプトが開いてしまう。
- しかも、結果文字列を受け取れない。
コマンドプロンプト上から hoge.rb を呼び出して、その中からWSHを呼び出した時しか、標準出力に出てきた結果を受け取れない模様。また、wscript.exe を使えばおそらくコマンドプロンプトは開かないけど、標準出力は利用できなくなるそうで。つまり、CUIで作業してるときは問題ないけど、GUIアプリでやろうとすると、これではいかんなあ、と。
どうやって結果を受け取ればいいのか悩んだけど。クリップボード経由ではどうだろうかと思いついたり。以下のような感じにしてみたけれど…。
select_open_folder.vbs
' フォルダ選択ダイアログを開いて、選択されたフォルダパスを返す VBScript
' 結果文字列をクリップボードに入れてから終了する。
Option Explicit
On Error Resume Next
Dim oParam, oShell, oFolder, s, dirname, objIe
Set oParam = WScript.Arguments
If oParam.Length > 0 Then
s = oParam(0)
Else
s = "フォルダを選択してください"
End If
dirname = "::"
Set oShell = WScript.CreateObject("Shell.Application")
If Err.Number = 0 Then
Set oFolder = oShell.BrowseForFolder(0, s, 0)
If Not oFolder Is Nothing Then
' フォルダ選択がされた場合
dirname = oFolder.Items.Item.Path
Else
' キャンセルされた場合
dirname = ""
End If
Else
' エラーが発生した場合
' WScript.Echo "エラー:" & Err.Description
dirname = ""
End If
' 結果を出力
' WScript.Echo dirname
' 結果をクリップボードにコピー
Const OLECMDID_COPY = 12
Const OLECMDID_SELECTALL = 17
Const OLECMDEXECOPT_DODEFAULT = 0
Set objIe = CreateObject("InternetExplorer.Application")
' objIe.Visible = true
objIe.Navigate "about:blank"
Do While objIe.Busy
WScript.Sleep 100
Loop
objIe.Document.Body.InnerText = dirname
objIe.ExecWB OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT
objIe.ExecWB OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT
objIe.Quit
Set objIe = Nothing
Set dirname = Nothing
Set s = Nothing
Set oFolder = Nothing
Set oShell = Nothing
Set oParam = Nothing
select_folder_use_vbs.rb
#!ruby -Ks
# -*- mode: ruby; encoding: sjis -*-
#
# DXRubyを使ったスクリプト中から、
# WSH(.vbs)でフォルダ選択ダイアログを開き、結果を受け取ってみる
#
# 以前は、cscript.exe を呼び、標準出力経由で結果を受け取っていたが、
# それだとコマンドプロンプトが開いてしまって鬱陶しいので、
# wscript.exe を呼び、かつ、クリップボード経由で受け取るようにしてみた。
require 'rubygems'
require 'dxruby'
require 'win32/clipboard'
include Win32
fpath = ENV['OCRA_EXECUTABLE'] || $0
cdir = File.dirname(File.expand_path(fpath))
fnt = Font.new(12)
folder = ""
cnt = 0
Window.loop do
break if Input.keyPush?(K_ESCAPE)
if Input.keyPush?(K_Z)
title = "フォルダを選択してください (・ωー)〜☆"
wsh_fname = File.join(cdir, "select_open_folder.vbs")
%x[wscript "#{wsh_fname}" "#{title}"] # WSH呼び出し
# クリップボードにフォルダパスが入っているはず
folder = Clipboard.data
puts folder
folder.chomp! # 返ってきた文字列には改行も含まれているので除去
folder = "" if folder =~ /^::/ # 特殊フォルダを選択された際の対策
end
l = [
"#{cnt}",
"Zキー : フォルダ選択ダイアログを開く",
"ESC : 終了",
"[#{folder}]",
]
x, y = 16, 16
l.each do |s|
Window.drawFont(x, y, s, fnt)
y += fnt.size + 8
end
cnt += 1
end
これでどや!? と思ったけど、ダメだった。なんか知らんけど、上手く行く時と、Rubyスクリプトが固まる時がある…。
キャンセルを押したときに正常動作しないことにも気付いたり。おそらく、"" をクリップボードに入れようとした際には、クリップボード内容を更新しない、という仕組みになってそうな気がする。何かしらの文字列を無理矢理にでも投入してやらないといかんらしい。
日本語フォルダを選択した時にエラーが発生することにも気付いたり。 win32-clipboard は英数字しか扱えないそうで。かなり致命的。 _cygwin ruby1.9.3 と win32-clipboard-0.5.2 - 世界はアルゴリズムでできている。 によると、パッチを当てれば日本語も通るようになるらしいけど…。標準では日本語文字列が使えないのって、やっぱり厳しい気がする。
[ ツッコむ ]
以上です。