Hey, Scripting Guy!

Scripting Guys が皆さんの質問にお答えします

Hey, Scripting Guy!

TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

詳細情報

Hey, Scripting Guy! カテゴリ別アーカイブ

Hey, Scripting Guy! 日付別アーカイブ

Hey, Scripting Guy! ダウンロード

Spacer

*

スクリプトを右クリックして [コマンド プロンプトで開く] をクリックした場合に、コマンド ウィンドウを開いたままにする方法はありますか

Hey, Scripting Guy! Question

Scripting Guy さん、よろしくお願いします。.VBS スクリプトを右クリックして [コマンド プロンプトで開く] をクリックした場合に、コマンド ウィンドウを開いたままにする方法はありますか。

-- BB

SpacerHey, Scripting Guy! AnswerScript Center

BB さん、こんにちは。みなさん、BB さんの電子メールの署名によると、彼は 9 歳だそうです。これが本当なら、本当に驚きです。VBScript がわかる 9 歳児ですよ。Scripting Guys が 9 歳のときは、自分で食事をすることも、靴紐を結ぶこともできませんでした。

Scripting Guys の場合は、物事の変化が進んでも、その本質は変わらない、ということです。

もちろん、BB さんが 9 歳だと言ったとしても、彼が本当に 9 歳であるとは限りません。何しろ、うちの編集者はずっと 23 歳だと言い張っていますから。しかし、彼女が 1937 年のフランクリン デラーノ ルーズベルト大統領の就任式に出席しているところをばっちり捉えた写真については、どう説明するのでしょうか。釈明の余地なしですよね。

むしろ、この話題になると、彼女はものを投げつけるだけです。

とにかく、BB さんが本当に 9 歳であるという確信は持てませんが、9 歳児しか答えることができないような質問をするなど、彼が 9 歳であることを確かめる方法を考えてみましょう。たとえば、こんな質問です。「ニンジャ タートルズ全員の名前を述べよ」。

確かに。このコラムを執筆している Scripting Guy でさえ、この質問の答えを知っています。レオナルド、ドナテロ、ミケランジェロ、ラファエロです。しかも、インターネットで答えを検索しなくても答えられます。

: 実際、このコラムを執筆している Scripting Guy は、インターネットであれ、それ以外のものであれ、答えを探すのに何かを使うことはありません。彼は何でも知っていると思っているのです。

もちろん、BB さんが本当に 9 歳かどうかは問題ではありません。いずれにせよ、彼はいい質問を送ってくれました。.VBS ファイルを右クリックして利用できるショートカット メニュー オプションの 1 つが、[コマンド プロンプトで開く] です。このオプションを選択した場合の動作として、通常は、コマンド ウィンドウが一瞬画面に表示されて、すぐに消えてしまいます。それだけです。なぜスクリプトが実際に実行されないのでしょうか。また、なぜコマンド ウィンドウが開いたままにならないのでしょうか。

まず、最初の点について考えてみましょう (Hey, Scripting Guy! では珍しいアプローチですね)。実際には、スクリプトは実行されています。多くの VBScripts は非常に短時間で実行されるために、処理が行われていることに気が付かないだけです (コマンド ウィンドウが画面に表示されるのとほぼ同時に、スクリプトの処理が完了し、コマンド ウィンドウを閉じる段階に到達しています)。これを確認する方法を 1 つご紹介しましょう。次のようなメッセージ ボックスを表示するだけの簡単なスクリプトを作成します。

Msgbox "Hey"

では、この .VBS ファイルを右クリックし、[コマンド プロンプトで開く] をクリックしてみましょう。すると、メッセージ ボックスが表示されます。つまり、スクリプトは実際に実行されているということです。

では、どうしてコマンド ウィンドウは開かれたままにならないのでしょうか。その理由は明快で、コマンド ウィンドウは、既定では、処理を実行すると終了するためです。たとえば、[ファイル名を指定して実行] ダイアログ ボックスを開き、「ipconfig」と入力して、Enter キーを押します。コマンド ウィンドウが開かれ、(動体視力がよい方であれば) Ipconfig.exe が実行されたことも確認できるでしょう。ただし、Ipconfig.exe が完了した瞬間に、コマンド ウィンドウは自動的に閉じられます。このため、通常は、コマンド ウィンドウを最初に開いてから、スクリプトやコマンド ライン ツールを実行するように指定されています。コマンド ウィンドウを開いてからスクリプトを実行しないと、スクリプトやツールは実行されても、おそらく結果を確認することはできません。

コマンド ウィンドウを開き、このウィンドウからスクリプトを実行しなければならないということは、問題でしょうか。もちろん、問題ですよね。これでは、そもそも [コマンド プロンプトで開く] というショートカットを用意する意味があまりありませんから。

でも、BB さん、朗報があります。[コマンド プロンプトで開く] ショートカットの動作が気に入らない場合は、このショートカットの動作を変更できます。その方法ですか。いい質問ですね。次のようなコードを使用してはどうでしょうか。

