;***************************************** ;winst32_preproc.au3 by Holger Pandel ;Erstellt mit ISN AutoIt Studio v. 1.09 ;***************************************** ;OPSI standard call to winst32 ;command = "%action_processor.local_dir%\\%action_processor.filename%" /opsiservice "%service_url%" /clientid %global.host_id% /username %global.host_id% /password %global.opsi_host_key% ; modified preprocessor command ;_getopts() ;command = "%global.base_dir%\\winst32_preproc.exe" -f="%action_processor.local_dir%\\%action_processor.filename%" -s=%service_url% -c=%global.host_id% -u=%global.host_id% -p=%global.opsi_host_key% -l="%global.log_dir%\\winst32_preproc.log" -r ; includes #include #include #include #include #include "UDFs\AssoArrays.au3" #include "UDFs\GetOpt.au3" #include "UDFs\json.au3" Global Const $HTTP_STATUS_OK = 200 ;Opt('MustDeclareVars', 1) ; appplication title and version Global $header = "winst32_preproc (MIT licensed)" Global $version = "1.1.0.0" Global $logdir = @TempDir & "\winst32_preproc" Global $log_mode = True ; write log file = true Global $log_file = $logdir & "\winst32_preproc.log" ; set default logfile name Global $opsi_command = "C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst\winst32.exe" Global $opsi_url = "https://server.id:4447/rpc" Global $opsi_client = "localhost.localdom.net" Global $opsi_user = "localhost.localdom.net" Global $opsi_pass = "1234567890" Global $Pid, $Handle, $ExitCode, $Cmd, $Cmdout Global $iniName = "winst32_preproc.ini" Global $isRegOk = False ; if true, it outputs messages on console, if false onbly to log file Global $debug = False ; if true, do not actually run any command Global $test = True Local $msg = '------------------------------------------------------------------------------------------------------------------' & @CRLF ; start line $msg &= $header & ' v' & $version & ' Command Line' & @CRLF & @CRLF ; Message. ; Load ini data Global $iniName = "winst32_preproc" _getIniValues($iniName) ; let's have a look at the CmdLine If $CmdLine[0] = 0 Then $msg &= "No arguments passed. See -h for help or use -d for a test run. Exiting." & @CRLF & @CRLF ConsoleWrite($msg) Exit 0 Else _debug($msg) EndIf ; get cmdline options _getopts() If not FileExists($opsi_command) Then _debug("OPSI action processor not found. Exit.") _exit(1) EndIf _debug("Running as user: " & @UserName) _debug("Profile dir : " & @UserProfileDir) _debug("Log file : " & $log_file) ; for debugging purpose ;If $test Then ; x_display() ;EndIf ; --------------------------------------------------------------------------------------------------------------------- ; ---- MAIN --------- If x($iniName & ".registry_check.count") > 0 Then Local $isRegOk = _runRegistryCheck() If $isRegOk Then _debug("All registry checks passed successfully.") Else _debug("One or more registry checks where unsuccsessful.") _exit(0) EndIf EndIf If x($iniName & ".process_check.count") > 0 Then Local $isProcOk = _runProcessCheck() If $isProcOk Then _debug("All process checks passed successfully.") Else _debug("One or more process checks where unsuccsessful.") _exit(0) EndIf EndIf if $test Then ; test run $Cmdout = '"' & $opsi_command & '" /opsiservice "' & $opsi_url & '" /clientid ' & $opsi_client & ' /username ' & $opsi_user & ' /password ***(confidential)***' _debug("") _debug("TESTMODE processing") _debug("-------------------") _debug("action processor: " & $opsi_command) _debug("url: " & $opsi_url) _debug("client: " & $opsi_client) _debug("user: " & $opsi_user) _debug("pass: (CONFIDENTIAL)") _debug("") If x($iniName & ".general.logInstalled") = 1 Then _opsi_showInstalledProducts($opsi_url, $opsi_client, $opsi_user, $opsi_pass) If x($iniName & ".general.logActions") = 1 Then _opsi_showActionRequests($opsi_url, $opsi_client, $opsi_user, $opsi_pass) _debug("") _debug("I) Registry PRE-phase:") _updateRegistry("pre") _debug("") _debug("II) Command to be launched: " & $Cmdout) _debug("") _debug("III) Registry POST-phase:") _updateRegistry("post") _debug("") _debug("Testing only, no opsi processing for now.") _debug("For production mode, use the -r switch (USE WITH CAUTION).") _exit(0) Else ; production run If x($iniName & ".general.logInstalled") = 1 Then _opsi_showInstalledProducts($opsi_url, $opsi_client, $opsi_user, $opsi_pass) If x($iniName & ".general.logActions") = 1 Then _opsi_showActionRequests($opsi_url, $opsi_client, $opsi_user, $opsi_pass) _updateRegistry("pre") $retval = _startActionProcessor($opsi_command, $opsi_url, $opsi_user, $opsi_client, $opsi_pass) _updateRegistry("post") _exit($retval) EndIf ; --------------------------------------------------------------------------------------------------------------------- ; ---- SUPPORT FUNCTIONS --------- ; check if registry values are as necessary Func _runRegistryCheck() Local $rc = False _debug("Running registry checkss...") If x($iniName & ".registry_check.count") = 0 Then _debug("--> nothing to check") return True EndIf ; Example entry: reg1=HKLM|64|SOFTWARE\FIDUCIA\Bitlocker|FSVActive|0 For $i = 1 To x($iniName & ".registry_check.count") Local $a = x($iniName & ".registry_check.reg" & $i) _debug("Test " & $i & ": " & $a[0] & "\" & $a[2] & "(" & $a[1] & "bit):" & $a[3] & "=" & $a[4]) If $a[2] = "32" Then If RegRead($a[0] & "\" & $a[2], $a[3]) = $a[4] then $rc = True _debug("--> rc=" & $rc) Else $rc = False _debug("--> rc=" & $rc) return $rc EndIf Else If RegRead($a[0] & $a[1] & "\" & $a[2], $a[3]) = $a[4] then $rc = True _debug("--> rc=" & $rc) Else $rc = False _debug("--> rc=" & $rc) return $rc EndIf EndIf Next return $rc EndFunc ; check if specified process exist Func _runProcessCheck() Local $rc = False _debug("Running process checks...") If x($iniName & ".process_check.count") = 0 Then _debug("--> nothing to check") return True EndIf ; Example entry: proc1=winword.exe For $i = 1 To x($iniName & ".process_check.count") Local $a = x($iniName & ".process_check.proc" & $i) _debug("Test if not running " & $i & ": " & $a) Local $pid = ProcessExists($a) If $pid > 0 Then $rc = False _debug("--> rc=" & $rc) _debug("--> PID=" & $pid) return $rc Else $rc = True _debug("--> rc=" & $rc) return $rc EndIf Next EndFunc ; set registry entries ; $phase can be "pre" or "post" ; RegWrite ( "keyname" [, "valuename", "type", value] ) Func _updateRegistry($phase) Local $rc = False _debug("Running registry phase: " & $phase) ; Example entry: reg1=HKLM|32|SOFTWARE\FIDUCIA\Bitlocker|FSVActive|0|REG_SZ If x($iniName & ".registry_" & $phase & ".count") = 0 Then _debug("--> nothing to do in this phase") return EndIf For $i = 1 To x($iniName & ".registry_" & $phase & ".count") Local $a = x($iniName & ".registry_" & $phase & ".reg" & $i) If not $test Then _debug("Setting " & $i & ": " & $a[0] & "\" & $a[2] & "(" & $a[1] & "bit):" & $a[3] & "=" & $a[4]) If $a[2] = "32" Then If RegWrite($a[0] & "\" & $a[2], $a[3], $a[5], $a[4]) then $rc = True _debug("--> rc=" & $rc) EndIf Else If RegWrite($a[0] & $a[1] & "\" & $a[2], $a[3], $a[5], $a[4]) then $rc = True _debug("--> rc=" & $rc) EndIf EndIf Else _debug("(TESTMODE) Setting " & $i & ": " & $a[0] & "\" & $a[2] & "(" & $a[1] & "bit):" & $a[3] & " = " & $a[5] & ":" & $a[4]) EndIf Next EndFunc ; run action processor command Func _startActionProcessor($command, $URL, $clientid, $user, $pass) _debug("Starting action...") $Cmd = '"' & $command & '" /opsiservice "' & $URL & '" /clientid ' & $clientid & ' /username ' & $user & ' /password ' & $pass $Cmdout = '"' & $command & '" /opsiservice "' & $URL & '" /clientid ' & $clientid & ' /username ' & $user & ' /password ***(confidential)***' _debug("action processor: " & $command) _debug("url: " & $URL) _debug("client: " & $clientid) _debug("user: " & $user) _debug("pass: (CONFIDENTIAL)") _debug("cmd: " & $Cmdout) $Pid = Run($Cmd, '', @SW_SHOW, $STDOUT_CHILD + $STDERR_CHILD) $Handle = _ProcessExitCode($Pid) ProcessWaitClose($pid) $ExitCode = _ProcessExitCode($Pid, $Handle) _ProcessCloseHandle($Handle) return $ExitCode EndFunc ; handle command line options Func _getopts() Local $sMsg = '------------------------------------------------------------------------------------------------------------------' & @CRLF ; start line $sMsg &= $header & ' v' & $version & ' Command Line' & @CRLF & @CRLF ; Message. Local $sOpt, $sSubOpt, $sOper Local $h_specified = False Local $failure = False ; Options array, entries have the format [short, long, default value] Local $aOpts[9][3] = [ _ ['-f', '--acp_command', $GETOPT_REQUIRED_ARGUMENT], _ ['-s', '--service_url', $GETOPT_REQUIRED_ARGUMENT], _ ['-c', '--clientid', $GETOPT_REQUIRED_ARGUMENT], _ ['-u', '--username', $GETOPT_REQUIRED_ARGUMENT], _ ['-p', '--password', $GETOPT_REQUIRED_ARGUMENT], _ ['-d', '--debug', True], _ ['-r', '--r', True], _ ['-l', '--log', $log_file], _ ['-h', '--help', True]] _GetOpt_Set($aOpts) ; Set options. If 0 < $GetOpt_Opts[0] Then ; If there are any options... ; first loop: analyse parameters and create message texts, exit program if needed While 1 ; ...loop through them one by one. ; Get the next option passing a string with valid options. $sOpt = _GetOpt('f:s:c:u:p:rdtlh') ; p: means -p option requires an argument. If Not $sOpt Then ExitLoop ; No options or end of loop. ; Check @extended above if you want better error handling. ; The current option is stored in $GetOpt_Opt, it's index (in $GetOpt_Opts) ; in $GetOpt_Ind and it's value in $GetOpt_Arg. Switch $sOpt ; What is the current option? Case '?' ; Unknown options come here. @extended is set to $E_GETOPT_UNKNOWN_OPTION $sMsg &= 'Unknown option: ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ').' & @CRLF $sMsg &= 'UNKNOWN OPTION passed.' & @CRLF $failure = True Case ':' ; Options with missing required arguments come here. @extended is set to $E_GETOPT_MISSING_ARGUMENT $sMsg &= 'MISSING REQUIRED ARGUMENT for option: ' & $GetOpt_Ind & ': ' & $GetOpt_Opt & @CRLF $failure = True Case 'l' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $log_file = $GetOpt_Arg Case 'd' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $debug = True Case 'r' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $test = False Case 'f' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with required value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $opsi_command = $GetOpt_Arg Case 's' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with required value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $opsi_url = $GetOpt_Arg Case 'c' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with required value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $opsi_client = $GetOpt_Arg Case 'u' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with required value "' & $GetOpt_Arg & '" (' & VarGetType($GetOpt_Arg) & ')' $sMsg &= '.' & @CRLF $opsi_user = $GetOpt_Arg Case 'p' $sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt $sMsg &= ' with ***(confidential)*** value supplied. ' $sMsg &= '.' & @CRLF $opsi_pass = $GetOpt_Arg Case 'h' $sMsg &= 'Available command line options:' & @CRLF & @CRLF & _ '-f' & @TAB & '--acp-command ' & @TAB & 'Action processor filename, ie. winst32.exe' & @CRLF & _ '-s' & @TAB & '--service_url ' & @TAB & 'service URL' & @CRLF & _ '-c' & @TAB & '--clientid ' & @TAB & 'client id' & @CRLF & _ '-u' & @TAB & '--username ' & @TAB & 'service username' & @CRLF & _ '-p' & @TAB & '--password ' & @TAB & 'password' & @CRLF & _ '-d' & @TAB & '--debug ' & @TAB & 'Debug output' & @CRLF & _ '-r' & @TAB & '--run ' & @TAB & 'Production mode (REALLY activate the program!)' & @CRLF & _ '-l' & @TAB & '--log ' & @TAB & 'Different logfile name' & @CRLF & _ '-h' & @TAB & '--help ' & @TAB & 'Show this help' & @CRLF & @CRLF & _ 'Default logfile: ' & $log_file & @CRLF & @CRLF $h_specified = True EndSwitch Wend If 0 < $GetOpt_Opers[0] Then ; If there are any operands... $sMsg &= 'INVALID OPERANDS PASSED. This is not allowed. Check for missing ''='' in --path or --log option!' & @CRLF While 1 ; ...loop through them one by one. $sOper = _GetOpt_Oper() ; Get the next operand. If Not $sOper Then ExitLoop ; no operands or end of loop. ; Check @extended above if you want better error handling. $sMsg &= 'Operand ' & $GetOpt_OperInd & ': ' & $sOper & @CRLF WEnd $failure = True EndIf If $failure Then $sMsg &= @CRLF & 'Please check the command line parameters!' & @CRLF If $h_specified Or $failure Then ; show help screen or wrong options ? ConsoleWrite(@crlf & $sMsg) If $failure Then _exit(1) _exit(0) EndIf EndIf ; write header to log _writeLog(_formatIOText($sMsg)) EndFunc ; part of _getIniValues Func _getLeaf($leaf, $tab) Local $str If not IsObj($leaf) Then Return $colKeys = $leaf.Keys For $strKey in $colKeys $str = "" If IsArray($leaf.Item($strKey)) Then $str = $leaf.Item($strKey)[0] For $i = 1 to Ubound($leaf.Item($strKey)) - 1 $str &= "|" & $leaf.Item($strKey)[$i] Next _debug($tab & $strKey & ' -> ' & $str) Else _debug($tab & $strKey & ' -> ' & $leaf.Item($strKey)) EndIf _getLeaf($leaf.Item($strKey), $tab & " ") Next EndFunc ; read ini values Func _getIniValues($iniName) Dim $szDrive, $szDir, $szFName, $szExt, $pathTemp, $kdSel, $op $pathTemp = _PathSplit(@ScriptFullPath, $szDrive, $szDir, $szFName, $szExt) Dim $appPath = $szDrive & $szDir Dim $iniFile = $appPath & $iniName & ".ini" Dim $rc, $cpm[3], $msg, $str, $colKeys _debug("Ini file : " & $iniFile) If FileExists($iniFile) Then ;--- global INI file found $rc = _ReadAssocFromIni2($iniFile) If @error Then _debug("Error while reading ini file. Errno: " & @error) Else _debug("Entries read: " & $rc) _debug("Logging configuration:") _debug("--------------- snip ------------------") _getLeaf($_xHashCollection, " ") _debug("--------------- snip -----------------") _debug("INI reading complete.") EndIf Else ;--- INI not existing, creating new one in script directory $msg = "INI file not found: " & $iniFile & @CRLF & _ "A new INI file with example values will be created in the script directory." & @CRLF & _ "Please customize the INI file before using it." & @CRLF & @CRLF ConsoleWrite($msg) _createIni($appPath & $iniName) EndIf EndFunc ;==>_getIniValues ; get current product status Func _REST_request($req, $clientid, $user, $pass) Local $REST = ObjCreate("WinHttp.WinHttpRequest.5.1") Local $agent ='Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36' ; https://$serverid:$serverport/rpc?{ "id": 1, "method": "getProductInstallationStatus_listOfHashes", "params": ["$clientid"] } ;ConsoleWrite(@CRLF & "Request: " & $req) $REST.Open("GET", $req, False) If (@error) Then Return SetError(1, 0, "Error on open") $REST.SetRequestHeader('Authorization','Basic ' & base64($user & ":" & $pass, True, True)) $REST.setRequestHeader ("User-Agent", $agent) $REST.Option(4) = 13056 $REST.Send() If (@error) Then Return SetError(2, 0, "Error on send") If ($REST.Status <> $HTTP_STATUS_OK) Then Return SetError(3, 0, "Error on request - HTTP status " & $REST.Status) return $REST.ResponseText EndFunc ; convert lastStateChange into more readable format Func _opsiDate($raw) Local $year = StringMid($raw,1, 4) Local $mon = StringMid($raw,5, 2) Local $day = StringMid($raw,7, 2) Local $hour = StringMid($raw,9, 2) Local $min = StringMid($raw,11, 2) return $day & "." & $mon & "." & $year & " " & $hour & ":" & $min EndFunc ; request all installed products on client Func _opsi_showInstalledProducts($URL, $clientid, $user, $pass) Local $_getProductInstallationStatus_listOfHashes = $URL & '?{ "id": 1, "method": "getProductInstallationStatus_listOfHashes", "params": ["' & $clientid & '"] }' Local $retval = _REST_request($_getProductInstallationStatus_listOfHashes, $clientid, $user, $pass) If (@error) Then _debug("Error on REST request: " & $retval) return EndIf Local $data = json_decode($retVal) ;json_dump($retval) _debug("Currently installed:") Local $i = 0 While 1 $product_id = json_get($data, '.result[' & $i & '].productId') $installationStatus = json_get($data, '.result[' & $i & '].installationStatus') $installed = json_get($data, '.result[' & $i & '].lastStateChange') If @error Then ExitLoop If $installationStatus = "installed" Then _debug("--> " & $product_id & " (lastStateChange: " & _opsiDate($installed) & ")") EndIf $i += 1 WEnd EndFunc ; request current action requests for client Func _opsi_showActionRequests($URL, $clientid, $user, $pass) Local $_getProductActionRequests_listOfHashes = $URL & '?{ "id": 1, "method": "getProductActionRequests_listOfHashes", "params": ["' & $clientid & '"] }' Local $retval = _REST_request($_getProductActionRequests_listOfHashes, $clientid, $user, $pass) If (@error) Then _debug("Error on REST request: " & $retval) return EndIf Local $data = json_decode($retVal) ;json_dump($retval) _debug("Current action requests:") Local $i = 0 While 1 $product_id = json_get($data, '.result[' & $i & '].productId') $actionRequest = json_get($data, '.result[' & $i & '].actionRequest') If @error Then ExitLoop If $actionRequest <> "none" Then _debug("--> " & $product_id & ": " & $actionRequest) EndIf $i += 1 WEnd EndFunc ; common exit Func _exit($rc) _debug("") _debug("winst32_preproc exiting.") _debug("------------------------------------------------------------------------------------------------------------------") Exit $rc EndFunc ; create default example ini file Func _createIni($ini) x($ini & ".general.version", $version) x($ini & ".general.logInstalled", 1) x($ini & ".general.logActions", 1) x($ini & ".registry_check.count", 1) Local $a = ["HKLM", "64", "SOFTWARE\RZ\FSV", "FSVActive", "0"] x($ini & ".registry_check.reg1", $a) x($ini & ".registry_pre.count", 2) Local $a = ["HKLM", "64", "SOFTWARE\RZ\FSV", "FSVActive", "1", "REG_SZ"] x($ini & ".registry_pre.reg1", $a) Local $a = ["HKLM", "64", "SOFTWARE\opsi.org\Winst", "Active", "1", "REG_SZ"] x($ini & ".registry_pre.reg2", $a) x($ini & ".registry_post.count", 3) Local $a = ["HKLM", "64", "SOFTWARE\RZ\FSV", "FSVActive", "0", "REG_SZ"] x($ini & ".registry_post.reg1", $a) Local $a = ["HKLM", "64", "SOFTWARE\opsi.org\Winst", "Active", "0", "REG_SZ"] x($ini & ".registry_post.reg2", $a) Local $a = ["HKLM", "32", "SOFTWARE\Somewhere\Else|SomeOtherValue", "50", "REG_DWORD"] x($ini & ".registry_post.reg3", $a) x($ini & ".process_check.count", 1) Local $a = ["svchost.exe"] x($ini & ".process_check.proc1", $a) _WriteAssocToIni($ini) EndFunc ; --------------------------------------------------------------------------------------------------------------------- ; ---- TOOLS --------- ; output debug messages to console Func _debug($dbg, $line = @ScriptLineNumber) Local $time = "[" & @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "] ! DEBUG" If $debug Then if $line = -1 then ConsoleWrite(@CRLF & $time & ": " & $dbg) Else ConsoleWrite(@CRLF & $time & " (" & $line & "): " & $dbg) Endif EndIf _writeLog(_formatIOText($dbg)) EndFunc ;==>_debug ; format message text line for console and log ; if $mark is "?????", then special question format is used Func _formatIOText($text, $mark = "") Local $time = "[" & @MDAY & "." & @MON & "." & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "] " If $mark = "" Then $text = $time & StringReplace($text, @CRLF, @CRLF & $time) ElseIf $mark = "?????" Then $text = $time & $text & ": " Else $text = $time & "! " & $mark & ": " & StringReplace($text, @CRLF, @CRLF & $time & "! " & $mark & ": ") EndIf Return $text EndFunc ;==>_formatIOText ; log messages to disc Func _writeLog($msg, $nocrlf = False) ; write lines to logfile, even if --quiet is specified If $log_mode Then Local $file = FileOpen($log_file, 1 + 8) ; create dir and open/create file If $nocrlf Then FileWrite($file, $msg) Else FileWrite($file, @CRLF & $msg) EndIf FileFlush($file) FileClose($file) EndIf EndFunc ;==>_writeLog ;=============================================================================== ; ; Function Name: _ProcessExitCode() ; Description: Returns a handle/exitcode from use of Run(). ; Parameter(s): $i_Pid - ProcessID returned from a Run() execution ; $h_Process - Process handle ; Requirement(s): None ; Return Value(s): On Success - Returns Process handle while Run() is executing ; (use above directly after Run() line with only PID parameter) ; - Returns Process Exitcode when Process does not exist ; (use above with PID and Process Handle parameter returned from first UDF call) ; On Failure - 0 ; Author(s): MHz (Thanks to DaveF for posting these DllCalls in Support Forum) ; ;=============================================================================== ; Func _ProcessExitCode($i_Pid, $h_Process = 0) ; 0 = Return Process Handle of PID else use Handle to Return Exitcode of a PID Local $v_Placeholder If Not IsArray($h_Process) Then ; Return the process handle of a PID $h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid) If Not @error Then Return $h_Process Else ; Return Process Exitcode of PID $h_Process = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', $v_Placeholder) If Not @error Then Return $h_Process[2] EndIf Return 0 EndFunc ;==>_ProcessExitCode ; close handle to attached process Func _ProcessCloseHandle($h_Process) ; Close the process handle of a PID DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process) If Not @error Then Return 1 Return 0 EndFunc ;==>_ProcessCloseHandle ; Get STDOUT and ERROUT from commandline tool Func ShowStdOutErr($l_Handle, $ShowConsole = 1, $Replace = "", $ReplaceWith = "") Local $Line = "x", $Line2 = "x", $tot_out, $err1 = 0, $err2 = 0, $cnt1 = 0, $cnt2 = 0 Do Sleep(10) $Line = StdoutRead($l_Handle) $err1 = @error If $Replace <> "" Then $Line = StringReplace($Line, $Replace, $ReplaceWith) $tot_out &= $Line If $ShowConsole Then ConsoleWrite($Line) EndIf $Line2 = StderrRead($l_Handle) $err2 = @error If $Replace <> "" Then $Line2 = StringReplace($Line2, $Replace, $ReplaceWith) $tot_out &= $Line2 If $ShowConsole Then ConsoleWrite($Line2) EndIf ; end the loop also when AutoIt3 has ended but a sub process was shelled with Run() that is still active ; only do this every 50 cycles to avoid cpu hunger If $cnt1 = 50 Then $cnt1 = 0 ; loop another 50 times just to ensure the buffers emptied. If Not ProcessExists($l_Handle) Then If $cnt2 > 2 Then ExitLoop $cnt2 += 1 EndIf EndIf $cnt1 += 1 Until ($err1 And $err2) Return $tot_out EndFunc ;==>ShowStdOutErr ; Author: MilesAhead ; http://www.autoitscript.com/forum/topic/110768-itaskbarlist3/page__view__findpost__p__910631 ; read AssocArray from IniFile Section ; returns number of items read - sets @error on failure ; modified (original see AssoArray.au3): Holger Pandel, 2015: accept full path name of ini Func _ReadAssocFromIni2($myIni = 'config.ini', $mySection = '', $sSep = "|") Local $szDrive, $szDir, $szFName, $szExt, $pathTemp $pathTemp = _PathSplit(@ScriptFullPath, $szDrive, $szDir, $szFName, $szExt) $sIni = $szFName If $mySection == '' Then $aSection = IniReadSectionNames ($myIni); All sections If @error Then _debug("Error while reading section names from: " & $myIni) Return SetError(@error, 0, 0) EndIf Else Dim $aSection[2] = [1,$mySection]; specific Section EndIf For $i = 1 To UBound($aSection)-1 Local $sectionArray = IniReadSection($myIni, $aSection[$i]) If @error Then _debug("Error while reading section: " & $aSection[$i]) Return SetError(1, 0, 0) EndIf For $x = 1 To $sectionArray[0][0] If StringInStr($sectionArray[$x][1], $sSep) then $posS = _MakePosArray($sectionArray[$x][1], $sSep) Else $posS = $sectionArray[$x][1] EndIf x($sIni&"."&$aSection[$i]&"."&$sectionArray[$x][0], $posS) Next next Return $sectionArray[0][0] EndFunc ;==>_ReadAssocFromIni ;============================================================================================================================== ; Function: base64($vCode [, $bEncode = True [, $bUrl = False]]) ; ; Description: Decode or Encode $vData using Microsoft.XMLDOM to Base64Binary or Base64Url. ; IMPORTANT! Encoded base64url is without @LF after 72 lines. Some websites may require this. ; ; Parameter(s): $vData - string or integer | Data to encode or decode. ; $bEncode - boolean | True - encode, False - decode. ; $bUrl - boolean | True - output is will decoded or encoded using base64url shema. ; ; Return Value(s): On Success - Returns output data ; On Failure - Returns 1 - Failed to create object. ; ; Author (s): (Ghads on Wordpress.com), Ascer ;=============================================================================================================================== Func base64($vCode, $bEncode = True, $bUrl = False) Local $oDM = ObjCreate("Microsoft.XMLDOM") If Not IsObj($oDM) Then Return SetError(1, 0, 1) Local $oEL = $oDM.createElement("Tmp") $oEL.DataType = "bin.base64" If $bEncode then $oEL.NodeTypedValue = Binary($vCode) If Not $bUrl Then Return $oEL.Text Return StringReplace(StringReplace(StringReplace($oEL.Text, "+", "-"),"/", "_"), @LF, "") Else If $bUrl Then $vCode = StringReplace(StringReplace($vCode, "-", "+"), "_", "/") $oEL.Text = $vCode Return $oEL.NodeTypedValue EndIf EndFunc ;==>base64