外部プログラムの実行

  WshShell.Run による外部プログラムの実行



↓Microsoft にあるサンプルコード
  
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run( "%windir%\notepad " & WScript.ScriptFullName )
  

通常外部プログラムをスクリプトから起動するには、WshShell.Run メソッドを使用しますが、実行する外部プログラムによっていくつか気を付けなければならない事があります

( もし実行に問題が出る場合は、zip.exe を cmd.exe /c zip.exe に書き換えて下さい )



非同期処理
  
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run( "zip.exe -r homepage D:\nifty\homepage" )
MsgBox("OK")
  

このコードは、D:\nifty\homepage 以下のファイルを全て homepage.zip に圧縮する処理ですが、圧縮が完了する前にメッセージボックスが表示されてしまいます。

バッチ処理は同期処理が基本なので、以下のように書き直します



同期処理 : コマンドプロンプトを開く
  
Set WshShell = WScript.CreateObject("WScript.Shell")
Call WshShell.Run( "zip.exe -r homepage D:\nifty\homepage", , True )
MsgBox("OK")
  

また、zip.exe はコンソールアプリケーション( コマンドライン用 ) なので、実行時にコマンドラインプロンプトのウインドウが開きます。処理時間の長い処理の場合は、実行中である事を示すために表示させる必要も出でてきますが、短時間の処理であればコマンドラインプロンプトのウインドウを開く必要がありません。

そのような場合は以下のように記述します



同期処理 : コマンドプロンプトを開かない
  
Set WshShell = WScript.CreateObject("WScript.Shell")
Call WshShell.Run( "zip.exe -r homepage D:\nifty\homepage", 0, True )
MsgBox("OK")
  

これは、バッチファイルの実行の場合にも同じ事が言えます。また、バッチファイルを実行する場合は cmd.exe /c バッチファイル と書きます



同期処理 : バッチファイルの実行
  
Set WshShell = WScript.CreateObject("WScript.Shell")
Call WshShell.Run( "cmd.exe /c homepage.bat", 0, True )
MsgBox("OK")
  

homepage.bat
  
zip.exe -r homepage D:\nifty\homepage
  


cmd.exe はバッチファイルの代わりに以下のようにして複数の処理を一度に指定できます

cmd.exe /c c: & cd \ & cd "c:\BatchHelper" & wscript.exe "c:\BatchHelper\setup.vbs"






  標準出力と標準エラー出力の取得



標準出力は、コンソールアプリケーションが、コマンドラインプロンプトに出力する場所です。以下のようにしてファイルに出力する事ができます

  
zip.exe -h > stdout.txt
  

Copyright (C) 1990-1999 Info-ZIP
Type 'zip "-L"' for software license.
Zip 2.3 (November 29th 1999). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
  The default action is to add or replace zipfile entries from list, which
  can include the special name - to compress standard input.
  If zipfile and list are omitted, zip compresses stdin to stdout.
  -f   freshen: only changed files  -u   update: only changed or new files
  -d   delete entries in zipfile    -m   move into zipfile (delete files)
  -r   recurse into directories     -j   junk (don't record) directory names
  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)
  -1   compress faster              -9   compress better
  -q   quiet operation              -v   verbose operation/print version info
  -c   add one-line comments        -z   add zipfile comment
  -@   read names from stdin        -o   make zipfile as old as latest entry
  -x   exclude the following names  -i   include only the following names
  -F   fix zipfile (-FF try harder) -D   do not add directory entries
  -A   adjust self-extracting exe   -J   junk zipfile prefix (unzipsfx)
  -T   test zipfile integrity       -X   eXclude eXtra file attributes
  -!   use privileges (if granted) to obtain all aspects of WinNT security
  -R   PKZIP recursion (see manual)
  -$   include volume label         -S   include system and hidden files
  -e   encrypt                      -n   don't compress these suffixes

標準エラー出力は、コンソールアプリケーションが、コマンドラインプロンプトに出力するエラー用の場所です。以下のようにして標準出力と同時にファイルに出力する事ができます

  
zip.exe -h > stdout.txt 2> stderr.txt
  

上記では、stderr.txt は空です。zip.exe にエラーを起こさせると違いがわかります

zip.exe - > stdout.txt 2> stderr.txt

この処理を非同期処理で実行すると、標準出力と標準エラー出力から文字列を取得する事ができます
( cmd.exe /c で実行する必要があります )

  
Call WshShell.Run( "cmd.exe /c zip.exe -h > stdout.txt 2> stderr.txt", 0, True )

strStd = "データはありません" : strErr = strStd
Set Handle = Fso.OpenTextFile( "stdout.txt", 1 )
if not Handle.AtEndOfStream then
	strStd = Handle.ReadAll
end if
Handle.Close
MsgBox(strStd)

Set Handle = Fso.OpenTextFile( "stderr.txt", 1 )
if not Handle.AtEndOfStream then
	strErr = Handle.ReadAll
end if
Handle.Close
MsgBox(strErr)
  



  WshShell.Exec による実行

この実行方法を使用すると、標準出力と標準エラー出力に直接アクセスできます。

ただ、この場合必ずコマントラインプロンプトが開いてしまいますので、ファイルに書き出したほうが実行結果の記録にもなるのでより利用価値があると思います。

※ 但しこの方法では 標準入力 にもアクセスできるので、限定的な利用には欠かせなくなります

  
Set objExec = WshShell.Exec( "zip.exe -h" )

Do While objExec.Status = 0
	WScript.Sleep 100
Loop

Do While not objExec.StdErr.AtEndOfStream
	Call MsgBox( objExec.StdErr.ReadAll,  , "エラー" )
Loop
Do While not objExec.StdOut.AtEndOfStream
	Call MsgBox( objExec.StdOut.ReadAll, , "正常終了" )
Loop
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