Difference between revisions of "Matlab"

From WPKG | Open Source Software Deployment and Distribution
Jump to: navigation, search
Line 4: Line 4:
 
Silent installer for Matlab 2010b.  Simply using the command line to run the Matlab provided setup.exe along with the argument -inputfile followed by a preconfigured input file containing your license key, silent install option etc, just won't work.  It seems that when the setup.exe is run, it spawns a new setup.exe (with another pid), the original setup.exe then exits, wpkg then sees this exit, tries to check the program has installed ok and fails.  Meanwhile, the spawned setup.exe continues and installs Matlab.   
 
Silent installer for Matlab 2010b.  Simply using the command line to run the Matlab provided setup.exe along with the argument -inputfile followed by a preconfigured input file containing your license key, silent install option etc, just won't work.  It seems that when the setup.exe is run, it spawns a new setup.exe (with another pid), the original setup.exe then exits, wpkg then sees this exit, tries to check the program has installed ok and fails.  Meanwhile, the spawned setup.exe continues and installs Matlab.   
  
To get around this, an Autoit script was written that is passed two arguments.  The first one is the path to the setup.exe program, the second is the path to the input file.  After setup.exe is started, a small sleep allows the spawned setup.exe to start.  All the processes called 'setup.exe' are then searched for along with the command they are running.  If one of the setup.exe's commands contain the string 'matlab', then this PID is obtained.  In a While loop, the existance of this PID is checked, if it still exists, sleep, then re-check.  If the PID doesn't exist, close the autoit exe, it is at this point that the install of Matlab would of finished and it is only now do we return pack the WPLG XML that will go and check the install has succeeded/failed.   
+
To get around this, an Autoit script was written that is passed 4 arguments.  The first one is the path to the setup.exe program.  The second is the argument required to read in a log file.  For Matlab this is '-inputfile'.  The third is the path to the input file.  The fourth is the time in seconds after which you want monitoring to start, give the 'real' setup.exe time to start.  All the processes called 'setup.exe' are then searched for along with the command they are running.  If one of the setup.exe's commands contain the string of the third argument, the config file, then its PID is obtained.  In a While loop, the existance of this PID is checked, if it still exists, sleep, then re-check.  If the PID doesn't exist, close the autoit exe, it is at this point that the install of Matlab would of finished and it is only now do we return pack the WPLG XML that will go and check the install has succeeded/failed.   
  
 
Passing the arguments to the Autoit script allows multiple licensed toolboxes to be installed.
 
Passing the arguments to the Autoit script allows multiple licensed toolboxes to be installed.
 
To remove Matlab and/or Matlab toolboxes, you can't simply run the documented command line:
 
 
<pre>
 
"%SYSTEMDRIVE%\matlab-%version%\uninstall\bin\win32\uninstall.exe" -inputfile "%SOFTWARE%\math_progs\\matlab_2010b_uninstaller_input.txt"
 
</pre>
 
 
If you do, the uninstall.exe program will start, launch the uninstall gui (hidden from view of course so you've no idea what's going on) and sit there.  To 'make it work', create a very simple batch file that accepts two arguments, one, the path the the uninstall.exe and the second, the path to the input file (copy of this input file is in {path to matlab}\uninstall\).  Run this batch file as the <remove>.
 
  
 
<source lang="xml">
 
<source lang="xml">
Line 45: Line 37:
 
<pre>
 
<pre>
 
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
 
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=icon.ico
 
 
#AutoIt3Wrapper_Outfile=matlab_install_wpkg.exe
 
#AutoIt3Wrapper_Outfile=matlab_install_wpkg.exe
 
#AutoIt3Wrapper_Change2CUI=y
 
#AutoIt3Wrapper_Change2CUI=y
Line 65: Line 56:
  
 
If @Compiled = 1 Then
 