Const HKEY_CLASSES_ROOT = &H80000000

strComputer = "."
 
Set objRegistry=GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
 
strKeyPath = "VBSFile\Shell\Open2\Command"
strValueName = ""
strValue = "cmd.exe /K cscript.exe " & Chr(34) & "%1" & Chr(34) & " %*" 

objRegistry.SetExpandedStringValue _
    HKEY_CLASSES_ROOT,strKeyPath,strValueName,strValue

[コマンド プロンプトで開く] ショートカットの動作は、レジストリ (HKEY_CLASSES_ROOT\VBSFile\Shell\Open2\Command) の設定によって制御されます。既定では、この設定により (ユーザー設定に応じて) CScript または WScript スクリプト エンジンが呼び出され、コマンド ライン引数としてファイル パスが渡されます。

%SystemRoot%\System32\CScript.exe "%1" %*

このショートカットを使用するときに、いつもコマンド ウィンドウが開かれたままにするのに必要な作業は、このレジストリ キーの設定を変更するだけです。その方法については、このすぐ後に説明します。

スクリプトを見るとわかるように、まず HKEY_CLASSES_ROOT という名前の定数を定義し、値を &H80000000 に設定しています。この定数を使用して、スクリプトに操作対象のレジストリ ハイブを指示します。次に、ローカル コンピュータの WMI サービスに接続して、StdRegProv クラスにバインドしています (このクラスは、root\default 名前空間に含まれています)。

: このスクリプトをリモート コンピュータに対して実行できるか、ですって。もちろんです。必要な作業は、リモート コンピュータの名前を strComputer 変数に代入するだけです。

WMI サービスに接続したら、次の 3 つの変数に値を代入します。

strKeyPath: HKEY_CLASSES_ROOT ハイブ内のレジストリ パスを示します。ここでは、パスを VBSFile\Shell\Open2\Command に設定しています。

strValueName: 実際に変更対象となるレジストリ値を示します。ここでは既定値を変更します。既定値とは、Regedit で "(既定)" のように表示される値です。この既定値を操作することを指示するにはどうしたらよいでしょうか。方法は簡単で、strValueName 変数に空の文字列 ("") を代入します。

strValue: レジストリに書き込む新しい値を示します。

strValue 変数について少し説明しましょう。既に説明したように、コマンド ウィンドウは、ウィンドウが開いて、処理を実行したら、ウィンドウを閉じるという動作を取ります。ただし、指定された作業を完了した後も、コマンド ウィンドウを開いたままにする方法はあります。これには、ウィンドウを開くときに、/K (維持を意味する keep の K) スイッチを使用します。ここでは、まさにこの処理を行います。ただし、ここでは、Cscript.exe を直接起動するのではなく、コマンド ウィンドウ (Cmd.exe) を開くときに /K スイッチを指定して、ウィンドウを開いたままにしています。これを行うのが次のコード ブロックです。

cmd.exe /K

次に、スクリプト ホスト名 (CScript.exe) とファイル パスを Cmd.exe の追加のコマンド ライン引数として渡します。つまり、[コマンド プロンプトで開く] が選択されるたびに、表示されたままになるコマンド ウィンドウを開き、このコマンド ウィンドウが開かれたときに CScript.exe と指定の .VBS ファイルを実行する必要があることを指示します。

難しいでしょうか。そうですね。少なくとも多少は難しいかもしれません。それに、このコマンドの構文 (文字列値に二重引用符を挿入するために使用している関数 Chr(34) が使用されている) は、あまり役に立ちません。しかし、要点としては、strValue 変数には次の値が代入されます。

cmd.exe /K cscript.exe "%1" %*

また、信じられないかもしれませんが、これが [コマンド プロンプトで開く] ショートカットの動作を修正するコマンドなのです。

変数に値を代入したら、後は、SetExpandedStringValue メソッドを呼び出すだけで (レジストリ値は REG_EXPAND_SZ データ型を保持するため) 作業は完了です。

objRegistry.SetExpandedStringValue _
    HKEY_CLASSES_ROOT,strKeyPath,strValueName,strValue

では、.VBS ファイルを右クリックし、[コマンド プロンプトで開く] をクリックしてみましょう。今回はコマンド ウィンドウが開き、スクリプトが実行されて、スクリプトが完了してもコマンド ウィンドウは開かれたままになります。とてもすてきですよね。

何度も言うようですが、BB さん、あなたが本当に 9 歳なら、Scripting Guys はあなたのことをすごいと思います。少なくとも、このコラムを執筆している Scripting Guy は、すごいと思っています。なんといっても、このコラムを執筆している Scripting Guy は、9 歳のときに VBScript をいじったりしていたりすることはありませんでしたから。最大の理由は、その当時は VBScript もコマンド スクリプトも発明されていなかったことですけれどもね。

実際、考えてみると 9 という数字さえ、このコラムを執筆している Scripting Guy が子供のころには発明されていませでした。いやはや・・・。


ページのトップへページのトップへ