SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

GUIのダイアログを使ったエンドユーザ向け対話バッチの実現

usebackqを使ってコマンドの結果を変数へ格納する


GUIのダイアログを使う場合の肝について

 バッチファイルはこの例では「usrOpe.bat」としています。

 エンドユーザーに使ってもらう場合はデスクトップにショートカットを作成するなどし、プロパティで[実行時の大きさ]を[最小化]にしておくとよいでしょう。

 ディレクトリの構成については、すべてのファイルが同じ階層にあれば基本的にどこに置いても構いません。ただし、Windows 2000の場合は、パスが半角英数のみである必要があります(後述します)。

 では、各ステップの肝となる部分を説明して行きます。添付ファイルを参照してください。

 まず、バッチファイルの頭に書いてある、

set usrOpeHome=%~d0%~p0

 これは何を意味しているかと言うと、このバッチファイルの存在する場所を取得しています。「%d0」はバッチファイルのドライブレター、「%p0」はファイルのフルパスで、半角チルダは「引用符があれば外す」という意味です。

 バッチファイルを直接ダブルクリックで実行(または、ショートカットを作成して実行)する場合、小物として使うVBScriptとコマンドライン・アプリは同じパス上にあるので、このHomeディレクトリのパスが切ってなくても問題はありません。

 しかし、次のように実行したらどうでしょう?

パスの通っていない場所から起動
C:\> C:\xxxxx\test\usrOpe.bat

 この場合は、実行パスは「C:\」なので、「usrOpe.bat」から呼ばれる小物達が「パスの通った場所」にいない限り、実行時にエラーになるはずです。「タスクでバッチ実行」や「cronでシェルスクリプト実行」する時にも同様の問題が発生します。

 つまり、ここでは、ファイル名に「%~d0%~p0」を付加することで小物達のパスを通している、というわけです。

 次に、

メッセージボックスで使用するVB定数
set msgboxMsg2=vbYesNo

 変数msgboxMsg2にセットしているVB定数については、「msgbox.vbs」の中で、以下の代表的なものについてのみ対応しています。

  1. vbOKOnly
  2. vbOKCancel
  3. vbYesNoCancel
  4. vbYesNo
  5. vbCritical
  6. vbQuestion
  7. vbExclamation
  8. vbInformation

 そして次がこのバッチで最も肝である部分。小物達の実行結果を、どのように環境変数に格納するか、です。

 この小物達は、すべて「結果を標準出力に出力する」という点で共通しています。バッチからこれらを実行した時の結果は、以下の方法で変数に格納できます。

コマンドをバッククォートで括る
for /f "usebackq tokens=*" %%i in (`call <コマンド名>`)
 do @set <変数名>=%%i

 シェルスクリプトを書く人であれば、「バッククォートで括ったコマンドの結果を変数に格納」する方法をよく使われると思います。同様に Windowsのバッチでもバッククォートを使って(usebackq)、結果を変数に格納できるわけです(コマンドがかなり長くなりますが)。

 先ほど、Windows 2000の場合はファイルの置き場所を半角英数のみのパスにする必要があると、述べました。理由は、Windows2000の場合、日本語などのダブルバイトを含んだパスでは上記コマンドがエラーになってしまうからです。これはOS上の制限です。Windows XP以降であれば、ダブルバイトのパスでもOKです。

 小物を実行した後は、変数に結果が格納されています。これを処理の判断材料に使うわけです。

メッセージボックス表示後、「はい」(=6)は処理継続。「いいえ」(=7)は処理終了
for /f "usebackq tokens=*" %%i in (`call cscript //nologo
 "%usrOpeHome%msgbox.vbs"`) do @set usrOpeResult=%%i
if "%usrOpeResult%" == "7" (
    set usrOpeStatus=CANCEL
    goto endofthis
)
if not "%usrOpeResult%" == "6" (
    set usrOpeStatus=ERROR
    goto endofthis
)
インプットボックス表示後、入力値があれば処理継続
for /f "usebackq tokens=*" %%i in (`call cscript //nologo
 "%usrOpeHome%inputbox.vbs"`) do @set usrOpeResult=%%i
if "%usrOpeResult%" == "" (
    set usrOpeStatus=NO_INPUT
    goto endofthis
)
処理対象となるファイルをコモンダイアログで選択後、入力値があれば処理継続
for /f "usebackq tokens=*" %%i in (`call "%usrOpeHome%commdlg"`)
 do @set usrOpeResult=%%i
if "%usrOpeResult%" == "" (
    set usrOpeStatus=NO_FILE
    goto endofthis
)
結果の出力先となるディレクトリをコモンダイアログで選択後、入力値があれば処理継続
for /f "usebackq tokens=*" %%i in (`call "%usrOpeHome%commdlgd"`)
 do @set usrOpeResult=%%i
if "%usrOpeResult%" == "" (
    set usrOpeStatus=NO_DIR
    goto endofthis
)

 このようにして小物達がすべて実行されると、継続する処理に必要な情報は揃ったことになるので、以降の処理は業務的なバッチを記述してください。

 バッチの終わりに終了メッセージを表示します。ここでは標準出力の結果はもう不要です。nulデバイスにリダイレクトして画面上に出さないようにしておきましょう。

バッチの終わりに終了メッセージを表示
call cscript //nologo "%usrOpeHome%msgbox.vbs" >nul 2>&1

おわりに

 「usebackqを使ってコマンド結果を変数へ格納する」というこの方法は、他のさまざまな既存のツールと組み合わせ可能です。

 今さらDOSコマンドでバッチを書くのは苦痛だ、という人が無理にこの方法を取る必要はありません。しかし、バッチを書くのが苦痛ではない人や、普段シェルスクリプトを書いていて、DOSのバッチに「IF分岐」「FORループ」「コマンドのバッククォート括り」などがあることを知らなかったという人は、「モノは試し」程度の気持ちでよいので活用してみてください。

参考資料

  1. コモンダイアログの表示』 護法童子 著
  2. Win32工作室 『フォルダの参照ダイアログを表示するには』 T-Matsuo 著

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

こじま しょういち(コジマ ショウイチ)

会社員。Ukulele Time(たまさかに更新しています)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1129 2008/08/19 17:09

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー