Hi Guys,

I am trying to install Matlab 2016a silent through -inputfile switch. But I found that process doesn't wait when I try to run in vbscript through oshell.Run("setup.exe and parameter",0,True).
Can anyone help me how to handle the wait for this setup.exe till the execution is finished.

Thanks in advance.
1 Comment   [ + ] Show Comment

Comments

  • Is there a particular reason that you are using a VBScript and not a batch file?
Please log in to comment

Answers

0

Here's some stuff I had lying around...I've not used it in ages but, as far as I can recall, it ran just fine.

'// Watch (via event subscription) a shelled process and cancel it if it is still running after intintMaxTime
'// Writes a log file to watchproc.log
'// Will optionally kill the shelled process if it does not complete in x seconds.
'// Useful for environments where machines may not be consistently available.

Option Explicit

Dim strScriptName
Dim strScriptFullName
Dim strMsg
Dim objWshShell
Dim objWMIService
Dim objEventSink
Dim colProcess
Dim objProcess
Dim lngProcessID
Dim blnProcessTerminated
Dim objFSO
Dim objLogFile
Dim intCounter
Dim strQuery
Dim strPath   
Dim strName
Dim strArguments
Dim intMaxTime
Dim blnFileExists

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Constants for opening files
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Const intOpenFileForReading  = 1
Const intOpenFileForWriting  = 2
Const intOpenFileForAppending  = 8

strScriptName   = WScript.ScriptName
strScriptFullName  = WScript.ScriptFullName

'// Get input parameters
If WScript.Arguments.Count = 0 Or WScript.Arguments.Count < 3 Then
 '// Script was run without arguments or too few arguments
 strMsg   = ""
 strMsg   = strMsg & "Usage:" & vbCRLF
 strMsg   = strMsg & "You must specify:" & vbCRLF
 strMsg   = strMsg & vbTAB & "the path to the script/program to be run," & vbCRLF
 strMsg   = strMsg & vbTAB & "the name of the script/program to be run" & vbCRLF
 strMsg   = strMsg & vbTAB & "and, optionally, any arguments for the script/program to be run:" & vbCRLF & vbCRLF
 strMsg   = strMsg & "Cscript " & strScriptFullName & " <path to script/exe to be run> <name of script/exe to be run> <script/exe arguments>" & vbCRLF
 MsgBox strMsg
 WScript.Quit(False)
Else
 strPath   = WScript.Arguments(0) '// Path to script
 strName   = WScript.Arguments(1) '// Name of script
 intMaxTime  = WScript.Arguments(2) '// Nbr of seconds to wait
 
 If WScript.Arguments.Count > 3 Then
  strArguments  = WScript.Arguments(3) '// Arguments to pass to script
 End If
 strMsg   = strPath & " " & strName & strArguments
End If

Set objWshShell   = CreateObject("WScript.Shell")
Set objFSO   = CreateObject("Scripting.FilesystemObject")
Set objLogFile   = objFSO.OpenTextFile(strScriptName & ".log", intOpenFileForAppending, True)

objLogFile.Write "Passed arguments: " & strMsg & vbCRLF
objLogFile.Write vbCRLF & Now() & strScriptName & " started." & vbCRLF

'// Initialise WMI
objLogFile.Write Now() & " Binding to WMI." & vbCRLF
Set objWMIService   = GetObject("WINMGMTS:{impersonationLevel=impersonate,(Security)}!\\.\ROOT\CIMV2")

'// Create the Event Notification Sink
objLogFile.Write Now() & " Creating event sink." & vbCRLF
Set objEventSink   = CreateObject("WbemScripting.SWbemSink")

objLogFile.Write Now() & " Connecting to event sink." & vbCRLF
WScript.ConnectObject objEventSink,"EVENTSINK_"

blnProcessTerminated  = False
blnFileExists   = False
strMsg = Now()

