none
VBScript to launch an application and wait for a process to complete before closing. RRS feed

  • Question

  • I found this script on ServerFault

    http://serverfault.com/questions/119398/script-to-wrap-around-an-application-and-wait-for-app-to-finish

    If I understand it correctly, it should launch the command set at RUN_CMD, and wait for the process defined at PROC_NAME.

    In his example, he has it starting and watching the same process.  I want to use it to start one, and watch the process spawned by it.  (Actually it's more like 3 processes removed)

    It's not working for me.  It closes immediately after RUN_CMD is executed.

    I guess all I'm really asking is, is this the way it's supposed to function and I just have something messed up?  Or am I completely misusing this script. :)

    Thanks,

    -Matt

    My edited version:

    Option Explicit
    
    Const PROC_NAME = "radpinit.exe"
    Const RUN_CMD = """C:\Program Files (x86)\Novadigm\radntfyc.exe"" LOCALHOST Radskman.exe cat=prompt,ulogon=n,hreboot=y,context=m,mname=radia,dname=SOFTWARE,ip=wkpv1radaa08.cbsh.com,port=3464,uid=$MACHINE,startdir=SYSTEM,ind=y,cop=y,log=software_connect.log"
    Const SLEEP_INTERVAL_MS = 1000
    Const WAIT_TIMEOUT_MS = 30000 ' = 1000 * 60 * 25 ms = 25 mins
    
    Dim objWshShell, objWMIService
    Dim colProcesses, objProcess
    Dim intWaited, blnProcessTerminated
    
    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
    Set objWshShell = WScript.CreateObject("WScript.Shell")
    objWshShell.Run RUN_CMD
    
    intWaited = 0
    blnProcessTerminated = False
    While intWaited < WAIT_TIMEOUT_MS And Not blnProcessTerminated
        Set colProcesses = objWMIService.ExecQuery(_
            "Select * from Win32_Process where Name='" & PROC_NAME & "'")
    
        blnProcessTerminated = True
        For Each objProcess In colProcesses
            blnProcessTerminated = False
        Next
    
        WScript.Sleep(SLEEP_INTERVAL_MS)
        intWaited = intWaited + SLEEP_INTERVAL_MS
    Wend


    There's no place like 127.0.0.1

    Saturday, October 31, 2015 3:36 AM

Answers

  • while(1){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    But the installers  will not necessarily have that name.


    \_(ツ)_/

    • Marked as answer by Matt5150 Tuesday, November 3, 2015 12:03 AM
    Monday, November 2, 2015 11:50 PM

All replies

  • I think you should jut put that little ditty back into the box and be happy that it didn't byte you.

    The script does nothing useful outside of what some inexperienced scripter thought was nifty.

    Perhaps you should learn to write a script and write your own script. I recommend using PowerShell since VBScript is almost obsolete.

    Start here: https://technet.microsoft.com/en-us/bb291022.aspx?f=255&MSPPError=-2147217396

    Its free.


    \_(ツ)_/

    Saturday, October 31, 2015 3:55 AM
  • I wish I had the time to learn PowerShell (and VBScript for that mater) inside and out. It would be extremely beneficial in almost every project I work on.  Unfortunately re-purposing scripts I come across on the internet, and slowly building my abilities with each is my only recourse.

    But actually I already wrote something simple in PowerShell but it only got me half-way.

    radskman
    wait-process -name radntfyc

    The radntfyc process starts and stops as it processes each application being installed.  Only breifly, but enough to put a wrench in the works.  So I need to add functionality to it, that causes it to delay the wait-process ending, until 30 seconds have passed, or something similar.  

    Start-Sleep came to mind as the next command to add, then have it loop back to Wait-Process, but 2 problems with that:

    1. If it loops back in between instances of the process running, it ends before it's completed.

    2. If I create a step before the Wait-Process line to check that the process exists first (to prevent a endless loop), still a chance #1 could occur.

    Is there a way to add a delay (that resets if the process starts again) to Wait-Process similar to the -Timeout parameter?

    -Matt



    There's no place like 127.0.0.1

    Saturday, October 31, 2015 6:10 AM
  • Spent some more time on it.  Mostly because the base script I had created wouldn't work with my processes.

    Still have the same problem.  The Radpinit process seems to start and stop frequently, and there is a slight delay before it starts, so I added a pause.  But the Wait-Process still ends as soon as the first instance end.

    $CMD =  'c:\Program Files (x86)\Novadigm\radntfyc.exe'
    $arg1 =  'LOCALHOST'
    $arg2 =  'Radskman.exe'
    $arg3 =  'cat=prompt,ulogon=n,hreboot=y,context=m,mname=radia,dname=SOFTWARE,ip=server.domain.com,port=3464,uid=$MACHINE,startdir=SYSTEM,ind=y,cop=y,log=software_connect.log'
    
    & $CMD $arg1 $arg2 $arg3 | Out-Null
    
    Start-Sleep -Seconds 2
    
    $proc = get-process Radpinit
    wait-process -id $proc.id


    There's no place like 127.0.0.1


    • Edited by Matt5150 Monday, November 2, 2015 11:26 PM Sanitize
    Saturday, October 31, 2015 8:05 AM
  • If you are tryingto mage installer processes you cannot do it by a script.  The installer runs under the system installer service.

    Run: get-service msiserver

    The exe or msi file just causes a call to the installer and gives it the file name and the options then quits. An MSI or setup.exe cn contain many calls to many msi packages embedded within an installer package.  You can only communicate with what is happening by embedding a special script inside the installer process.

    This issue come up repeatedly in this and other forum.  The answer has always been to either create  custom installer or monitor the installer log file.  What you need to monitor for is specific to the installer package you are running. 

    There is really no way short of using the debug API to monitor the installer.


    \_(ツ)_/

    Saturday, October 31, 2015 1:26 PM
  • If you are tryingto mage installer processes you cannot do it by a script.  The installer runs under the system installer service.

    Run: get-service msiserver

    The exe or msi file just causes a call to the installer and gives it the file name and the options then quits. An MSI or setup.exe cn contain many calls to many msi packages embedded within an installer package.  You can only communicate with what is happening by embedding a special script inside the installer process.

    This issue come up repeatedly in this and other forum.  The answer has always been to either create  custom installer or monitor the installer log file.  What you need to monitor for is specific to the installer package you are running. 

    There is really no way short of using the debug API to monitor the installer.


    \_(ツ)_/

    I thought about doing this, but I don't think it will work for my problem. What I'm trying to do, is this:

    I use MDT LiteTouch for Windows Image deployment.

    We use HP (Accelerate) Radia for software distribution.

    I'm trying to add a Task toward the end of my Task Sequence that will run a local command, that prompts the Radia Software Manager client to call to the server and install any applications entitled to it.

    These applications can be anything from MSI's, EXE's, BAT files, simple file drops, you name it.

    The only constant, is that when each "package" is being delivered and executed, a process named "RADNTFYC.EXE" is running.

    What I am attempting to do, is find / write a script that will launch this local command line, and monitor "RADNTFYC.EXE", preventing that script from closing, which will in turn let LiteTouch know the Task is still running, and not to continue to the next task.

    Originally I used to run this at the very end, that way it didn't butt heads with anything, but I now have deal with McAfee EPO doing something very similar, and due to a war I lost with our InfoSec folks I have to work around McAfee.  (And so far with McAfee I haven't been able to identify a common process that runs only when components are installing.)

    I'm not asking for anyone to write this for me, just a nudge in the right direction would be very helpful.

    Thanks!

    -Matt


    There's no place like 127.0.0.1

    Monday, November 2, 2015 6:08 PM
  • Well. You are out of luck.  Contact HP to see if they have an API that will let you monitor to process.  I bet they do.


    \_(ツ)_/

    Monday, November 2, 2015 6:57 PM
  • HP was the first place I started.  Thanks for talking a look, jrv.

    Anyone else got any ideas?

    Thanks,

    -Matt


    There's no place like 127.0.0.1

    Monday, November 2, 2015 8:07 PM
  • Anyone else got any ideas?

    Sorry, but this forum is for answering specific scripting questions rather than writing script solutions.

    A big part of what you need to do is to write a rigorously specific technical problem definition. Only then will you be able to write code to solve the problem.

    If this is critical to your business, you will probably need to hire a consultant.


    -- Bill Stewart [Bill_Stewart]

    Monday, November 2, 2015 11:03 PM
    Moderator
  • Hi Bill, my specific question is: 

    Is there a cmdlet or known function / example that will watch for a running process with some kind of dwell time.  Dwell time, meaning it will wait a defined number of seconds for the process after it has ended to make sure it doesn't start back up. If it reoccurs during that time period, it checks again after it's ended, and so on.  I'm assuming a loop function would be needed but I can't find a way to delay Wait-Process, know of a similar cmdlet that would work in this case.  Looping Wait-Process and Start-Sleep with a retry count if result is equal to "can't find process" was my other idea.  Not ideal but would narrow the margin of error.

    I'm not asking for anyone to write a free script for me.  If anyone knows of something like this being done and has a example they can point me to, great!

    If it's known not to be possible, fine, I stop spinning my wheels on this.

    If you know it's possible, but know it will require heavy scripting that your not about to provide for free (kind of what I'm getting from your post), I get it.

    Just let me know. From that point I can proceed or move on.

    -Matt


    There's no place like 127.0.0.1

    Monday, November 2, 2015 11:23 PM
  • If you are tryingto mage installer processes you cannot do it by a script.  The installer runs under the system installer service.

    Run: get-service msiserver

    The exe or msi file just causes a call to the installer and gives it the file name and the options then quits. An MSI or setup.exe cn contain many calls to many msi packages embedded within an installer package.  You can only communicate with what is happening by embedding a special script inside the installer process.

    This issue come up repeatedly in this and other forum.  The answer has always been to either create  custom installer or monitor the installer log file.  What you need to monitor for is specific to the installer package you are running. 

    There is really no way short of using the debug API to monitor the installer.


    \_(ツ)_/

    I apologize, jrv.  I completely misread your response.  I didn't catch the part where you stated this has been tried times before and no solution was found.  That does change things.

    -Matt


    There's no place like 127.0.0.1

    Monday, November 2, 2015 11:28 PM
  • In a compiled program you can use the debug API to do many things.

    As Bill has pointed out you have not defined your technical requirements.  Without that it will be hardd  to find or even guess at an answer.


    \_(ツ)_/

    Monday, November 2, 2015 11:30 PM
  • Maybe I'm misunderstanding what you mean by technical requirements, but I'll retry:

    I want to write a script that will:

    1. Launch our Radia Notification command: "c:\Program Files (x86)\Novadigm\radntfyc.exe" with arguments.
    2. Wait 3 seconds for the spawned process, "radpinit.exe" to start.
    3. Detect or discover this spawned process and keep the script open 60 seconds after the initial, and any subsequent instances of this named process have ended.  
    4. If no instances of the named process have occurred during that 60 seconds, end the script.

    -Matt


    There's no place like 127.0.0.1

    Monday, November 2, 2015 11:41 PM
  • while(1){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    But the installers  will not necessarily have that name.


    \_(ツ)_/

    • Marked as answer by Matt5150 Tuesday, November 3, 2015 12:03 AM
    Monday, November 2, 2015 11:50 PM
  • while(1){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    But the installers  will not necessarily have that name.


    \_(ツ)_/

    Ha!  That's so elegant!  I love it, I'll give it a go.

    That shouldn't be a problem, as this particular installer tool seems to have an instance of RADPINIT.exe open for the duration of each and every package, no mater the type or installer method.

    Thanks!

    -Matt


    There's no place like 127.0.0.1

    Monday, November 2, 2015 11:54 PM
  • while(1){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    But the installers  will not necessarily have that name.


    \_(ツ)_/

    That worked perfectly!  Thanks a bunch! And it's so simple I'm banging my head a bit because I didn't consider it.

    Tested Script:

    $CMD =  'c:\Program Files (x86)\Novadigm\radntfyc.exe'
    $arg1 =  'LOCALHOST'
    $arg2 =  'Radskman.exe'
    $arg3 =  'cat=prompt,ulogon=n,hreboot=y,context=m,mname=radia,dname=SOFTWARE,ip=server.domain.com,port=3464,uid=$MACHINE,startdir=SYSTEM,ind=y,cop=y,log=software_connect.log'
    
    & $CMD $arg1 $arg2 $arg3 | Out-Null
    
    Start-Sleep -Seconds 2
    
    while(1){ 
         if(Get-process Radpinit){sleep 60}else{exit}
    }


    There's no place like 127.0.0.1

    Tuesday, November 3, 2015 12:04 AM
  • When we can clearly state the desired outcome the answers can be easy to find.

    \_(ツ)_/

    Tuesday, November 3, 2015 12:20 AM
  • while(1){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    But the installers  will not necessarily have that name.


    \_(ツ)_/

    Is there a simple way to get this to retry "x" amount of times?

    There's no place like 127.0.0.1

    Thursday, November 5, 2015 1:49 AM
  • while(1){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    But the installers  will not necessarily have that name.


    \_(ツ)_/

    Is there a simple way to get this to retry "x" amount of times?

    There's no place like 127.0.0.1

    for($x=1;$x -le 10;$x++){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    \_(ツ)_/

    Thursday, November 5, 2015 4:25 AM

  • for($x=1;$x -le 10;$x++){
         if(Get-process radpinit){sleep 60}else{exit}
    }

    \_(ツ)_/

    That looked like complete Greek at first!  But I think I understand it now.

    First script sample would look for the process, if it existed, it would wait 60 seconds and try again, infinitely.  If it wasn't found it would exit.

    Second script sample will look for the process, if it finds it it will wait 60, then try again only $x amount of times.  If it wasn't found running, it will exit.

    I remembered last night, that PowerShell doesn't process scripts chronologically.  What I'm finding during testing is that first the FOR or WHILE loop will begin, then my $CMD, then the "Sleep 5"

    & $CMD $arg1 $arg2 $arg3
    
    Sleep 5
    
    for($x=1;$x -le 10;$x++){ 
         if(Get-Process radpinit){sleep 60}else{exit}


    That results in "Get-Process" not ever seeing "Radpinit", since it hasn't started yet.  I'm going to do some more research on script assembly and process flow. I really want to understand better how this works.

    Secondly, even after Radpinit has started, it will stop briefly (second or less) as a package completes, and restart when the next package install begins.  Kind of like a 4 year old playing with a light switch....

    I was researching the heck out of "Do" "For" "While" loops last night, and was having trouble finding information on the different conditions that could be supplied to each. I found some examples similar to what I'm trying to do, but most of them had a page of code to do what you just did in a few characters! :)  

    This is where my idea of having the While loop, "in a loop" came from.  But I realize I wasn't clear on that, at all.

    Revised Technical Requirements:

    1. Launch our Radia Notification command:

    "c:\Program Files (x86)\Novadigm\radntfyc.exe" with arguments.

    2. Wait 3 seconds for the spawned process, "radpinit.exe" to start.

    3. Detect or discover this spawned process and keep the script open 60 seconds after the

    initial, and any subsequent instances of this named process have ended.

    4. If no instance of the named process is found, wait 60, add retry increment and return

    to step 3 for 3 retries.

    5. At the end of the 3rd retry if the process is not found running, end the script.



    Anyway, thanks a lot for your help.  You've definitely got me on the right track and I now know this is possible.  I just need more time / practice / education :).

    -Matt


    There's no place like 127.0.0.1



    • Edited by Matt5150 Thursday, November 5, 2015 6:45 PM Format
    Thursday, November 5, 2015 6:42 PM
  • It is worth learning the more technical aspects of Windows but it takes time and a lot of reading.

    \_(ツ)_/

    Thursday, November 5, 2015 7:54 PM