If @Compiled = 1 Then
If $CmdLine[0] < 2 Then
+
If $CmdLine[0] < 4 Then
MsgBox(32, "Usage", "Usage:" & @CRLF & @CRLF & @ScriptName & " (path to Matlab setup.exe program) (path to config file)" & @CRLF & @CRLF _
+
MsgBox(32, "Usage", "KeepAlive WPKG Installer Usage:" & @CRLF & @CRLF & "For some installers (Java based), a program setup " & _
& "E.g. " & @ScriptName & " %LOGONSERVER%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab-2010b\setup.exe %LOGONSERVER%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab_2010b_input.txt" & _
+
"program exits before the install has finished.  This program stops the premature exiting until the installer " & _
@CRLF & @CRLF & "C. Mortimer 2011")
+
"has finished.  It does this by monitoring the PID of the installer and only exiting when the installer has finished.  Useful " & _
 +
"when installing a program with WPKG." & @CRLF & @CRLF & @ScriptName & " (path to programs' install program) (argument " & _
 +
"needed to include config file) (path to config file)  (time in seconds to wait before monitoring installer)" & @CRLF & _
 +
@CRLF & "E.g. " & @ScriptName & " %LOGONSERVER%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab-2010b\setup.exe " & _
 +
"-inputFile  %LOGONSERVER%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab_2010b_input.txt 5" & @CRLF & @CRLF & _
 +
"This script creates a log file in the users running this scripts Temp dir called {exe of 1st argument}_install.log" & @CRLF & @CRLF _
 +
& "C. Mortimer 2011", 30)
 
Exit
 
Exit
 
Else
 
Else
 
$install_prog = $CmdLine[1]
 
$install_prog = $CmdLine[1]
$config_file = $CmdLine[2]
+
$call_argument_wth = $CmdLine[2]
 +
$config_file = $CmdLine[3]
 +
$wait_time = $CmdLine[4] * 1000
 
EndIf
 
EndIf
 
Else
 
Else
;~ $install_prog = "\\winsam\netlogon\scripts\ssh_key.reg"
+
Exit ; not really going to be run without compiling it
;~ $install_prog = "\\winsam\netlogon\scripts\ssh_key_byhost"
+
 
EndIf
 
EndIf
  
$run_install = Run($install_prog & " -inputFile " & $config_file)
+
$q = 1
 +