With objFSO
 If .FolderExists(strPath) Then
  If .FileExists(strPath & "\" & strName) Then
   blnFileExists = True
   strMsg = strMsg & "Launching " & strPath & "\" & strName & " " & strArguments & vbCRLF
   If Len(strArguments) > 0 Then
    Call ProcessLaunch(strPath & "\" & strName & " " & strArguments, strPath)
   Else
    Call ProcessLaunch(strPath & "\" & strName, strPath)
   End If
  Else
   strMsg = strMsg & "File " & strName & " not found in " & strPath & vbCRLF
  End If
 Else
  strMsg = strMsg & "Folder " & strPath & " not found" & vbCRLF
 End If
 
 objLogFile.Write strMsg
 
End With

If blnFileExists Then
 intCounter   = 0

 Do While blnProcessTerminated = False
  intCounter  = intCounter + 1
  'objLogFile.Write "Sleeping for " & intMaxTime/1000 & " seconds." & vbCRLF
  WScript.Sleep 1000
  If intCounter > intMaxTime Then
   Call KillProcess(lngProcessID)
  End If
 Loop
End If

'**************************************************************
Sub ProcessLaunch(ByVal strProcessName, ByVal strProcessPath)
 Dim objProcess
 Dim objStartup
 Dim objConfig
 Dim lngReturn
 
 Const intSW_HIDE  = 0  '// Hides the window and activates another window.
 Const intSW_NORMAL  = 1  '// Activates and displays a window.
      '// If the window is minimised or maximised, the system restores it to the original size and position.
      '// An application specifies this flag when displaying the window for the first time.
 Const intSW_SHOWMINIMIZED = 2  '// Activates the window, and displays it as a minimised window.
 Const intSW_SHOWMAXIMIZED = 3  '// Activates the window, and displays it as a maximised window.
 Const intSW_SHOWNOACTIVATE = 4  '// Displays a window in its most recent size and position.
      '// This value is similar to SW_SHOWNORMAL, except that the window is not activated.
 Const intSW_SHOW  = 5  '// Activates the window, and displays it at the current size and position.
 Const intSW_MINIMIZE  = 6  '// Minimises the specified window, and activates the next top level window in the Z order.
 Const intSW_SHOWMINNOACTIVE = 7  '// Displays the window as a minimised window. This value is similar to SW_SHOWMINIMZED,
      '// except that the window is not activated.
 Const intSW_SHOWNA  = 8  '// Displays the window at the current size and position. This value is similar to SW_SHOW,
      '// except that the window is not activated.
 Const intSW_RESTORE  = 9  '// Activates and displays the window. If the window is minimised or maximised, the system
      '// restores it to the=original size and position. An application specifies this flag when
      '// restoring a minimised window.
 Const intSW_SHOWDEFAULT  = 10  '// Sets the show state based on the SW_ value that is specified in the STARTUPINFO structure
      '// passed to the CreateProcess function by the program that starts the application.
 Const intSW_FORCEMINIMIZE = 11 '// Windows Server 2003, Windows 2000, and Windows XP: 
      '// Minimises a window, even when the thread that owns the window is hung.
      '// Only use this flag when minimising windows from a different thread.

 Set objStartup   = objWMIService.Get("Win32_ProcessStartup")
 Set objConfig   = objStartup.SpawnInstance_
 objConfig.ShowWindow  = intSW_NORMAL
 
 Set objProcess   = objWMIService.Get("Win32_Process")

 'Err.Clear
 lngReturn  = objProcess.Create(strProcessPath & "\" & strProcessName, strProcessPath, objConfig, lngID)

 If lngReturn = 0 Then
  strMsg  = strProcessName & " PID:" & lngProcessID & " created." & vbCRLF
  objLogFile.Write strMsg
 Else
  strMsg  = "Failed to launch " & strProcessName & vbCRLF
  strMsg  = strMsg & "Error " & lngReturn & ":"
  Select Case lngReturn
   Case 2  
    strMsg  = strMsg & "Access denied."
   Case 3  
    strMsg  = strMsg & "Insufficient privilege."
   Case 8  
    strMsg  = strMsg & "Unknown failure."
   Case 9  
    strMsg  = strMsg & "Path not found."
   Case 21  
    strMsg  = strMsg & "Invalid parameter."
  End Select
  
  objLogFile.Write strMsg
  Exit Sub
 End If

 Call WatchProcess(lngProcessID)
End Sub
 
'**************************************************************
Sub KillProcess(ByVal lngProcessID)

 strQuery    = ""
 strQuery    = strQuery & "SELECT "
 strQuery    = strQuery & "* "
 strQuery    = strQuery & "FROM "
 strQuery    = strQuery & "Win32_Process "
 strQuery    = strQuery & "WHERE "
 strQuery    = strQuery & "ProcessID="
 strQuery    = strQuery & lngID
 
 Set colProcess    = objWMIService.ExecQuery(strQuery)

 If colProcess.Count <> 0 Then
  For Each objProcess In colProcess
   objProcess.Terminate()
   objLogFile.Write "Process " & lngProcessID & " timed out " & Now() & vbCRLF
   objEventSink.Cancel()
   blnProcessTerminated=True 
  Next 
 End If 
End Sub

'**************************************************************
Sub WatchProcess(ByVal lngProcessID)

 strQuery    = ""
 strQuery    = strQuery & "SELECT "
 strQuery    = strQuery & "* "
 strQuery    = strQuery & "FROM "
 strQuery    = strQuery & "__InstanceOperationEvent "
 strQuery    = strQuery & "WITHIN 1 "
 strQuery    = strQuery & "WHERE "
 strQuery    = strQuery & "TargetInstance "
 strQuery    = strQuery & "ISA "
 strQuery    = strQuery & "'Win32_Process' "
 strQuery    = strQuery & "AND "
 strQuery    = strQuery & "TargetInstance.ProcessID='"
 strQuery    = strQuery & lngID & "'"

 objWMIService.ExecNotificationQueryAsync objEventSink, strQuery 
End Sub

'**************************************************************
Sub EVENTSINK_OnObjectReady(objInstance, objAsyncContext)

 If objInstance.Path_.Class = "__InstanceDeletionEvent" Then
  strMsg    = "Process " & objInstance.TargetInstance.ProcessID & " terminated at " & Now() & vbCRLF
  objLogFile.Write strMsg
  
  objEventSink.Cancel()
  blnProcessTerminated  = True
  WScript.Quit 
 End If 
 
End Sub

Sub EVENTSINK_OnCompleted(objInstance, objAsyncContext)
   
 strMsg    = "ExecQueryAsync completed"
 objLogFile.Write strMsg
 blnProcessTerminated  = True
   
End Sub

Answered 05/18/2016 by: VBScab
Red Belt

Please log in to comment
Answer this question or Comment on this question for clarity