Windowsプログラムおよびドキュメントのオープン
Question
IBM i から Windows アプリケーションを開いたり、ドキュメントを開くにはどうしたらいいでしょうか。ブラウザーを開いたり、イメージや PDF を開いたり、Microsoft Word または Excel ドキュメントを開くような感じでやりたいのですが。
Answer
これは、いつでも System iNetwork フォーラムでよくある質問の 1 つのようです。ほとんどの場合、Windows Start コマンドに関する回答が示されています。コマンド・プロンプト・ウィンドウが開き、その醜いウィンドウ表示を処理しなければならないため、Start コマンドは好きではありません。さらに、DOS が特別な方法で解釈するすべての文字のエスケープを処理する必要があります。
お勧めしない別のよくある回答は、Windows プログラムへのパス名のハードコーディングです。ユーザーが別のプログラムを使用する場合どうなるでしょう。別のバージョンのプログラムにアップグレードするつもりでいたのに、名前が異なっている場合はどうなるでしょうか。さぁ、皆さん! 皆さんはプログラマーでしょう。ハードコーディングが、害があるのはわかっているはずです。私がお気に入りの技法は、Windows rundll32 ツールを使用することです。
Windows ファイル・アソシエーション
ハードコーディングしないようにするため、Windows にはファイル・タイプおよびそれらのファイル・タイプ上で動作できるプログラムのデータベース (実際は、レジストリーの一部) があります。これらをファイル・アソシエーションと呼びます。例えば、DOC ファイル・タイプは通常 Microsoft Word に関連づけられています。レジストリー内では、「.DOC ファイルを開く場合は、Microsoft Word を実行してください」という鍵があり、正しいパラメーターを指定したプログラムを実行して .DOC ファイルを開くためのパス名および構文を提供しています。
オープン操作は通常デフォルト操作ですが、編集、印刷、探索、検索などの他の操作があります。Windows では、ファイルを右クリックすると、どの操作を実行するか選択できます。Windows はレジストリーを調べて正しいプログラムを見つけ、正しいパラメーターを渡し、規定の方法でドキュメントを操作します。
プログラムをハードコーディングする必要がないため、これはエレガントなシステムです。Microsoft Office ではなく OpenOffice を使用する場合、.DOC が OpenOffice に話しかけるためのアソシエーションを設定できます。URL や HTML ドキュメントにも同じことが当てはまります。Web ドキュメントを開くよう Chrome を設定しながら、同時に Firefox を選択するかもしれません。Internet Explorer を選択する人もいるかもしれません。ハードコーディングされていないため、自分で決断すれば、自分で選んだプログラムが開きます。
Windows ShellExecute() API
ShellExecute() は Shell32.DLL という DLL の中で活動している API です。この DLL は Windows に同梱されています。その役割は、ファイルのダブルクリックや右クリックに相当する API を提供することです。ShellExecute() に、起動するファイルへのパス名や希望の操作 (オープン、印刷、編集など) などのパラメーターをいくつか渡します。ShellExecute() は正しいアプリケーションを見つけ、ドキュメントを処理し、正しいパラメーターでそのドキュメントを呼び出します。
DLL はサービス・プログラムの Windows 相当版です。それはプログラムに似ていますが、プログラム名で呼び出す開始ポイントを 1 つ持つのではなく、ILE サービス・プログラムのように、個別に呼び出すことができる多数のサブプロシージャー (PC 用語では「関数」と呼びます) を持っています。したがって、それを使用して IBM i ソフトウェアからネットワーク経由でプログラムは開始できません。それとも、できますか。
RunDLL32 ユーティリティー
RunDLL32 は「Run DLL (32 ビット)」を表す Windows プログラムで、コマンド・ラインから関数を呼び出すことができます。DLL32 の実行には、次の 2 つのパラメーターが必要です。
rundll32 DllName,FunctionName パラメーター
RunDLL32 に渡された最初のパラメーターにはフィールドが 2 つあります。最初のフィールドは DLL の名前 (拡張子はありません) です。この後にコンマが続き、呼び出す関数の名前が続きます。
RunDLL32 により、呼び出す関数にパラメーターを 1 つ (1 つだけです。これは最も不満がたまる制限です) 渡すことができます。Windows プログラムを起動する理想的な方法は ShellExecute() であるため多少のジレンマはありますが、ShellExecute() は 1 つのパラメーターだけでは動作しません。6 つのパラメーターが必要なのです。つまり、RunDLL32 からは呼び出せないということですね。
まあ、それにはコツが必要です。ある段階で、Microsoft は ShellExecute() が RunDLL32 と互換性がないという事実を認識したため、「RunDLL 互換バージョン」の ShellExecute() を追加しました。Microsoft はそれを ShellExec_RunDLL と名付け、RunDLL 互換であると示しました。ShellExec_RunDLL では、パラメーターは 1 つ、アイコンへのパス名だけが必要です。そのアイコンでは常に「デフォルト」操作 (ほとんど常に「オープン」) となり、デフォルト設定でウィンドウを開きます。
結果的に、Windows コマンド・プロンプトまたは「スタート」「ファイル名を指定して実行」から、次を実行できます。
rundll32 shell32,ShellExec_RunDLL "C:\scott-test\test.pdf"
これを実行する場合、Windows はデフォルト・ビューアーを使用して PDF ドキュメントを開きます (通常は Acrobat Reader ですが xpdf や同様のツールでもかまいません)。
IBM i の RunDLL32
Start PC Command (STRPCCMD) コマンド経由で対話式セッションを行っているときに、ユーザーの PC で RunDLL32 を実行できます。STRPCCMD は、特殊なフォーマットの画面イメージをエミュレーション・ソフトウェアに送信することで動作します。エミュレーターはそれを (通常の画面ではなく) リモート・コマンドとして認識し、代行受信します。そして、送信したコマンドを実行します。ほとんどのエミュレーション・ソフトウェアは実行依頼されたプログラムを検査します。DOS プログラムならば、DOS ウィンドウを開いて実行します。Windows プログラムならば、小さなブラック・ボックスがない Windows アプリケーションとして起動します。だから、スタート・ユーティリティーを使用したくないのです。
STRPCCMD を使用してユーザーの PC のプログラムを開始する例を示します。
PGM DCL VAR(&CMD) TYPE(*CHAR) LEN(123) DCL VAR(&PATH) TYPE(*CHAR) LEN(89) STRPCO PCTA(*NO) MONMSG IWS4010 CHGVAR VAR(&PATH) + VALUE('"C:\Windows\Media\Windows XP Shutdown.wav"') CHGVAR VAR(&CMD) + VALUE('rundll32 shell32,ShellExec_RunDLL ' *BCAT &PATH) STRPCCMD PCCMD(&CMD) PAUSE(*NO) ENDPGM
前述のプログラムは、デフォルト・アプリケーションを起動し、Windows XP PC をシャットダウンするときにいつも聞こえる WAV (サウンド) ファイルを再生します。ご心配なく。実際には PC をシャットダウンしませんから。サウンドを再生するだけです。同僚が見ていないときにこっそり彼らのプログラムに忍び込みます。彼らには「Windows をシャットダウンしています」音声が聞こえ、あたふたするわけです。面白いですよ。一度お試しを。
試すことはもっとあります。
- Word を開く: CHGVAR &PATH VALUE('C:\path\to\mydocument.doc')
- Excel を開く: CHGVAR &PATH VALUE('C:\path\to\mydocument.xls')
- PDF を開く: CHGVAR &PATH VALUE('C:\path\to\mydocument.pdf')
- ブラウザーを開く: CHGVAR &PATH VALUE('http://www.google.com/search?q=Scott+Klement')
- プログラムを実行する: CHGVAR &PATH VALUE('calc')
- コントロール・パネル・プラグイン: CHGVAR &PATH VALUE('services.msc')
- 30 秒でシャットダウン: CHGVAR &PATH VALUE('shutdown.exe -s')
- 異常終了: CHGVAR &PATH VALUE('shutdown.exe -a')
もちろん STRPCCMD で行う場合も欠点があり、それは呼び出しプログラムに戻すことは難しいということです。例えば、コマンドが成功したかどうか告げる方法はありません。それでも、かなりいかしたツールではあります。