プロセスの優先度をスクリプトで変更
動画などのフォーマット変換などのリアルタイム性の低いソフトはCPUの空き時間にのみ行えるように、特定のプロセスの優先順位を変更するスクリプトを作成してみました。
WMIを使用するとアプリケーションの起動・終了や各種イベントの取得などができます。
これを利用して優先度を変更するスクリプトを作成します。
SINK_OnObjectReadyはWindowsが呼び出したくれるのでメインプログラムは何もする必要がありません。そのため、このプログラムでは意味のない無限ループになっています。
WMIを使用するとアプリケーションの起動・終了や各種イベントの取得などができます。
これを利用して優先度を変更するスクリプトを作成します。
- initProcessStartTrace関数によりプロセスの起動の監視を開始します。プロセスが起動するとコールバック関数SINK_OnObjectReadyがWindowsにより呼び出されるように登録します。
- SINK_OnObjectReady関数はWindowsにより呼び出されます。関数は起動したプロセスの名前を確認しターゲットの関数であれば優先度を変更します。
SINK_OnObjectReadyはWindowsが呼び出したくれるのでメインプログラムは何もする必要がありません。そのため、このプログラムでは意味のない無限ループになっています。
'************************************************************************
'プロセスの起動を監視し優先度を変更するプログラム
' 2006/11/24 namichin
'************************************************************************
initProcessStartTrace
Do
WScript.Sleep 10000
Loop
'*************************************************************************
'メインプログラム終了
'*************************************************************************
'監視するプログラム
Const strTargetProc = "notepad.exe"
'優先度の設定パラメータ
Const PROCESS_LOW = 64 '低
Const PROCESS_BELOW_NORMAL = 16384 '通常以下
Const PROCESS_NORMAL = 32 '通常
Const PROCESS_ABOVE_NORMAL = 32768 '通常以上
Const PROCESS_HIGH = 256 '高
Const PROCESS_REALTIME = 128 'リアルタイム(最高)
'グローバル変数
Dim objWMIService
'*************************************************************************
' プロセスの生成を監視する
' 初期設定関数
' プロセスが生成された場合、コールバック関数SINK_OnObjectReadyを呼び出す
'*************************************************************************
Sub initProcessStartTrace()
Set SINK = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
call objWMIService.ExecNotificationQueryAsync( SINK,"SELECT * FROM Win32_ProcessStartTrace")
End Sub
'*************************************************************************
' プロセス生成時に呼び出されるコールバック関数
' 特定のプロセスのみ優先度を変更する
'*************************************************************************
Sub SINK_OnObjectReady(objLatestEvent, objAsyncContext)
Wscript.Echo "Process Name: " & objLatestEvent.ProcessName & vbcrlf & "Process ID: " & objLatestEvent.ProcessID
If LCase(objLatestEvent.ProcessName) = LCase(strTargetProc) Then
'プロセスIDからプロセスコントロール用のオブジェクトを取得
strHandle = CStr(objLatestEvent.ProcessID)
Set objProcess = objWMIService.Get("Win32_Process.Handle='" & strHandle & "'")
'プロセスの優先度を変更
objProcess.SetPriority(PROCESS_LOW)
End If
End Sub
優先度を変更できるのはWindowsXP以上のOSが必要だそうです。
参考にしたサイト
ちなみにプロセスの起動はここにサンプルがあり、このような形になります。
strCommand = "notepad.exe"
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
intReturn = objProcess.Create(strCommand, Null, Null, intProcessID)
ちなみに、この方法で起動するとWindows 2003 Server以外は終了したプロセスのステータスコードを知ることはできないそうです。

Comments