2

I'm using the following code to obtain the current pid of the currently started wsf script:

<script language="VBScript" type="text/vbscript">
<![CDATA[
On Error Resume Next
Err.Clear

    REM Obtain process id

    WScript.Echo "#$% Find Process ID"

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

    Function CurrProcessId
        Dim oShell, sCmd, oWMI, oChldPrcs, oCols, lOut
        lOut = 0
        Set oShell  = CreateObject("WScript.Shell")
        Set oWMI    = GetObject(_
            "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
        Randomize
        sCmd = "/K @echo " & Int(Rnd * 3333) * CDbl(Timer) \ 1
        oShell.Run "%comspec% " & sCmd, 0
        WScript.Sleep 100 'For healthier skin, get some sleep
        Set oChldPrcs = oWMI.ExecQuery(_
            "Select * From Win32_Process Where CommandLine Like '%" & sCmd & "'", ,32)
        For Each oCols In oChldPrcs
            lOut = oCols.ProcessId 'get parent
            oCols.Terminate 'process terminated
            Exit For
        Next
        Set oChldPrcs = Nothing
        Set oWMI = Nothing
        Set oShell = Nothing
        CurrProcessId = lOut
    End Function

    WScript.Echo CurrProcessId

    WScript.Echo "#$% Process ID Found"

if  Err.Number <> 0  then   
    ' An exception occurred
    WScript.Echo "Exception:" & vbCrLf &_
        "    Error number: " & Err.Number & vbCrLf &_
        "    Error description: '" & Err.Description & vbCrLf
end if
]]>
</script>

It worked perfectly while I started the wsf scripts sequentially, however when more of them is started "parallelly" something unexpected happends, multiple scripts are obtaining the same Process ID:

10 scripts started
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
#$% Find Process ID
1472
#$% Process ID Found
6664
#$% Process ID Found
6456
#$% Process ID Found
6456
#$% Process ID Found
test1.wsf exit code 0
test10.wsf exit code 0
test2.wsf exit code 0
test4.wsf exit code 0
6456
#$% Process ID Found
4100
#$% Process ID Found
4100
#$% Process ID Found
4100
#$% Process ID Found
test3.wsf exit code 0
test5.wsf exit code 0
test6.wsf exit code 0
test7.wsf exit code 0
#$% Process ID Found
Exception:
    Error number: -2147217406
    Error description: 'Not found

6540
#$% Process ID Found
test8.wsf exit code 0
test9.wsf exit code 0

Not to mention that randomly I'm getting some garbe as exception.

My questions are the following:

  1. How it's possible the Windows obtains the same process id for simultaneously started processes?

  2. What causes the exception?

  3. I'm not experienced in wsf and the above code is literally a copy paste, am I doing something wrong?

Akos K
  • 7,071
  • 3
  • 33
  • 46
  • What I'm trying to do is to return the process id of the currently executing wsf script. – Akos K Jan 24 '14 at 09:42
  • Unless I'm missing something, that code is never going to work. I don't know where you got it from, but I don't think it's any good. It doesn't do what it's supposed to, what it does do is pointless, and it isn't even reliable at doing that. – Harry Johnston Jan 28 '14 at 01:00
  • I appreciate your comment, I'm a Java programmer and this code is borrowed from a really old forum post, I could find the link if you want. Given that I'm not a VB script expert, the only way to find out what this script does was to actually start a long running script, grab its process ID then try to terminate the process with that process ID. This worked with one script. If you have any reliable method to return the process ID, please post an answer. – Akos K Jan 29 '14 at 08:30
  • Do you really need the script to determine its own process ID? I ask because it is very easy for a script to determine the process ID for a process it has launched, and depending on what you're trying to achieve it may be possible to rearchitecture to take advantage of this. – Harry Johnston Jan 29 '14 at 20:30
  • These scripts are stared by an external framework, I need to return their process ID because later I can manually terminate the script with `taskkill`. – Akos K Jan 30 '14 at 14:53
  • Unless someone comes up with a way of doing this, your best bet may be to get the external framework to start a wrapper script. The wrapper script would do nothing but launch the actual script and report its ID. See http://msdn.microsoft.com/en-us/library/x78640t0%28v=vs.84%29.aspx – Harry Johnston Jan 30 '14 at 22:12
  • Try this answer http://stackoverflow.com/a/15435873/886887 – Harry Johnston Jan 30 '14 at 22:17
  • possible duplicate of [Find my own process ID in VBScript](http://stackoverflow.com/questions/8296037/find-my-own-process-id-in-vbscript) – Harry Johnston Jan 30 '14 at 22:25
  • regarding the first answer, I have a windows server trial installation and the script terminates on line `If objWMIService Is Nothing Then Exit Function ' Should only happen if in Guest or other super-limited account`. Regarding the second answer, the code given there is almost identical to mine, which turns out that doesn't work at all. – Akos K Jan 31 '14 at 08:33
  • The code in the answer I linked to isn't complete, you'll need to add a line to define `objWMIService`. Try `Set objWMIService = GetObject ("WinMgmts:Root\Cimv2")` – Harry Johnston Feb 02 '14 at 21:50
  • The other answer isn't reliable, but unlike the code in your question it will work at least some of the time. The critical difference is that the code in the other answer says `oCols.ParentProcessId` whereas the code in your question says `oCols.ProcessId`, that is, the code in your question is retrieving the process ID for the child rather than its own. – Harry Johnston Feb 02 '14 at 21:59

0 Answers0