Уточнённый текст WQL-запроса (в предыдущем примере скрипт, открытый в Блокноте, воспринимался как уже запущенный), учитывающий, что исполняющими хостами для WSH могут быть только «wscript.exe» или «cscript.exe» (если Вы используете дополнительные хосты — исправьте WQL-запрос соответствующим образом):
"SELECT Name, CommandLine, ProcessID FROM Win32_Process WHERE " & _
"Name LIKE '%[cw]script.exe' AND " & _
"CommandLine LIKE '%[cw]script%" & WScript.ScriptName & "%'", "WQL", 0)
Расширенный пример:
Option Explicit
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx
Dim currPID
Set objSWbemServicesEx = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
currPID = GetScriptProcessID()
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT Name, CommandLine, ProcessID FROM Win32_Process WHERE " & _
"Name LIKE '%[cw]script.exe' AND " & _
"CommandLine LIKE '%[cw]script%" & WScript.ScriptName & "%'", "WQL", 0)
If collSWbemObjectSet.Count > 1 Then
WScript.Echo "Скрипт уже запущен (* — текущий процесс):"
For Each objSWbemObjectEx In collSWbemObjectSet
If currPID = objSWbemObjectEx.ProcessID Then
WScript.Echo " * PID:" & vbTab & objSWbemObjectEx.ProcessID & vbTab & "Command line: " & objSWbemObjectEx.CommandLine
Else
WScript.Echo " PID:" & vbTab & objSWbemObjectEx.ProcessID & vbTab & "Command line: " & objSWbemObjectEx.CommandLine
End If
Next
WScript.Quit 1
End If
WScript.Echo "Единственный экземпляр скрипта:"
For Each objSWbemObjectEx In collSWbemObjectSet
WScript.Echo " * PID:" & vbTab & objSWbemObjectEx.ProcessID & vbTab & "Command line: " & objSWbemObjectEx.CommandLine
Next
WScript.Echo
WScript.Echo "Здесь операторы Вашего скрипта. В примере же просто ждём 60 секунд."
WScript.Echo "Вы можете за это время попробовать запустить другой экземпляр этого же скрипта."
WScript.Sleep 60 * 1000
Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing
WScript.Quit 0
'=============================================================================
'=============================================================================
' WSH: как из скрипта определить его идентификатор процесса (PID)
' (http://forum.script-coding.com/viewtopic.php?id=2454)
'
Function GetScriptProcessID()
With WScript.CreateObject("WScript.Shell").Exec("""mshta.exe"" ""<HTML><HEAD><HTA:APPLICATION APPLICATIONNAME='GetParentPID' WINDOWSTATE='minimize' SHOWINTASKBAR='no'</HEAD></HTML>""")
GetScriptProcessID = objSWbemServicesEx.Get("Win32_Process.Handle='" & CStr(.ProcessID) &"'").ParentProcessID
.Terminate
End With
End Function
'=============================================================================
Первый запуск скрипта:
Единственный экземпляр скрипта:
* PID: 5888 Command line: CScript.exe "C:\Песочница\39\0001.vbs"
Здесь операторы Вашего скрипта. В примере же просто ждём 60 секунд.
Вы можете за это время попробовать запустить другой экземпляр этого же скрипта.
Второй запуск скрипта (во время работы первого):
Скрипт уже запущен (* - текущий процесс):
PID: 4912 Command line: CScript.exe "C:\Песочница\39\0001.vbs"
* PID: 4708 Command line: CScript.exe "C:\Песочница\39\0001.vbs"