$process_name = StringTrimLeft($install_prog, StringInStr($install_prog, "\", 0, -1))
  
$log = FileOpen(EnvGet("temp") & "\matlab_running", 2)
+
$run_install = Run($install_prog & " " & $call_argument_wth & " " & $config_file) ; Run the installer...
FileWriteLine($log, "Now starting.  Program to run = '" & $install_prog & "', config = '" & $config_file & "'.  [PID = " & $run_install & "] [" & @HOUR & ":" & @MIN & ":" & @SEC & "]")
+
  
Sleep(5000)
+
$log = FileOpen(EnvGet("temp") & "\" & $process_name & "_install.log", 2) ; Open the log file deleting all existing data
 +
FileWriteLine($log, "Now starting.  Program to run = '" & $install_prog & "', argument required to call in config file ='" & $call_argument_wth & "'," & @CRLF & "config file = '" & $config_file & "', search string = '" & $install_prog & "', wait before monitoring = '" & $wait_time / 1000 & "s'.  [PID = " & $run_install & "] [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")
 +
FileClose($log)
  
$q = 1
+
Sleep($wait_time)
$process_name = "setup.exe"
+
  
 
While $q = 1
 
While $q = 1
$log = FileOpen(EnvGet("temp") & "\matlab_running", 1)
+
$log = FileOpen(EnvGet("temp") & "\" & $process_name & "_install.log", 1) ; append to the log file
 
$avRET = _ProcessListProperties($process_name)
 
$avRET = _ProcessListProperties($process_name)
$array_search = _ArraySearch($avRET, "matlab", "", "", 0, 1)
+
$array_search = _ArraySearch($avRET, $call_argument_wth, "", "", 0, 1)
;~ FileWriteLine($log, "$array_search = " & $array_search)
+
 
If $array_search >= 0 Then
 
If $array_search >= 0 Then
FileWriteLine($log, "Setup still running... [PID = " & $avRET[$array_search][1] & "] [" & @HOUR & ":" & @MIN & ":" & @SEC & "]")
+
FileWriteLine($log, $process_name & " still running... [PID = " & $avRET[$array_search][1] & "] [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")
 
FileClose($log)
 
FileClose($log)
 
Else
 
Else
FileWriteLine($log, "Now exiting, " & $process_name & " no long running. [" & @HOUR & ":" & @MIN & ":" & @SEC & "]")
+
FileWriteLine($log, "Now exiting, " & $process_name & " no long running. [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")
 
FileClose($log)
 
FileClose($log)
 
$q = 2
 
$q = 2
Line 237: Line 235:
 
</pre>
 
</pre>
  
==Remove bat file==
+
===Removal of Matlab===
 +
 
 +
To remove Matlab and/or Matlab toolboxes, you can't simply run the documented command line:
 +
 
 +
<pre>
 +
"%SYSTEMDRIVE%\matlab-%version%\uninstall\bin\win32\uninstall.exe" -inputfile "%SOFTWARE%\math_progs\\matlab_2010b_uninstaller_input.txt"
 +
</pre>
 +
 
 +
If you do, the uninstall.exe program will start, launch the uninstall gui (hidden from view of course so you've no idea what's going on) and sit there.  To 'make it work', create a very simple batch file that accepts two arguments, one, the path the the uninstall.exe and the second, the path to the input file (copy of this input file is in {path to matlab}\uninstall\).  Run this batch file as the <remove>.
  
 
<pre>
 
<pre>

Revision as of 08:32, 15 April 2011

Matlab

Silent installer for Matlab 2010b. Simply using the command line to run the Matlab provided setup.exe along with the argument -inputfile followed by a preconfigured input file containing your license key, silent install option etc, just won't work. It seems that when the setup.exe is run, it spawns a new setup.exe (with another pid), the original setup.exe then exits, wpkg then sees this exit, tries to check the program has installed ok and fails. Meanwhile, the spawned setup.exe continues and installs Matlab.

To get around this, an Autoit script was written that is passed 4 arguments. The first one is the path to the setup.exe program. The second is the argument required to read in a log file. For Matlab this is '-inputfile'. The third is the path to the input file. The fourth is the time in seconds after which you want monitoring to start, give the 'real' setup.exe time to start. All the processes called 'setup.exe' are then searched for along with the command they are running. If one of the setup.exe's commands contain the string of the third argument, the config file, then its PID is obtained. In a While loop, the existance of this PID is checked, if it still exists, sleep, then re-check. If the PID doesn't exist, close the autoit exe, it is at this point that the install of Matlab would of finished and it is only now do we return pack the WPLG XML that will go and check the install has succeeded/failed.

Passing the arguments to the Autoit script allows multiple licensed toolboxes to be installed.

<?xml version="1.0" encoding="UTF-8"?>
<packages>

<package id="matlab-main" name="Matlab R2010b - Main" revision="1.1" priority="15"  >
	<variable name="version" value="R2010b" />
	<variable name="domain" value="MATHS" />
 
	<check type="uninstall" condition="exists" path="MATLAB %version%" />
	
	<install cmd='%COMSPEC% /c if not exist c:\temp\ mkdir c:\temp' />	<!-- used for the matlab logs -->
	<install cmd='%COMSPEC% /c start "" /wait "\\%DOMAIN%\netlogon\scripts\matlab\matlab_install_wpkg.exe" "\\%DOMAIN%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab-2010b\setup.exe" "%SOFTWARE%\math_progs\matlab_2010b_input.txt"' />
	
	<upgrade cmd='%COMSPEC% /c start "" /wait 2\\%DOMAIN%\netlogon\scripts\matlab\matlab_install_wpkg.exe" "\\%DOMAIN%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab-2010b\setup.exe" "%SOFTWARE%\math_progs\matlab_2010b_input.txt"' />
	
	<remove cmd='%COMSPEC% /C if exist "%SYSTEMDRIVE%\matlab-%version%\uninstall\bin\win32\uninstall.exe" "%SOFTWARE%\math_progs\matlab_uninstall.bat" "%SYSTEMDRIVE%\matlab-%version%\uninstall\bin\win32\uninstall.exe" "%SOFTWARE%\math_progs\\matlab_2010b_uninstaller_input.txt"' />
	<remove cmd='%COMSPEC% /c rd /s /q "%SYSTEMDRIVE%\matlab-%version%"'>
		<exit code='any' />
	</remove>
	
</package>

</packages>

Autoit code. Compile this into an exe

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=matlab_install_wpkg.exe
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <File.au3>
#include <Array.au3>
#include <Date.au3>

; Script to start the Matlab install and keep alive until the setup.exe program finishes.  This script is used by the Matlab WPKG program.
; It's not as simple as making sure the process setup.exe is still running as there may already be a process running called setup.exe.  We need
; to look for the one that has the string matlab in the processes execute command line.  To make things harder, the matlab setup.exe seems to
; start with one pid for the exe, this then seems to spawn a new setup.exe with another pid so we can't simple launch the original setup.exe, note
; its pid and then keep an eye on it, we need to keep looking for the pid for the process setup.exe with the string matlab in the execute command.
; This is where the function _ProcessListProperties (http://www.autoitscript.com/forum/topic/70538-processlistproperties/) is used.

; C. Mortimer April 2011

Opt("TrayMenuMode", 1) ; Default tray menu items (Script Paused/Exit) will not be shown.

If @Compiled = 1 Then
	If $CmdLine[0] < 4 Then
		MsgBox(32, "Usage", "KeepAlive WPKG Installer Usage:" & @CRLF & @CRLF & "For some installers (Java based), a program setup " & _
				"program exits before the install has finished.  This program stops the premature exiting until the installer " & _
				"has finished.  It does this by monitoring the PID of the installer and only exiting when the installer has finished.  Useful " & _
				"when installing a program with WPKG." & @CRLF & @CRLF & @ScriptName & " (path to programs' install program) (argument " & _
				"needed to include config file) (path to config file)  (time in seconds to wait before monitoring installer)" & @CRLF & _
				@CRLF & "E.g. " & @ScriptName & "  %LOGONSERVER%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab-2010b\setup.exe  " & _
				"-inputFile  %LOGONSERVER%\wpkg7\server\WPKG-1.1.2\programs\math_progs\matlab_2010b_input.txt  5" & @CRLF & @CRLF & _
				"This script creates a log file in the users running this scripts Temp dir called {exe of 1st argument}_install.log" & @CRLF & @CRLF _
				 & "C. Mortimer 2011", 30)
		Exit
	Else
		$install_prog = $CmdLine[1]
		$call_argument_wth = $CmdLine[2]
		$config_file = $CmdLine[3]
		$wait_time = $CmdLine[4] * 1000
	EndIf
Else
	Exit ; not really going to be run without compiling it
EndIf

$q = 1
$process_name = StringTrimLeft($install_prog, StringInStr($install_prog, "\", 0, -1))

$run_install = Run($install_prog & " " & $call_argument_wth & " " & $config_file) ; Run the installer...

$log = FileOpen(EnvGet("temp") & "\" & $process_name & "_install.log", 2) ; Open the log file deleting all existing data
FileWriteLine($log, "Now starting.  Program to run = '" & $install_prog & "', argument required to call in config file ='" & $call_argument_wth & "'," & @CRLF & "config file = '" & $config_file & "', search string = '" & $install_prog & "', wait before monitoring = '" & $wait_time / 1000 & "s'.  [PID = " & $run_install & "] [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")
FileClose($log)

Sleep($wait_time)

While $q = 1
	$log = FileOpen(EnvGet("temp") & "\" & $process_name & "_install.log", 1) ; append to the log file
	$avRET = _ProcessListProperties($process_name)
	$array_search = _ArraySearch($avRET, $call_argument_wth, "", "", 0, 1)
	If $array_search >= 0 Then
		FileWriteLine($log, $process_name & " still running... [PID = " & $avRET[$array_search][1] & "] [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")
		FileClose($log)
	Else
		FileWriteLine($log, "Now exiting, " & $process_name & " no long running. [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")
		FileClose($log)
		$q = 2
	EndIf
	Sleep(5000)
WEnd
Exit


;===============================================================================
; Function Name:    _ProcessListProperties()
; Description:   Get various properties of a process, or all processes
; Call With:       _ProcessListProperties( [$Process [, $sComputer]] )
; Parameter(s):  (optional) $Process - PID or name of a process, default is "" (all)
;          (optional) $sComputer - remote computer to get list from, default is local
; Requirement(s):   AutoIt v3.2.4.9+
; Return Value(s):  On Success - Returns a 2D array of processes, as in ProcessList()
;            with additional columns added:
;            [0][0] - Number of processes listed (can be 0 if no matches found)
;            [1][0] - 1st process name
;            [1][1] - 1st process PID
;            [1][2] - 1st process Parent PID
;            [1][3] - 1st process owner
;            [1][4] - 1st process priority (0 = low, 31 = high)
;            [1][5] - 1st process executable path
;            [1][6] - 1st process CPU usage
;            [1][7] - 1st process memory usage
;            [1][8] - 1st process creation date/time = "MM/DD/YYY hh:mm:ss" (hh = 00 to 23)
;            [1][9] - 1st process command line string
;            ...
;            [n][0] thru [n][9] - last process properties
; On Failure:      Returns array with [0][0] = 0 and sets @Error to non-zero (see code below)
; Author(s):        PsaltyDS at http://www.autoitscript.com/forum
; Date/Version:   12/01/2009  --  v2.0.4
; Notes:            If an integer PID or string process name is provided and no match is found,
;            then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList)
;          This function requires admin permissions to the target computer.
;          All properties come from the Win32_Process class in WMI.
;            To get time-base properties (CPU and Memory usage), a 100ms SWbemRefresher is used.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
	Local $sUserName, $sMsg, $sUserDomain, $avProcs, $dtmDate
	Local $avProcs[1][2] = [[0, ""]], $n = 1

	; Convert PID if passed as string
	If StringIsInt($Process) Then $Process = Int($Process)

	; Connect to WMI and get process objects
	$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy, (Debug)}!\\" & $sComputer & "\root\cimv2")
	If IsObj($oWMI) Then
		; Get collection processes from Win32_Process
		If $Process == "" Then
			; Get all
			$colProcs = $oWMI.ExecQuery("select * from win32_process")
		ElseIf IsInt($Process) Then
			; Get by PID
			$colProcs = $oWMI.ExecQuery("select * from win32_process where ProcessId = " & $Process)
		Else
			; Get by Name
			$colProcs = $oWMI.ExecQuery("select * from win32_process where Name = '" & $Process & "'")
		EndIf

		If IsObj($colProcs) Then
			; Return for no matches
			If $colProcs.count = 0 Then Return $avProcs

			; Size the array
			ReDim $avProcs[$colProcs.count + 1][10]
			$avProcs[0][0] = UBound($avProcs) - 1

			; For each process...
			For $oProc In $colProcs
				; [n][0] = Process name
				$avProcs[$n][0] = $oProc.name
				; [n][1] = Process PID
				$avProcs[$n][1] = $oProc.ProcessId
				; [n][2] = Parent PID
				$avProcs[$n][2] = $oProc.ParentProcessId
				; [n][3] = Owner
				If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName
				; [n][4] = Priority
				$avProcs[$n][4] = $oProc.Priority
				; [n][5] = Executable path
				$avProcs[$n][5] = $oProc.ExecutablePath
				; [n][8] = Creation date/time
				$dtmDate = $oProc.CreationDate
				If $dtmDate <> "" Then
					; Back referencing RegExp pattern from weaponx
					Local $sRegExpPatt = "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)"
					$dtmDate = StringRegExpReplace($dtmDate, $sRegExpPatt, "$2/$3/$1 $4:$5:$6")
				EndIf
				$avProcs[$n][8] = $dtmDate
				; [n][9] = Command line string
				$avProcs[$n][9] = $oProc.CommandLine

				; increment index
				$n += 1
			Next
		Else
			SetError(2); Error getting process collection from WMI
		EndIf
		; release the collection object
		$colProcs = 0

		; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process
		; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros
		Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
		$colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet
		$oRefresher.Refresh

		; Time delay before calling refresher
		Local $iTime = TimerInit()
		Do
			Sleep(20)
		Until TimerDiff($iTime) >= 100
		$oRefresher.Refresh

		; Get PerfProc data
		For $oProc In $colProcs
			; Find it in the array
			For $n = 1 To $avProcs[0][0]
				If $avProcs[$n][1] = $oProc.IDProcess Then
					; [n][6] = CPU usage
					$avProcs[$n][6] = $oProc.PercentProcessorTime
					; [n][7] = memory usage
					$avProcs[$n][7] = $oProc.WorkingSet
					ExitLoop
				EndIf
			Next
		Next
	Else
		SetError(1); Error connecting to WMI
	EndIf

	; Return array
	Return $avProcs
EndFunc   ;==>_ProcessListProperties

Removal of Matlab

To remove Matlab and/or Matlab toolboxes, you can't simply run the documented command line:

"%SYSTEMDRIVE%\matlab-%version%\uninstall\bin\win32\uninstall.exe" -inputfile "%SOFTWARE%\math_progs\\matlab_2010b_uninstaller_input.txt"

If you do, the uninstall.exe program will start, launch the uninstall gui (hidden from view of course so you've no idea what's going on) and sit there. To 'make it work', create a very simple batch file that accepts two arguments, one, the path the the uninstall.exe and the second, the path to the input file (copy of this input file is in {path to matlab}\uninstall\). Run this batch file as the <remove>.

@echo off
set SOFTWARE=%1
set config=%2

start "matlab" /wait %SOFTWARE% -inputFile %CONFIG%