[VBS] Mutex o Similar

Iniciado por avenkanet, 23 Junio 2015, 18:39 PM

0 Miembros y 1 Visitante están viendo este tema.

avenkanet

Estaba buscando info para hacer algo similar a la API CreateMutex desde VBS. La idea es evitar que nuestro script este corriendo dos o mas veces al mismo tiempo, y encontré este código:

Código (vb) [Seleccionar]

Function MutexOpt()
Dim oProcesses
Dim oProcess
Dim iProcCount
Dim bQuit
Set oProcesses = GetObject("winmgmts:\\.\root\cimv2").ExecQuery( "Select * from Win32_Process where Name='cscript.exe' or Name='wscript.exe'",,48)

For Each oProcess in oProcesses
If Instr(1, oProcess.CommandLine, WScript.ScriptName, 1) > 0 Then
iProcCount = iProcCount + 1
End If
Next

MutexOpt = (iProcCount > 1)

End Sub


Pero no creo que sea la mejor opción porque si corremos nuestro script dos o mas veces pero con diferentes nombres este función no serviría.

Alguien tiene alguna mejor idea ?

Gracias.

XcryptOR

#1
encontré esto por ahí, no se si sea una mejor opción

Código (vb) [Seleccionar]
''Objects
set shell = createObject("wscript.shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")


''Check the args passed into the script. Specifically looking for the last argument which is the script mutex
Set args = Wscript.Arguments
argsFound = false
For Each arg In args
argsFound = arg
Next

''If we didn't get any arguments re-run self with a random arg string, this will be the mutex
if argsFound = false then
runSelf(genRndStr(8))
Else

''The last argument is the mutex string
mutex = argsFound
end if

''remove any other instances of this script
killPastInstances(mutex)



''This sub will kill all instnances of the currently running vbscript that are running under the same interpreter
''but it will not kill it's self
''note, this requires that this script has a uniquite mutex
sub killPastInstances(mutex)

''Get self name
scriptName = WScript.ScriptFullName

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process",,48)
For Each objItem in colItems

if instr(objItem.CommandLine, scriptName) > 0 Then
 ''If the instance of the script is NOT this instance
 if not instr(objItem.CommandLine, mutex) > 0 then

  ''Kill it!
  objItem.Terminate()
 end if
end if
Next
end sub


''generates a random string of length "count"
Function genRndStr(Count)
   Randomize
   For i = 1 To Count
       If (Int((1 - 0 + 1) * Rnd + 0)) Then
           genRndStr = genRndStr & Chr(Int((90 - 65 + 1) * Rnd + 65))
       Else
           genRndStr = genRndStr & Chr(Int((57 - 48 + 1) * Rnd + 48))
       End If
   Next
End Function


''re-runs the curernt script with args in cscript if it is running in wscript. current script exits
sub forceCscript
 If Instr(1, WScript.FullName, "CScript", vbTextCompare) = 0 Then

Set args = Wscript.Arguments
argStr = ""
For Each arg In args
argStr = argStr & " " & arg
Next

   Shell.Run "cscript """ & WScript.ScriptFullName & """" & argStr, 1, False
   WScript.Quit
 End If
end sub



''Runs a new instance of the current script with additional arguments. Current script exits
sub runSelf(extraArgStr)
 
''Are we runing in C or W script?
interpreter = "wscript.exe"
If Instr(1, WScript.FullName, "CScript", vbTextCompare) = 0 Then
interpreter = "wscript.exe"
else
interpreter = "cscript.exe"
end if

''Get current args
Set args = Wscript.Arguments
argStr = ""
For Each arg In args
argStr = argStr & " " & arg
Next

''append new args if required
if extraArgStr <> "" then argStr = argStr & " " & extraArgStr

   Shell.Run interpreter & " """ & WScript.ScriptFullName & """" & argStr, 1, False
   WScript.Quit
 
end sub