Run と Exec の違い【WSH】

まとめ

RunExec
表示IntWindowStyle 引数で指定可能
非表示/表示/アクティブ/最小化/最大化
非表示(cscript) / 表示(wscript)
入出力不可※StdIn / StdOut / StdErr が取得可能
親終了親通常終了:子実行継続
親強制終了:子実行継続
親通常終了:子実行継続※
親強制終了:子強制終了
子強制終了不可※Terminate で強制終了が可能
戻り値同期実行時の戻り値ExitCode で取得可能
プロセスID不可※ProcessID で取得可能

表示

  • Run
    • 引数の IntWindowStyle で指定可能
    • 下記の表参考
  • Exec
    • 実行方法で強制選択
    • 非表示(cscript) / 表示(wscript)

IntWindowStyle

IntWindowStyle内容
0ウィンドウを非表示にし、別のウィンドウをアクティブにします。
1ウィンドウをアクティブにして表示します。ウィンドウが最小化または最大化されている場合は、元のサイズと位置に戻ります。アプリケーションでウィンドウを最初に表示するときには、このフラグを指定してください。
2ウィンドウをアクティブにし、最小化ウィンドウとして表示します。
3ウィンドウをアクティブにし、最大化ウィンドウとして表示します。
4ウィンドウを最新のサイズと位置で表示します。アクティブなウィンドウは切り替わりません。
5ウィンドウをアクティブにし、現在のサイズと位置で表示します。
6指定したウィンドウを最小化し、Z オーダー上で次に上位となるウィンドウをアクティブにします。
7ウィンドウを最小化ウィンドウとして表示します。アクティブなウィンドウは切り替わりません。
8ウィンドウを現在の状態で表示します。アクティブなウィンドウは切り替わりません。
9ウィンドウをアクティブにして表示します。ウィンドウが最小化または最大化されている場合は、元のサイズと位置に戻ります。アプリケーションで最小化ウィンドウを復元するときには、このフラグを指定してください。
10アプリケーションを起動したプログラムの状態に基づいて、表示状態を設定します。

Microsoft."Run メソッド | Microsoft Docs" (最終閲覧日: 2020年03月02日)

入出力

  • Run
    • 不可(ただし、ファイルから入出力が可能)
    • 入力:子標準入力にファイルを入力する
    • 出力:子標準出力をファイル出力後、親からファイルを読込んで結果を取得する
  • Exec
    • StdIn / StdOut / StdErr が取得可能

親終了

  • Run
    • 親通常終了:子実行継続
    • 親強制終了:子実行継続
  • Exec
    • 親通常終了:子実行継続(親終了後、入出力でエラー)
    • 親強制終了:子強制終了

子強制終了

  • Run
    • 不可
    • プロセス ID を取得できれば可能
  • Exec
    • Terminate 関数で強制終了
    • プロセス ID を使用して強制終了
      • WMI 等を使用する

戻り値

  • Run
    • 同期実行時の戻り値
    • 非同期実行時は不可
  • Exec
    • ExitCode 変数から取得

プロセス ID

  • Run
    • 不可
    • ただし、特殊な引数等で実行して、 WMI でプロセスを特定すれば可能
  • Exec
    • ProcessID 変数から取得

Run サンプル

run.jsif (WScript.Arguments.Named.Exists('abc')) {
  // abc オプションあり
  WScript.Echo(WScript.StdIn.ReadLine());
  for (var i=0; i<3; i++) {
    WScript.StdOut.Write(i);
    WScript.StdErr.Write('Error Test.\n');
  }
  WScript.StdOut.Write('\n');
  WScript.Quit(3);
} else {
  // abc オプションなし
  var fs = new ActiveXObject('Scripting.FileSystemObject');
  var f1 = fs.OpenTextFile(".\\run.in.txt", 2, true)
  f1.WriteLine('Hello Run World.');
  f1.Close();
  f1 = null;

  var sh = new ActiveXObject('WScript.Shell');
  var ret = sh.Run('cmd /C 1> run.out.txt 2> run.err.txt cscript "'+WScript.ScriptFullName+'" /abc+ < run.in.txt', 1, true);

  var f2 = fs.OpenTextFile(".\\run.out.txt", 1)
  var out = f2.ReadAll();
  f2.Close();
  f2 = null;

  var f3 = fs.OpenTextFile(".\\run.err.txt", 1)
  var err = f3.ReadAll();
  f3.Close();
  f3 = null;

  WScript.Echo(''
    +      'stdout: '+'\n'+out
    + '\n'+'stderr: '+'\n'+err
    + '\n'+'  exit: '+ret
  );
}

/* 実行結果例
> cscript run.js
stdout:
Hello Run World.
012

stderr:
Error Test.
Error Test.
Error Test.

  exit: 3

*/

Exec サンプル

exec.jsif (WScript.Arguments.Named.Exists('abc')) {
  // abc オプションあり
  WScript.Echo(WScript.StdIn.ReadLine());
  for (var i=0; i<3; i++) {
    WScript.StdOut.Write(i);
    WScript.StdErr.Write('Error Test.\n');
  }
  WScript.StdOut.Write('\n');
  WScript.Quit(3);
} else {
  // abc オプションなし
  var sh = new ActiveXObject('WScript.Shell');
  var obj = sh.Exec('cscript "'+WScript.ScriptFullName+'" /abc+');

  // 1行入力
  obj.StdIn.WriteLine('Hello Exec World');

  // 終了待機 + 標準出力の全読み込み
  var out = obj.StdOut.ReadAll();
  var err = obj.StdErr.ReadAll();
  var id = obj.ProcessID;
  var exit = obj.ExitCode;
  obj = null;

  WScript.Echo(''
    +      'stdout: '+'\n'+out
    + '\n'+'stderr: '+'\n'+err
    + '\n'+'    id: '+id
    + '\n'+'  exit: '+exit
  );
}

/* 実行結果例
> cscript exec.js
stdout:
Hello Exec World
012

stderr:
Error Test.
Error Test.
Error Test.

    id: 17224
  exit: 3

*/

参考