VBScriptの覚書

ちょっと、記事にするほどでもないのですが、VBScriptを勉強したので覚書として残します

■呼び出し方法

・BATファイルからVBScriptを起動する

echo off

%~d0
cd %~d0%~p0
cd

cscript /nologo test.vbs

pause

管理者権限でBATファイルを実行すると、パスがSystemフォルダになってしまうので、それを避けるために、呼び出し前にcdしています

■UACの回避

・Shell.ApplicationでExeを起動する

Option Explicit

' 引数がない場合、Script自身を再度、管理者権限で実行する
If Wscript.Arguments.Count = 0 Then
    ' 管理者として実行
    AppExecute("wscript.exe", WScript.ScriptFullName & " runas", "runas", 1)
    WScript.Quit
End If

'==============================================================
' これ以降に管理者権限で実行したい処理を記載する
'==============================================================
' メモ帳を管理者権限で実行
AppExecute("notepad.exe", "", "open", 1)

WScript.Quit

'==============================================================
' "Shell.Application"のShellExecuteメソッド
'==============================================================
Sub AppExecute(appPath, appArgs, appOpe, appShow)
    Dim shell
    Set shell = Wscript.CreateObject("Shell.Application")
    
    ' appOpe
    'edit   :エディタを起動し、編集用にドキュメントを開きます。
    'find   :指定されたディレクトリから検索を開始します。
    'open   :アプリケーションを起動します。このファイルが実行可能ファイルでない場合、関連するアプリケーションが起動されます。
    'print  :ドキュメントファイルを印刷します。
    'properties :オブジェクトのプロパティを表示します。
    'runas  :管理者としてアプリケーションを起動します。

    ' 対象のEXEを起動します。
    shell.ShellExecute """" & appPath & """", appArgs, "", appOpe, appShow

    Set shell = Nothing

End Sub
広告

ShellExecuteメソッドでスクリプト自信を”runas”指定して起動することで、管理者権限で実行させることができるので、そのあとに起動するExeは全て管理者権限での実行となる

■実行中プロセス

・WMIでプロセス一覧を取得する

Option Explicit

Dim ret

' メモ帳が実行しているかを取得する
ret = ExistsProcess("notepad.exe")

If (ret = True) Then
    WScript.Echo "実行中です。"
Else
    WScript.Echo "未実行です。"
End If

WScript.Quit

'==============================================================
' WMIで実行中のプロセスを取得する
'==============================================================
Function ExistsProcess(targetExeName)
    ' WMIにて使用する各種オブジェクトを定義・生成する。
    Dim oClassSet
    Dim oClass
    Dim oLocator
    Dim oService
    Dim ret

    ret = False

    Set oLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
    Set oService = oLocator.ConnectServer
    Set oClassSet = oService.ExecQuery("Select * From Win32_Process Where Description = '" & targetExeName & "'")
    
    If oClassSet.Count > 0 Then
        ' コレクションを解析する。
        For Each oClass In oClassSet
            ' http://www.wmifun.net/library/win32_process.html
            Wscript.Echo oClass.Handle & ":" & oClass.Description & ":" & oClass.CommandLine
            If targetExeName = oClass.Description Then
                ret = True
            End If
        Next
        
    End If

    Set oClassSet = Nothing
    Set oClass = Nothing
    Set oService = Nothing
    Set oLocator = Nothing

    ExistsProcess = ret

End Function

「If oClassSet.Count > 0 Then」の時点で、「ret = True」でいいんですけどね

広告

■プロセスの終了を待つ

・WScript.ShellのRunメソッドで終了を待つ

Option Explicit

' メモ帳の終了を待つ
ShellRun("notepad.exe", "", 1, True)

WScript.Echo "終了しました。"

WScript.Quit

'==============================================================
' 指定したEXEを起動します。
'==============================================================
Sub ShellRun(runPath, runArgs, runShow, runWait)
    Dim shell
    Set shell = Wscript.CreateObject("WScript.Shell")
    
    ' runWait : 起動したコマンドの終了待ち
    'True	:待つ
    'False	:待たない

    ' 対象のEXEを起動します。
    shell.Run """" & runPath & """ " & runArgs, runShow, runWait

    Set shell = Nothing

End Sub

Runメソッドを使用すると起動したプロセスの終了を待たせることができます

■標準出力を取得する

・WScript.ShellのExecメソッドで出力を取得する

Option Explicit

Dim sOut, sErr

' メモ帳を管理者権限で実行
ShellExec("cmd /C dir", sOut, sErr)

WScript.Echo "StdOut : " & sOut
WScript.Echo "StdErr : " & sErr

WScript.Quit

'==============================================================
' "WScript.Shell"のExecメソッド
'==============================================================
Sub ShellExec(command, sOut, sErr)
    Dim shell, oExec, stdOut, stdErr
    Set shell = Wscript.CreateObject("WScript.Shell")
    
    Set oExec = shell.Exec(command)
    ' ここでExecの終了を待つ(oExec.statusを見る)
    Set stdOut = oExec.StdOut
    Set stdErr = oExec.StdErr
    ' 
    sOut = stdOut.ReadAll()
    sErr = stdErr.ReadAll()

    Set stdErr = Nothing
    Set stdOut = Nothing
    Set oExec = Nothing
    Set shell = Nothing
    
End Sub

Execメソッドでは標準出力や標準エラー出力を取得することができます

■最後に

VBScriptでできるExe実行の方法をいくつか調べたので記載しました

Excelマクロだと、マクロの実行中に他のExcelが動かせないので、VBScriptで処理させるのも仕事の効率化につながります!

ファイルの存在チェック等と合わせて処理を作れば、夜間バッチのような処理も実現可能ですね

ではでは

広告

やもす ʕ•͡-•ʔ

のんびり!のほほん!がモットーです!w 蕎麦食いたい ライブ行きたい 暑いの嫌い

シェアする