Have your VBA Add-in autogenerate menus for easier access to your macros

  1. P_20160720_203804
  2. Storing your macros in add-ins (.xlam) has many advantages over personal.xlsm and similar document locations.
  3. One disadvantage is that an Add-in macro is not accessible through the macros dialogue.
  4. The community recommends assigning shortcuts for easy access. I did that and went a couple of steps further using VBE extensibility to
    1. depending on scope
      1. public procedures on your end users’ computer to whom you distribute your Add-in
      2. and also non-private on the developer  machine
    2. list your modules alphabetically
    3. list your macros alphabetically under your modules
    4. find pick a free (within Excel -  short of windows-wide shortcuts – In my current work environment, I am unable run tools that allow you to list these shortcuts) shortcut combination and and assign it to your macro Code
  5. Code TBA

Inserting Word Building Blocks from Template using Ribbon or QAT

Either insert from Ribbon / Insert / Quickparts: image

Or for extra speed and convenience, you can have your template store access to your building from the Quick Access Toolbar: image

Demo video is here.

Try “Stop Collecting” with Office Clipboard for Runtime Error 1004 “Paste Method of Worksheet Failed”

There seem plenty potential sources of error for  method .Pastespecial, and  a vast amount of questions and good advice online.

But I did not find this one, and only this one managed to make Pastespecial into Excel work for me. image

PowerShell script to save all .pdf’s as .docx in and underneath a folder failing on Word 2016, working on Word 2010.

  1. Problem: Word 2016 shows erratic behavior when trying to save (admittedly: complex) .PDF as .DOCX – whether
    1. using automation
      1. “The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108  (RPC_E_DISCONNECTED))”
      2. “The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)”
    2. or trying manually.
      1. “There is a problem saving the file.”
      2. “A file error has occurred.”
      3. Or Word crashes.
  2. Workaround: My age-old Word 2010 installation on Windows Vista with PowerShell 2 (gasp! Smiley) manages this automation script (inspired by The Scripting Guy) just fine:
$Word = NEW-OBJECT –COMOBJECT WORD.APPLICATION  
# Acquire a list of DOCX files in a folder
$Files = GET-CHILDITEM -include *.pdf -exclude *_converted.pdf -recurse -path 'G:\bookz\office\excel' # 'G:\bookz\lang\vba' # 'G:\bookz\office\access' # 
 
Foreach ($File in $Files) {
    try{
        write-host "Trying  " $File.fullname 
        # open a Word document, filename from the directory
        $Doc1=$Word.Documents.Open($File.fullname)
        write-host "Opening " $File.fullname ". RESULT=" + $?
        # Swap out PDF with DOCX in the Filename
        $Name=($File.Fullname).replace("pdf",“docx”) # $Name=($Doc1.Fullname).replace("pdf",“docx”)
        # Save this File as a PDF in Word 2010/2013 - hm, and 2016 fails? 
        $Doc1.saveas([ref] $Name, [ref] 16) # see WdSaveFormat enumeration : 16 is word default, 
    }
    catch 
    { 
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        write-host "Caught error saving " $FailedItem ". Msg: " $ErrorMessage 
    } 
    finally {
        $Doc1.close()
        [GC]::Collect() # watch me trying a number of things to get this to work with Word 2016...🙂
        move-item -path $file.FullName -destination ($file.Directory.ToString() + "\" + $file.BaseName + "_converted" + $file.Extension)
    }
}

 

AutoIt script to export a Testing Anywhere tamx codebase to text files

  1. Being confronted with a legacy codebase of over 750 tamx automated test scripts and
  2. the limited Testing Anywhere IDE .
    1. Normal view – essentially links to property dialogues – without helpful search,
    2. Expert view not being used with no cross-file, let alone codebase search, and just another partial view of the actual underlying code which is only available encrypted in the tamx files;
    3. Server Backup diff feature rudimentary and not being used.
  3. I came up with this AutoIT script (Testing Anywhere – but not Anything – won’t allow automation of its own window) which:
    1. collects, given a flat file listing of their paths, the Testing Anywhere (tested with 9.2) automated test scripts (tamx),
    2. from a list of networked (and drive-letter-mapped: fill out hash to guide the path translation) test automation computers,
    3. to a local directory (root=$localpathpattern, plus remote path) as
      1. .txt, using  TA‘s built-in export function) and
      2. .tax (using line-by-line copy from TA expert view).
    4. To improve resilience despite automation errors, the script keeps track of files exported in 2 ways, through
      1. a list tamxlistdone.txt
      2. comparison of file dates and exports only tamx files updated since last save as txt/tax.
    5. You can try the script out opening the tamx files in a text editor instead of the Testing Anywhere editor if you set $isdryrun = True.
  4. Compile this script to an AutoIt exe and make it a Scheduled Task to update your searchable codebase overnight.
  5. Benefits:
    1. Use for better cross automation project search (e.g. for magic strings and other literals, like log messages emitted)
    2. and to put into better source control than TA provides: Export the .txt./.tax  into a Git repository, to be able to monitor your progress/collaborators.
  6. Sorry: no round tripping.
    1. There are some stubs in the script to implement uploading changes, since Expert view allows line-by-line paste from the clipboard.
    2. However, it seems Expert view represents only another partial view of the underlying code which a textual paste is likely to break.
    3. In addition, even with test scripts that are run, switching to Expert View can result in intractable syntax errors that prevent user from saving, even from switching back to normal view without.
  7. Had to obfuscate the script – message me if you cannot figure how to fill in the config section at the top.
     
    Global Const $0 = 1
    Global Const $1 = 0
    Global Const $2 = 1
    Global Const $3 = 2
    Func _0($4, $5, $6 = 0, $7 = 0, $8 = 0, $9 = "wparam", $a = "lparam", $b = "lresult")
    	Local $c = DllCall("user32.dll", $b, "SendMessageW", "hwnd", $4, "uint", $5, $9, $6, $a, $7)
    	If @error Then Return SetError(@error, @extended, "")
    	If $8 >= 0 And $8 <= 4 Then Return $c[$8]
    	Return $c
    EndFunc   ;==>_0
    Global Const $d = 1
    Global Const $e = 2
    Global Const $f = 0
    Global Const $g = 1
    Global Const $h = 2
    Global Const $i = 0
    Global Const $j = 1
    Func _2(Const $k = @error, Const $l = @extended)
    	Local $c = DllCall("kernel32.dll", "dword", "GetLastError")
    	Return SetError($k, $l, $c[0])
    EndFunc   ;==>_2
    Global Const $m = "Debug Window hidden text"
    Global $n = "AutoIt Debug Report"
    Global $o = 0
    Global $p = True, $q = True
    Global $r = 0
    Global $s
    Global $t = False
    Func _8(Const $u, Const $k = @error, Const $l = @extended)
    	If IsNumber($u) = 0 And IsString($u) = 0 And IsBool($u) = 0 Then Return SetError(1, 0, 0)
    	If _a($u) = 0 Then Return SetError(3, 0, 0)
    	Return SetError($k, $l, 1)
    EndFunc   ;==>_8
    Func _a($v, $w = False, $x = False, Const $k = @error, $l = @extended)
    	If $o <= 0 Or $o > 6 Then Return SetError($k, $l, 0)
    	$l = _k($v, $w)
    	If $x Then Exit
    	Return SetError($k, $l, 1)
    EndFunc   ;==>_a
    Func _h()
    	Local $y = Opt("WinDetectHiddenText", $0)
    	Local $0z = WinExists($n, $m)
    	If $0z Then
    		If $r = 0 Then
    			$r = ControlGetHandle($n, $m, "Edit1")
    			$p = False
    		EndIf
    	EndIf
    	Opt("WinDetectHiddenText", $y)
    	$q = False
    	If Not $p Then Return 0
    	Local Const $10 = 0x00CF0000
    	Local Const $11 = 0x00100000
    	Local Const $12 = 0x00200000
    	Local Const $13 = 2048
    	Local Const $14 = 0xC5
    	Local Const $15 = 32
    	Local $16 = 580, $17 = 280
    	GUICreate($n, $16, $17, -1, -1, $10)
    	Local $18 = GUICtrlCreateLabel($m, 0, 0, 1, 1)
    	GUICtrlSetState($18, $15)
    	Local $19 = GUICtrlCreateEdit("", 4, 4, $16 - 8, $17 - 8, BitOR($11, $12, $13))
    	$r = GUICtrlGetHandle($19)
    	GUICtrlSetBkColor($19, 0xFFFFFF)
    	GUICtrlSendMsg($19, $14, 0, 0)
    	GUISetState()
    	$p = True
    	Return 1
    EndFunc   ;==>_h
    #Au3Stripper_Off
    Func __Debug_ReportWindowWrite($sData)
    	#Au3Stripper_On
    	If $q Then _h()
    	Local Const $1a = 0x000E
    	Local Const $1b = 0xB1
    	Local Const $1c = 0xC2
    	Local $1d = _0($r, $1a, 0, 0, 0, "int", "int")
    	_0($r, $1b, $1d, $1d, 0, "int", "int")
    	_0($r, $1c, True, $v, 0, "int", "wstr")
    EndFunc   ;==>__Debug_ReportWindowWrite
    Func _j()
    	Local $0z = WinExists($n)
    	If $0z Then
    		If $r = 0 Then
    			$r = WinGetHandle($n)
    			Return 0
    		EndIf
    	EndIf
    	Local $1e = Run("Notepad.exe")
    	$r = WinWait("[CLASS:Notepad]")
    	If $1e <> WinGetProcess($r) Then
    		Return SetError(3, 0, 0)
    	EndIf
    	WinActivate($r)
    	WinSetTitle($r, "", String($n))
    	Return 1
    EndFunc   ;==>_j
    #Au3Stripper_Off
    Func __Debug_ReportNotepadWrite($sData)
    	#Au3Stripper_On
    	If $r = 0 Then _j()
    	ControlCommand($r, "", "Edit1", "EditPaste", String($v))
    EndFunc   ;==>__Debug_ReportNotepadWrite
    Func _k($v, $w = False, $1f = @extended)
    	Local $1g = @CRLF
    	If $t And ($v <> "") Then $v = @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " " & $v
    	If $w Then
    		$1f = _2()
    		Local Const $1h = 0x1000
    		Local $c = DllCall("kernel32.dll", "dword", "FormatMessageW", "dword", $1h, "ptr", 0, "dword", $1f, "dword", 0, "wstr", "", "dword", 4096, "ptr", 0)
    		$1g = " : " & $c[5]
    	EndIf
    	$v &= $1g
    	Local $1i = BlockInput(1)
    	BlockInput(0)
    	$v = StringReplace($v, "'", "''")
    	Execute($s & "'" & $v & "')")
    	If Not $1i Then BlockInput(1)
    	Return $1f
    EndFunc   ;==>_k
    Func _r(ByRef $1j, $1k)
    	If Not IsArray($1j) Then Return SetError(1, 0, -1)
    	Local $1l = UBound($1j, $2) - 1
    	If IsArray($1k) Then
    		If UBound($1k, $1) <> 1 Or UBound($1k, $2) < 2 Then Return SetError(4, 0, -1)
    	Else
    		Local $1m, $1n, $1o
    		$1k = StringStripWS($1k, 8)
    		$1n = StringSplit($1k, ";")
    		$1k = ""
    		For $1p = 1 To $1n[0]
    			If Not StringRegExp($1n[$1p], "^\d+(-\d+)?$") Then Return SetError(3, 0, -1)
    			$1o = StringSplit($1n[$1p], "-")
    			Switch $1o[0]
    				Case 1
    					$1k &= $1o[1] & ";"
    				Case 2
    					If Number($1o[2]) >= Number($1o[1]) Then
    						$1m = $1o[1] - 1
    						Do
    							$1m += 1
    							$1k &= $1m & ";"
    						Until $1m = $1o[2]
    					EndIf
    			EndSwitch
    		Next
    		$1k = StringSplit(StringTrimRight($1k, 1), ";")
    	EndIf
    	If $1k[1] < 0 Or $1k[$1k[0]] > $1l Then Return SetError(5, 0, -1)
    	Local $1q = 0
    	Switch UBound($1j, $1)
    		Case 1
    			For $1p = 1 To $1k[0]
    				$1j[$1k[$1p]] = ChrW(0xFAB1)
    			Next
    			For $1r = 0 To $1l
    				If $1j[$1r] == ChrW(0xFAB1) Then
    					ContinueLoop
    				Else
    					If $1r <> $1q Then
    						$1j[$1q] = $1j[$1r]
    					EndIf
    					$1q += 1
    				EndIf
    			Next
    			ReDim $1j[$1l - $1k[0] + 1]
    		Case 2
    			Local $1s = UBound($1j, $3) - 1
    			For $1p = 1 To $1k[0]
    				$1j[$1k[$1p]][0] = ChrW(0xFAB1)
    			Next
    			For $1r = 0 To $1l
    				If $1j[$1r][0] == ChrW(0xFAB1) Then
    					ContinueLoop
    				Else
    					If $1r <> $1q Then
    						For $1t = 0 To $1s
    							$1j[$1q][$1t] = $1j[$1r][$1t]
    						Next
    					EndIf
    					$1q += 1
    				EndIf
    			Next
    			ReDim $1j[$1l - $1k[0] + 1][$1s + 1]
    		Case Else
    			Return SetError(2, 0, False)
    	EndSwitch
    	Return UBound($1j, $2)
    EndFunc   ;==>_r
    Func _14(Const ByRef $1j, $1u, $1v = 0, $1w = 0, $1x = 0, $1y = 0, $1z = 1, $20 = -1, $21 = False)
    	If $1v = Default Then $1v = 0
    	If $1w = Default Then $1w = 0
    	If $1x = Default Then $1x = 0
    	If $1y = Default Then $1y = 0
    	If $1z = Default Then $1z = 1
    	If $20 = Default Then $20 = -1
    	If $21 = Default Then $21 = False
    	If Not IsArray($1j) Then Return SetError(1, 0, -1)
    	Local $1l = UBound($1j) - 1
    	If $1l = -1 Then Return SetError(3, 0, -1)
    	Local $1s = UBound($1j, $3) - 1
    	Local $22 = False
    	If $1y = 2 Then
    		$1y = 0
    		$22 = True
    	EndIf
    	If $21 Then
    		If UBound($1j, $1) = 1 Then Return SetError(5, 0, -1)
    		If $1w < 1 Or $1w > $1s Then $1w = $1s
    		If $1v < 0 Then $1v = 0
    		If $1v > $1w Then Return SetError(4, 0, -1)
    	Else
    		If $1w < 1 Or $1w > $1l Then $1w = $1l
    		If $1v < 0 Then $1v = 0
    		If $1v > $1w Then Return SetError(4, 0, -1)
    	EndIf
    	Local $23 = 1
    	If Not $1z Then
    		Local $24 = $1v
    		$1v = $1w
    		$1w = $24
    		$23 = -1
    	EndIf
    	Switch UBound($1j, $1)
    		Case 1
    			If Not $1y Then
    				If Not $1x Then
    					For $1p = $1v To $1w Step $23
    						If $22 And VarGetType($1j[$1p]) <> VarGetType($1u) Then ContinueLoop
    						If $1j[$1p] = $1u Then Return $1p
    					Next
    				Else
    					For $1p = $1v To $1w Step $23
    						If $22 And VarGetType($1j[$1p]) <> VarGetType($1u) Then ContinueLoop
    						If $1j[$1p] == $1u Then Return $1p
    					Next
    				EndIf
    			Else
    				For $1p = $1v To $1w Step $23
    					If $1y = 3 Then
    						If StringRegExp($1j[$1p], $1u) Then Return $1p
    					Else
    						If StringInStr($1j[$1p], $1u, $1x) > 0 Then Return $1p
    					EndIf
    				Next
    			EndIf
    		Case 2
    			Local $25
    			If $21 Then
    				$25 = $1l
    				If $20 > $25 Then $20 = $25
    				If $20 < 0 Then
    					$20 = 0
    				Else
    					$25 = $20
    				EndIf
    			Else
    				$25 = $1s
    				If $20 > $25 Then $20 = $25
    				If $20 < 0 Then
    					$20 = 0
    				Else
    					$25 = $20
    				EndIf
    			EndIf
    			For $1t = $20 To $25
    				If Not $1y Then
    					If Not $1x Then
    						For $1p = $1v To $1w Step $23
    							If $21 Then
    								If $22 And VarGetType($1j[$1t][$1t]) <> VarGetType($1u) Then ContinueLoop
    								If $1j[$1t][$1p] = $1u Then Return $1p
    							Else
    								If $22 And VarGetType($1j[$1p][$1t]) <> VarGetType($1u) Then ContinueLoop
    								If $1j[$1p][$1t] = $1u Then Return $1p
    							EndIf
    						Next
    					Else
    						For $1p = $1v To $1w Step $23
    							If $21 Then
    								If $22 And VarGetType($1j[$1t][$1p]) <> VarGetType($1u) Then ContinueLoop
    								If $1j[$1t][$1p] == $1u Then Return $1p
    							Else
    								If $22 And VarGetType($1j[$1p][$1t]) <> VarGetType($1u) Then ContinueLoop
    								If $1j[$1p][$1t] == $1u Then Return $1p
    							EndIf
    						Next
    					EndIf
    				Else
    					For $1p = $1v To $1w Step $23
    						If $1y = 3 Then
    							If $21 Then
    								If StringRegExp($1j[$1t][$1p], $1u) Then Return $1p
    							Else
    								If StringRegExp($1j[$1p][$1t], $1u) Then Return $1p
    							EndIf
    						Else
    							If $21 Then
    								If StringInStr($1j[$1t][$1p], $1u, $1x) > 0 Then Return $1p
    							Else
    								If StringInStr($1j[$1p][$1t], $1u, $1x) > 0 Then Return $1p
    							EndIf
    						EndIf
    					Next
    				EndIf
    			Next
    		Case Else
    			Return SetError(2, 0, -1)
    	EndSwitch
    	Return SetError(6, 0, -1)
    EndFunc   ;==>_14
    Global Const $26 = 0
    Global Const $27 = 1
    Global Const $28 = 0
    Global Const $29 = 2
    Global Const $2a = 0
    Global Const $2b = 1
    Global Const $2c = 2
    Global Const $2d = 4
    Func _1x($2e, ByRef $2f, $2g = $2b, $2h = "")
    	$2f = 0
    	If $2g = Default Then $2g = $2b
    	If $2h = Default Then $2h = ""
    	Local $2i = True
    	If BitAND($2g, $2c) Then
    		$2i = False
    		$2g -= $2c
    	EndIf
    	Local $2j = $f
    	If BitAND($2g, $2d) Then
    		$2j = $g
    		$2g -= $2d
    	EndIf
    	Local $2k = 0
    	If $2g <> $2b Then
    		$2g = $2a
    		$2k = $h
    	EndIf
    	If $2h Then
    		Local $2l = FileReadToArray($2e)
    		If @error Then Return SetError(@error, 0, 0)
    		Local $1l = UBound($2l) + $2g
    		If $2i Then
    			Local $1s = UBound(StringSplit($2l[0], $2h, $2j + $h))
    			Local $2m[$1l][$1s]
    			Local $2n, $2o
    			For $1p = 0 To $1l - $2g - 1
    				$2o = StringSplit($2l[$1p], $2h, $2j + $h)
    				$2n = UBound($2o)
    				If $2n <> $1s Then
    					Return SetError(3, 0, 0)
    				EndIf
    				For $1t = 0 To $2n - 1
    					$2m[$1p + $2g][$1t] = $2o[$1t]
    				Next
    			Next
    			If $1s < 2 Then Return SetError(4, 0, 0)
    			If $2g Then
    				$2m[0][0] = $1l - $2g
    				$2m[0][1] = $1s
    			EndIf
    		Else
    			Local $2m[$1l]
    			For $1p = 0 To $1l - $2g - 1
    				$2m[$1p + $2g] = StringSplit($2l[$1p], $2h, $2j + $2k)
    			Next
    			If $2g Then
    				$2m[0] = $1l - $2g
    			EndIf
    		EndIf
    		$2f = $2m
    	Else
    		If $2g Then
    			Local $2p = FileOpen($2e, $28)
    			If $2p = -1 Then Return SetError(1, 0, 0)
    			Local $2q = FileRead($2p)
    			FileClose($2p)
    			If StringLen($2q) Then
    				$2f = StringRegExp(@LF & $2q, "(?|(\N+)\z|(\N*)(?:\R))", 3)
    				$2f[0] = UBound($2f) - 1
    			Else
    				Return SetError(2, 0, 0)
    			EndIf
    		Else
    			$2f = FileReadToArray($2e)
    			If @error Then
    				$2f = 0
    				Return SetError(@error, 0, 0)
    			EndIf
    		EndIf
    	EndIf
    	Return 1
    EndFunc   ;==>_1x
    Func _1y($2e, Const ByRef $1j, $2r = Default, $2s = Default, $2h = "|")
    	Local $8 = 0
    	If Not IsArray($1j) Then Return SetError(2, 0, $8)
    	Local $2t = UBound($1j, $1)
    	If $2t > 2 Then Return SetError(4, 0, 0)
    	Local $2u = UBound($1j) - 1
    	If $2s = Default Or $2s > $2u Then $2s = $2u
    	If $2r < 0 Or $2r = Default Then $2r = 0
    	If $2r > $2s Then Return SetError(5, 0, $8)
    	If $2h = Default Then $2h = "|"
    	Local $2p = $2e
    	If IsString($2e) Then
    		$2p = FileOpen($2e, $29)
    		If $2p = -1 Then Return SetError(1, 0, $8)
    	EndIf
    	Local $2v = 0
    	$8 = 1
    	Switch $2t
    		Case 1
    			For $1p = $2r To $2s
    				If Not FileWrite($2p, $1j[$1p] & @CRLF) Then
    					$2v = 3
    					$8 = 0
    					ExitLoop
    				EndIf
    			Next
    		Case 2
    			Local $2w = ""
    			For $1p = $2r To $2s
    				$2w = $1j[$1p][0]
    				For $1t = 1 To UBound($1j, $3) - 1
    					$2w &= $2h & $1j[$1p][$1t]
    				Next
    				If Not FileWrite($2p, $2w & @CRLF) Then
    					$2v = 3
    					$8 = 0
    					ExitLoop
    				EndIf
    			Next
    	EndSwitch
    	If IsString($2e) Then FileClose($2p)
    	Return SetError($2v, 0, $8)
    EndFunc   ;==>_1y
    Func _24($2e, ByRef $2x, ByRef $2y, ByRef $2z, ByRef $30)
    	Local $1j = StringRegExp($2e, "^\h*((?:\\\\\?\\)*(\\\\[^\?\/\\]+|[A-Za-z]:)?(.*[\/\\]\h*)?((?:[^\.\/\\]|(?(?=\.[^\/\\]*\.)\.))*)?([^\/\\]*))$", $j)
    	If @error Then
    		ReDim $1j[5]
    		$1j[0] = $2e
    	EndIf
    	$2x = $1j[1]
    	If StringLeft($1j[2], 1) == "/" Then
    		$2y = StringRegExpReplace($1j[2], "\h*[\/\\]+\h*", "\/")
    	Else
    		$2y = StringRegExpReplace($1j[2], "\h*[\/\\]+\h*", "\\")
    	EndIf
    	$1j[2] = $2y
    	$2z = $1j[3]
    	$30 = $1j[4]
    	Return $1j
    EndFunc   ;==>_24
    Global Const $31 = '{66087055-AD66-4C7C-9A18-38A2310B8337}'
    Global Const $32 = '{E09D739D-CCD4-44EE-8EBA-3FBF8BE4FC58}'
    Global Const $33 = '{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}'
    Global Const $34 = 4
    Global Const $35 = 2
    Global Const $36 = 0x00021808
    Global Const $37 = "struct;long X;long Y;endstruct"
    Global Const $38 = "struct;long Left;long Top;long Right;long Bottom;endstruct"
    Global Const $39 = "struct;word Year;word Month;word Dow;word Day;word Hour;word Minute;word Second;word MSeconds;endstruct"
    Global Const $3a = "struct;byte GUID[16];ulong NumberOfValues;ulong Type;ptr Values;endstruct"
    Global Const $3b = "uint Count;" & $3a
    Global Const $3c = "uint Version;ptr Callback;bool NoThread;bool NoCodecs"
    Global Const $3d = "byte CLSID[16];byte FormatID[16];ptr CodecName;ptr DllName;ptr FormatDesc;ptr FileExt;" & "ptr MimeType;dword Flags;dword Version;dword SigCount;dword SigSize;ptr SigPattern;ptr SigMask"
    Global Const $3e = "uint cbSize;uint fMask;uint fStyle;dword clrFore;dword clrBack;ptr lpText;uint cch;" & "int iImage;hwnd hwndChild;uint cxMinChild;uint cyMinChild;uint cx;handle hbmBack;uint wID;uint cyChild;uint cyMaxChild;" & "uint cyIntegral;uint cxIdeal;lparam lParam;uint cxHeader" & ((@OSVersion = "WIN_XP") ? "" : ";" & $38 & ";uint uChevronState")
    Global Const $3f = "struct;ulong Data1;ushort Data2;ushort Data3;byte Data4[8];endstruct"
    Global Const $3g = Ptr(-1)
    Global Const $3h = Ptr(-1)
    Global Const $3i = 0x0100
    Global Const $3j = 0x2000
    Global Const $3k = 0x8000
    Global Const $3l = BitShift($3i, 8)
    Global Const $3m = BitShift($3j, 8)
    Global Const $3n = BitShift($3k, 8)
    Global Const $3o = "dword Size;dword Flags;handle hCursor;" & $37
    Global Const $3p = "bool Icon;dword XHotSpot;dword YHotSpot;handle hMask;handle hColor"
    Func _2t($3q, $3r, $3s, $3t, $3u, $3v, $3w, $3x, $3y)
    	Local $c = DllCall("gdi32.dll", "bool", "BitBlt", "handle", $3q, "int", $3r, "int", $3s, "int", $3t, "int", $3u, "handle", $3v, "int", $3w, "int", $3x, "dword", $3y)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_2t
    Func _30($3z)
    	Local $c = DllCall("user32.dll", "handle", "CopyIcon", "handle", $3z)
    	If @error Then Return SetError(@error, @extended, 0)
    	Return $c[0]
    EndFunc   ;==>_30
    Func _32($40, $3t, $3u)
    	Local $c = DllCall("gdi32.dll", "handle", "CreateCompatibleBitmap", "handle", $40, "int", $3t, "int", $3u)
    	If @error Then Return SetError(@error, @extended, 0)
    	Return $c[0]
    EndFunc   ;==>_32
    Func _33($40)
    	Local $c = DllCall("gdi32.dll", "handle", "CreateCompatibleDC", "handle", $40)
    	If @error Then Return SetError(@error, @extended, 0)
    	Return $c[0]
    EndFunc   ;==>_33
    Func _3g($40)
    	Local $c = DllCall("gdi32.dll", "bool", "DeleteDC", "handle", $40)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_3g
    Func _3h($41)
    	Local $c = DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $41)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_3h
    Func _3i($3z)
    	Local $c = DllCall("user32.dll", "bool", "DestroyIcon", "handle", $3z)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_3i
    Func _3m($40, $42, $43, $3z)
    	Local $c = DllCall("user32.dll", "bool", "DrawIcon", "handle", $40, "int", $42, "int", $43, "handle", $3z)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_3m
    Func _4n()
    	Local $44 = DllStructCreate($3o)
    	Local $45 = DllStructGetSize($44)
    	DllStructSetData($44, "Size", $45)
    	Local $46 = DllCall("user32.dll", "bool", "GetCursorInfo", "struct*", $44)
    	If @error Or Not $46[0] Then Return SetError(@error + 10, @extended, 0)
    	Local $47[5]
    	$47[0] = True
    	$47[1] = DllStructGetData($44, "Flags") <> 0
    	$47[2] = DllStructGetData($44, "hCursor")
    	$47[3] = DllStructGetData($44, "X")
    	$47[4] = DllStructGetData($44, "Y")
    	Return $47
    EndFunc   ;==>_4n
    Func _4o($4)
    	Local $c = DllCall("user32.dll", "handle", "GetDC", "hwnd", $4)
    	If @error Then Return SetError(@error, @extended, 0)
    	Return $c[0]
    EndFunc   ;==>_4o
    Func _4p()
    	Local $c = DllCall("user32.dll", "hwnd", "GetDesktopWindow")
    	If @error Then Return SetError(@error, @extended, 0)
    	Return $c[0]
    EndFunc   ;==>_4p
    Func _4y($3z)
    	Local $48 = DllStructCreate($3p)
    	Local $46 = DllCall("user32.dll", "bool", "GetIconInfo", "handle", $3z, "struct*", $48)
    	If @error Or Not $46[0] Then Return SetError(@error + 10, @extended, 0)
    	Local $49[6]
    	$49[0] = True
    	$49[1] = DllStructGetData($48, "Icon") <> 0
    	$49[2] = DllStructGetData($48, "XHotSpot")
    	$49[3] = DllStructGetData($48, "YHotSpot")
    	$49[4] = DllStructGetData($48, "hMask")
    	$49[5] = DllStructGetData($48, "hColor")
    	Return $49
    EndFunc   ;==>_4y
    Func _5g($4a)
    	Local $c = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $4a)
    	If @error Then Return SetError(@error, @extended, 0)
    	Return $c[0]
    EndFunc   ;==>_5g
    Func _5v($4b)
    	Local $4c = DllStructCreate($3f)
    	_5w($4b, $4c)
    	If @error Then Return SetError(@error + 10, @extended, 0)
    	Return $4c
    EndFunc   ;==>_5v
    Func _5w($4b, $4c)
    	Local $c = DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", $4b, "struct*", $4c)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_5w
    Func _72($4, $40)
    	Local $c = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $4, "handle", $40)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_72
    Func _74($40, $4d)
    	Local $c = DllCall("gdi32.dll", "handle", "SelectObject", "handle", $40, "handle", $4d)
    	If @error Then Return SetError(@error, @extended, False)
    	Return $c[0]
    EndFunc   ;==>_74
    Func _7w($4c)
    	Local $c = DllCall("ole32.dll", "int", "StringFromGUID2", "struct*", $4c, "wstr", "", "int", 40)
    	If @error Or Not $c[0] Then Return SetError(@error, @extended, "")
    	Return SetExtended($c[0], $c[2])
    EndFunc   ;==>_7w
    Func _89($4e, $4f = 0, $4g = True)
    	Local $4h = "wstr"
    	If Not IsString($4e) Then $4h = "struct*"
    	Local $c = DllCall("kernel32.dll", "int", "WideCharToMultiByte", "uint", $4f, "dword", 0, $4h, $4e, "int", -1, "ptr", 0, "int", 0, "ptr", 0, "ptr", 0)
    	If @error Or Not $c[0] Then Return SetError(@error + 20, @extended, "")
    	Local $4i = DllStructCreate("char[" & $c[0] & "]")
    	$c = DllCall("kernel32.dll", "int", "WideCharToMultiByte", "uint", $4f, "dword", 0, $4h, $4e, "int", -1, "struct*", $4i, "int", $c[0], "ptr", 0, "ptr", 0)
    	If @error Or Not $c[0] Then Return SetError(@error + 10, @extended, "")
    	If $4g Then Return DllStructGetData($4i, 1)
    	Return $4i
    EndFunc   ;==>_89
    Global Const $4j = 'struct;dword OSVersionInfoSize;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128];endstruct'
    Global Const $4k = _9d()
    Func _9d()
    	Local $4l = DllStructCreate($4j)
    	DllStructSetData($4l, 1, DllStructGetSize($4l))
    	Local $46 = DllCall('kernel32.dll', 'bool', 'GetVersionExW', 'struct*', $4l)
    	If @error Or Not $46[0] Then Return SetError(@error, @extended, 0)
    	Return BitOR(BitShift(DllStructGetData($4l, 2), -8), DllStructGetData($4l, 3))
    EndFunc   ;==>_9d
    Global $4m = 0
    Global $4n = 0
    Global $4o = 0
    Global $4p = True
    Func _gg($4q, $4r, $4s, $4t, $4u, $4v = 0x00021808)
    	Local $c = DllCall($4m, "int", "GdipCloneBitmapArea", "float", $4r, "float", $4s, "float", $4t, "float", $4u, "int", $4v, "handle", $4q, "handle*", 0)
    	If @error Then Return SetError(@error, @extended, 0)
    	If $c[0] Then Return SetError(10, $c[0], 0)
    	Return $c[7]
    EndFunc   ;==>_gg
    Func _gk($4q, $4w = 0)
    	Local $c = DllCall($4m, "int", "GdipCreateBitmapFromHBITMAP", "handle", $4q, "handle", $4w, "handle*", 0)
    	If @error Then Return SetError(@error, @extended, 0)
    	If $c[0] Then Return SetError(10, $c[0], 0)
    	Return $c[3]
    EndFunc   ;==>_gk
    Func _hi()
    	Local $4x = _hk()
    	Local $4y = _hn()
    	Local $4z = DllStructCreate("byte[" & $4y & "]")
    	Local $c = DllCall($4m, "int", "GdipGetImageEncoders", "uint", $4x, "uint", $4y, "struct*", $4z)
    	If @error Then Return SetError(@error, @extended, 0)
    	If $c[0] Then Return SetError(10, $c[0], 0)
    	Local $50 = DllStructGetPtr($4z)
    	Local $51, $52[$4x + 1][14]
    	$52[0][0] = $4x
    	For $53 = 1 To $4x
    		$51 = DllStructCreate($3d, $50)
    		$52[$53][1] = _7w(DllStructGetPtr($51, "CLSID"))
    		$52[$53][2] = _7w(DllStructGetPtr($51, "FormatID"))
    		$52[$53][3] = _89(DllStructGetData($51, "CodecName"))
    		$52[$53][4] = _89(DllStructGetData($51, "DllName"))
    		$52[$53][5] = _89(DllStructGetData($51, "FormatDesc"))
    		$52[$53][6] = _89(DllStructGetData($51, "FileExt"))
    		$52[$53][7] = _89(DllStructGetData($51, "MimeType"))
    		$52[$53][8] = DllStructGetData($51, "Flags")
    		$52[$53][9] = DllStructGetData($51, "Version")
    		$52[$53][10] = DllStructGetData($51, "SigCount")
    		$52[$53][11] = DllStructGetData($51, "SigSize")
    		$52[$53][12] = DllStructGetData($51, "SigPattern")
    		$52[$53][13] = DllStructGetData($51, "SigMask")
    		$50 += DllStructGetSize($51)
    	Next
    	Return $52
    EndFunc   ;==>_hi
    Func _hj($54)
    	Local $55 = _hi()
    	If @error Then Return SetError(@error, 0, "")
    	For $53 = 1 To $55[0][0]
    		If StringInStr($55[$53][6], "*." & $54) > 0 Then Return $55[$53][1]
    	Next
    	Return SetError(-1, -1, "")
    EndFunc   ;==>_hj
    Func _hk()
    	Local $c = DllCall($4m, "int", "GdipGetImageEncodersSize", "uint*", 0, "uint*", 0)
    	If @error Then Return SetError(@error, @extended, -1)
    	If $c[0] Then Return SetError(10, $c[0], -1)
    	Return $c[1]
    EndFunc   ;==>_hk
    Func _hn()
    	Local $c = DllCall($4m, "int", "GdipGetImageEncodersSize", "uint*", 0, "uint*", 0)
    	If @error Then Return SetError(@error, @extended, -1)
    	If $c[0] Then Return SetError(10, $c[0], -1)
    	Return $c[2]
    EndFunc   ;==>_hn
    Func _jt($56)
    	Local $c = DllCall($4m, "int", "GdipDisposeImage", "handle", $56)
    	If @error Then Return SetError(@error, @extended, False)
    	If $c[0] Then Return SetError(10, $c[0], False)
    	Return True
    EndFunc   ;==>_jt
    Func _jx($56)
    	Local $c = DllCall($4m, "int", "GdipGetImageHeight", "handle", $56, "uint*", 0)
    	If @error Then Return SetError(@error, @extended, -1)
    	If $c[0] Then Return SetError(10, $c[0], -1)
    	Return $c[2]
    EndFunc   ;==>_jx
    Func _k4($56)
    	Local $c = DllCall($4m, "int", "GdipGetImageWidth", "handle", $56, "uint*", -1)
    	If @error Then Return SetError(@error, @extended, -1)
    	If $c[0] Then Return SetError(10, $c[0], -1)
    	Return $c[2]
    EndFunc   ;==>_k4
    Func _k9($56, $2z, $57, $58 = 0)
    	Local $4c = _5v($57)
    	Local $c = DllCall($4m, "int", "GdipSaveImageToFile", "handle", $56, "wstr", $2z, "struct*", $4c, "struct*", $58)
    	If @error Then Return SetError(@error, @extended, False)
    	If $c[0] Then Return SetError(10, $c[0], False)
    	Return True
    EndFunc   ;==>_k9
    Func _l3(ByRef $58, $4b, $59, $5a, $5b)
    	Local $4x = DllStructGetData($58, "Count")
    	Local $5c = DllStructGetPtr($58, "GUID") + ($4x * _l5())
    	Local $5d = DllStructCreate($3a, $5c)
    	_5w($4b, $5c)
    	DllStructSetData($5d, "Type", $5a)
    	DllStructSetData($5d, "NumberOfValues", $59)
    	DllStructSetData($5d, "Values", $5b)
    	DllStructSetData($58, "Count", $4x + 1)
    EndFunc   ;==>_l3
    Func _l4($4x)
    	Local $5e = $3b
    	For $1p = 2 To $4x
    		$5e &= ";struct;byte[16];ulong;ulong;ptr;endstruct"
    	Next
    	Return DllStructCreate($5e)
    EndFunc   ;==>_l4
    Func _l5()
    	Local $5d = DllStructCreate($3a)
    	Return DllStructGetSize($5d)
    EndFunc   ;==>_l5
    Func _ny()
    	If $4m = 0 Then Return SetError(-1, -1, False)
    	$4n -= 1
    	If $4n = 0 Then
    		DllCall($4m, "none", "GdiplusShutdown", "ulong_ptr", $4o)
    		DllClose($4m)
    		$4m = 0
    	EndIf
    	Return True
    EndFunc   ;==>_ny
    Func _nz($5f = Default, $5g = False)
    	$4n += 1
    	If $4n > 1 Then Return True
    	If $5f = Default Then $5f = "gdiplus.dll"
    	$4m = DllOpen($5f)
    	If $4m = -1 Then
    		$4n = 0
    		Return SetError(1, 2, False)
    	EndIf
    	Local $5h = FileGetVersion($5f)
    	$5h = StringSplit($5h, ".")
    	If $5h[1] > 5 Then $4p = False
    	Local $5i = DllStructCreate($3c)
    	Local $5j = DllStructCreate("ulong_ptr Data")
    	DllStructSetData($5i, "Version", 1)
    	Local $c = DllCall($4m, "int", "GdiplusStartup", "struct*", $5j, "struct*", $5i, "ptr", 0)
    	If @error Then Return SetError(@error, @extended, False)
    	If $c[0] Then Return SetError(10, $c[0], False)
    	$4o = DllStructGetData($5j, "Data")
    	If $5g Then Return $4m
    	Return SetExtended($5h[1], True)
    EndFunc   ;==>_nz
    Func _ob($2z, $5k = True)
    	Local $4a = _oc(".\:", $2z)
    	If ($4a > 0) And (StringMid($2z, $4a, 1) = '.') Then
    		If $5k Then
    			Return StringMid($2z, $4a + 1)
    		Else
    			Return StringMid($2z, $4a)
    		EndIf
    	Else
    		Return ""
    	EndIf
    EndFunc   ;==>_ob
    Func _oc($5l, $5m)
    	Local $2h, $5n
    	For $53 = 1 To StringLen($5l)
    		$2h = StringMid($5l, $53, 1)
    		$5n = StringInStr($5m, $2h, 0, -1)
    		If $5n > 0 Then Return $5n
    	Next
    EndFunc   ;==>_oc
    Global $5o = $36
    Global $5p = 100
    Global $5q = 24
    Global $5r = $35
    Global Const $5s = 0
    Global Const $5t = 1
    Global Const $5u = 0x00CC0020
    Func _p6($2z = "", $5v = 0, $5w = 0, $5x = -1, $5y = -1, $5z = True)
    	Local $60 = False
    	If $5x = -1 Then $5x = _5g($5s) - 1
    	If $5y = -1 Then $5y = _5g($5t) - 1
    	If $5x < $5v Then Return SetError(-1, 0, $60)
    	If $5y < $5w Then Return SetError(-2, 0, $60)
    	Local $61 = ($5x - $5v) + 1
    	Local $62 = ($5y - $5w) + 1
    	Local $4 = _4p()
    	Local $63 = _4o($4)
    	Local $64 = _33($63)
    	Local $65 = _32($63, $61, $62)
    	_74($64, $65)
    	_2t($64, 0, 0, $61, $62, $63, $5v, $5w, $5u)
    	If $5z Then
    		Local $47 = _4n()
    		If Not @error And $47[1] Then
    			$5z = True
    			Local $3z = _30($47[2])
    			Local $49 = _4y($3z)
    			If Not @error Then
    				_3h($49[4])
    				If $49[5] <> 0 Then _3h($49[5])
    				_3m($64, $47[3] - $49[2] - $5v, $47[4] - $49[3] - $5w, $3z)
    			EndIf
    			_3i($3z)
    		EndIf
    	EndIf
    	_72($4, $63)
    	_3g($64)
    	If $2z = "" Then Return $65
    	$60 = _p8($2z, $65, True)
    	Return SetError(@error, @extended, $60)
    EndFunc   ;==>_p6
    Func _p8($2z, $4q, $66 = True)
    	_nz()
    	If @error Then Return SetError(-1, -1, False)
    	Local $67 = StringUpper(_ob($2z))
    	Local $68 = _hj($67)
    	If $68 = "" Then Return SetError(-2, -2, False)
    	Local $56 = _gk($4q)
    	If @error Then Return SetError(-3, -3, False)
    	Local $69, $58
    	Switch $67
    		Case "BMP"
    			Local $42 = _k4($56)
    			Local $43 = _jx($56)
    			Local $6a = _gg($56, 0, 0, $42, $43, $5o)
    			_jt($56)
    			$56 = $6a
    		Case "JPG", "JPEG"
    			$58 = _l4(1)
    			$69 = DllStructCreate("int Quality")
    			DllStructSetData($69, "Quality", $5p)
    			_l3($58, $33, 1, $34, DllStructGetPtr($69))
    		Case "TIF", "TIFF"
    			$58 = _l4(2)
    			$69 = DllStructCreate("int ColorDepth;int Compression")
    			DllStructSetData($69, "ColorDepth", $5q)
    			DllStructSetData($69, "Compression", $5r)
    			_l3($58, $31, 1, $34, DllStructGetPtr($69, "ColorDepth"))
    			_l3($58, $32, 1, $34, DllStructGetPtr($69, "Compression"))
    	EndSwitch
    	Local $6b = 0
    	If IsDllStruct($58) Then $6b = $58
    	Local $60 = _k9($56, $2z, $68, $6b)
    	_jt($56)
    	If $66 Then _3h($4q)
    	_ny()
    	Return SetError($60 = False, 0, $60)
    EndFunc   ;==>_p8
    Global Const $6c = 1
    Global Const $6d = 2
    Global Const $6e = 0x001D
    Global Const $6f = 0x001E
    Global Const $6g = 0x001F
    Global Const $6h = 0x0020
    Global Const $6i = 0x1003
    Global Const $6j = 0x0028
    Global Const $6k = 0x0029
    Global Const $6l = 0x007F
    Global Const $6m = 0x0400
    Func _q5($6n = 0, $6o = 0, $2g = 0, $6p = '')
    	If Not $6n Then $6n = 0x0400
    	Local $6q = 'wstr'
    	If Not StringStripWS($6p, $d + $e) Then
    		$6q = 'ptr'
    		$6p = 0
    	EndIf
    	Local $46 = DllCall('kernel32.dll', 'int', 'GetDateFormatW', 'dword', $6n, 'dword', $2g, 'struct*', $6o, $6q, $6p, 'wstr', '', 'int', 2048)
    	If @error Or Not $46[0] Then Return SetError(@error, @extended, '')
    	Return $46[5]
    EndFunc   ;==>_q5
    Func _q8($6n, $5a)
    	Local $46 = DllCall('kernel32.dll', 'int', 'GetLocaleInfoW', 'dword', $6n, 'dword', $5a, 'wstr', '', 'int', 2048)
    	If @error Or Not $46[0] Then Return SetError(@error + 10, @extended, '')
    	Return $46[3]
    EndFunc   ;==>_q8
    Func _qt($6r, $4v = Default)
    	Local Const $6s = 128
    	If $4v = Default Then $4v = 0
    	$6r = Int($6r)
    	If $6r < 1 Or $6r > 7 Then Return SetError(1, 0, "")
    	Local $6o = DllStructCreate($39)
    	DllStructSetData($6o, "Year", BitAND($4v, $6s) ? 2007 : 2006)
    	DllStructSetData($6o, "Month", 1)
    	DllStructSetData($6o, "Day", $6r)
    	Return _q5(BitAND($4v, $6d) ? $6m : $6l, $6o, 0, BitAND($4v, $6c) ? "ddd" : "dddd")
    EndFunc   ;==>_qt
    Func _qw($6t)
    	If StringIsInt($6t) Then
    		Select
    			Case Mod($6t, 4) = 0 And Mod($6t, 100) <> 0
    				Return 1
    			Case Mod($6t, 400) = 0
    				Return 1
    			Case Else
    				Return 0
    		EndSelect
    	EndIf
    	Return SetError(1, 0, 0)
    EndFunc   ;==>_qw
    Func _qx($1m)
    	$1m = Int($1m)
    	Return $1m >= 1 And $1m <= 12
    EndFunc   ;==>_qx
    Func _qy($6u)
    	Local $6v[4], $6w[4]
    	_r7($6u, $6v, $6w)
    	If Not StringIsInt($6v[1]) Then Return 0
    	If Not StringIsInt($6v[2]) Then Return 0
    	If Not StringIsInt($6v[3]) Then Return 0
    	$6v[1] = Int($6v[1])
    	$6v[2] = Int($6v[2])
    	$6v[3] = Int($6v[3])
    	Local $6x = _rq($6v[1])
    	If $6v[1] < 1000 Or $6v[1] > 2999 Then Return 0
    	If $6v[2] < 1 Or $6v[2] > 12 Then Return 0
    	If $6v[3] < 1 Or $6v[3] > $6x[$6v[2]] Then Return 0
    	If $6w[0] < 1 Then Return 1
    	If $6w[0] < 2 Then Return 0
    	If $6w[0] = 2 Then $6w[3] = "00"
    	If Not StringIsInt($6w[1]) Then Return 0
    	If Not StringIsInt($6w[2]) Then Return 0
    	If Not StringIsInt($6w[3]) Then Return 0
    	$6w[1] = Int($6w[1])
    	$6w[2] = Int($6w[2])
    	$6w[3] = Int($6w[3])
    	If $6w[1] < 0 Or $6w[1] > 23 Then Return 0
    	If $6w[2] < 0 Or $6w[2] > 59 Then Return 0
    	If $6w[3] < 0 Or $6w[3] > 59 Then Return 0
    	Return 1
    EndFunc   ;==>_qy
    Func _r6($6u, $6y)
    	Local $6v[4], $6w[4]
    	Local $6z = "", $70 = ""
    	Local $71, $72, $73 = ""
    	If Not _qy($6u) Then
    		Return SetError(1, 0, "")
    	EndIf
    	If $6y < 0 Or $6y > 5 Or Not IsInt($6y) Then
    		Return SetError(2, 0, "")
    	EndIf
    	_r7($6u, $6v, $6w)
    	Switch $6y
    		Case 0
    			$73 = _q8($6m, $6g)
    			If Not @error And Not ($73 = '') Then
    				$6z = $73
    			Else
    				$6z = "M/d/yyyy"
    			EndIf
    			If $6w[0] > 1 Then
    				$73 = _q8($6m, $6i)
    				If Not @error And Not ($73 = '') Then
    					$70 = $73
    				Else
    					$70 = "h:mm:ss tt"
    				EndIf
    			EndIf
    		Case 1
    			$73 = _q8($6m, $6h)
    			If Not @error And Not ($73 = '') Then
    				$6z = $73
    			Else
    				$6z = "dddd, MMMM dd, yyyy"
    			EndIf
    		Case 2
    			$73 = _q8($6m, $6g)
    			If Not @error And Not ($73 = '') Then
    				$6z = $73
    			Else
    				$6z = "M/d/yyyy"
    			EndIf
    		Case 3
    			If $6w[0] > 1 Then
    				$73 = _q8($6m, $6i)
    				If Not @error And Not ($73 = '') Then
    					$70 = $73
    				Else
    					$70 = "h:mm:ss tt"
    				EndIf
    			EndIf
    		Case 4
    			If $6w[0] > 1 Then
    				$70 = "hh:mm"
    			EndIf
    		Case 5
    			If $6w[0] > 1 Then
    				$70 = "hh:mm:ss"
    			EndIf
    	EndSwitch
    	If $6z <> "" Then
    		$73 = _q8($6m, $6e)
    		If Not @error And Not ($73 = '') Then
    			$6z = StringReplace($6z, "/", $73)
    		EndIf
    		Local $74 = _r8($6v[1], $6v[2], $6v[3])
    		$6v[3] = StringRight("0" & $6v[3], 2)
    		$6v[2] = StringRight("0" & $6v[2], 2)
    		$6z = StringReplace($6z, "d", "@")
    		$6z = StringReplace($6z, "m", "#")
    		$6z = StringReplace($6z, "y", "&")
    		$6z = StringReplace($6z, "@@@@", _qt($74, 0))
    		$6z = StringReplace($6z, "@@@", _qt($74, 1))
    		$6z = StringReplace($6z, "@@", $6v[3])
    		$6z = StringReplace($6z, "@", StringReplace(StringLeft($6v[3], 1), "0", "") & StringRight($6v[3], 1))
    		$6z = StringReplace($6z, "####", _rb($6v[2], 0))
    		$6z = StringReplace($6z, "###", _rb($6v[2], 1))
    		$6z = StringReplace($6z, "##", $6v[2])
    		$6z = StringReplace($6z, "#", StringReplace(StringLeft($6v[2], 1), "0", "") & StringRight($6v[2], 1))
    		$6z = StringReplace($6z, "&&&&", $6v[1])
    		$6z = StringReplace($6z, "&&", StringRight($6v[1], 2))
    	EndIf
    	If $70 <> "" Then
    		$73 = _q8($6m, $6j)
    		If Not @error And Not ($73 = '') Then
    			$71 = $73
    		Else
    			$71 = "AM"
    		EndIf
    		$73 = _q8($6m, $6k)
    		If Not @error And Not ($73 = '') Then
    			$72 = $73
    		Else
    			$72 = "PM"
    		EndIf
    		$73 = _q8($6m, $6f)
    		If Not @error And Not ($73 = '') Then
    			$70 = StringReplace($70, ":", $73)
    		EndIf
    		If StringInStr($70, "tt") Then
    			If $6w[1] < 12 Then
    				$70 = StringReplace($70, "tt", $71)
    				If $6w[1] = 0 Then $6w[1] = 12
    			Else
    				$70 = StringReplace($70, "tt", $72)
    				If $6w[1] > 12 Then $6w[1] = $6w[1] - 12
    			EndIf
    		EndIf
    		$6w[1] = StringRight("0" & $6w[1], 2)
    		$6w[2] = StringRight("0" & $6w[2], 2)
    		$6w[3] = StringRight("0" & $6w[3], 2)
    		$70 = StringReplace($70, "hh", StringFormat("%02d", $6w[1]))
    		$70 = StringReplace($70, "h", StringReplace(StringLeft($6w[1], 1), "0", "") & StringRight($6w[1], 1))
    		$70 = StringReplace($70, "mm", StringFormat("%02d", $6w[2]))
    		$70 = StringReplace($70, "ss", StringFormat("%02d", $6w[3]))
    		$6z = StringStripWS($6z & " " & $70, $d + $e)
    	EndIf
    	Return $6z
    EndFunc   ;==>_r6
    Func _r7($6u, ByRef $75, ByRef $76)
    	Local $77 = StringSplit($6u, " T")
    	If $77[0] > 0 Then $75 = StringSplit($77[1], "/-.")
    	If $77[0] > 1 Then
    		$76 = StringSplit($77[2], ":")
    		If UBound($76) < 4 Then ReDim $76[4]
    	Else
    		Dim $76[4]
    	EndIf
    	If UBound($75) < 4 Then ReDim $75[4]
    	For $78 = 1 To 3
    		If StringIsInt($75[$78]) Then
    			$75[$78] = Int($75[$78])
    		Else
    			$75[$78] = -1
    		EndIf
    		If StringIsInt($76[$78]) Then
    			$76[$78] = Int($76[$78])
    		Else
    			$76[$78] = 0
    		EndIf
    	Next
    	Return 1
    EndFunc   ;==>_r7
    Func _r8($6t, $79, $7a)
    	If Not _qy($6t & "/" & $79 & "/" & $7a) Then
    		Return SetError(1, 0, "")
    	EndIf
    	Local $7b = Int((14 - $79) / 12)
    	Local $7c = $6t - $7b
    	Local $7d = $79 + (12 * $7b) - 2
    	Local $7e = Mod($7a + $7c + Int($7c / 4) - Int($7c / 100) + Int($7c / 400) + Int((31 * $7d) / 12), 7)
    	Return $7e + 1
    EndFunc   ;==>_r8
    Func _rb($7f, $4v = Default)
    	If $4v = Default Then $4v = 0
    	$7f = Int($7f)
    	If Not _qx($7f) Then Return SetError(1, 0, "")
    	Local $6o = DllStructCreate($39)
    	DllStructSetData($6o, "Year", @YEAR)
    	DllStructSetData($6o, "Month", $7f)
    	DllStructSetData($6o, "Day", 1)
    	Return _q5(BitAND($4v, $6d) ? $6m : $6l, $6o, 0, BitAND($4v, $6c) ? "MMM" : "MMMM")
    EndFunc   ;==>_rb
    Func _rf()
    	Return _r6(@YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC, 0)
    EndFunc   ;==>_rf
    Func _rq($6t)
    	Local $7g = [12, 31, (_qw($6t) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    	Return $7g
    EndFunc   ;==>_rq
    Opt("wintitlematchmode", 2)
    Global $7h = 5
    Global $7i
    Global $7j
    Global $1p
    Global $7k
    Global $7l
    $7m = True
    Global $7n = "c:\temp"
    Global $7o = "debugconsole"
    Global $7p = "(?i)(?:ares|midas)"
    Global $7q = "(?i)(g:|b:)"
    Global $7r = "G:\skydrive\conf\lang\autoit\tamx2txt\tamxlist.txt"
    Global $7s = "G:\skydrive\conf\lang\autoit\tamx2txt\tamxlistdone.txt"
    Global $7t = "G:;;skydrive;;conf;;lang;;autoit;;tamx2txt"
    Global $7u[2][2] = [["ares;;g", "midas;;c"], ["G:", "B:"]]
    Global $7k
    Global $7v, $7w
    Global $7x = 100
    Global $7y = "(?i).*"
    Global $7z = True
    Global $80 = True
    Global $7m = True
    Local $81 = True
    Global $82 = True
    Global $83
    Global $84
    Global $85
    If $82 Then
    	$83 = ""
    	$84 = "notepad.exe"
    	If @ComputerName = "ARES" Then
    		$85 = "TextPad"
    	Else
    		$85 = "Notepad"
    	EndIf
    Else
    	$83 = "C:\Program Files (x86)\Testing Anywhere 9.2\Testing Anywhere"
    	$84 = "TATestEditor.exe"
    	$85 = "Testing Anywhere Client - Test Editor"
    EndIf
    _tv($7y, 1)
    Func _tq($86, $7u)
    	Local $87
    	$87 = StringStripWS($86, 3)
    	$87 = StringRegExpReplace($87, "^file://", "")
    	$87 = StringStripWS($87, 3)
    	For $1p = 0 To UBound($7u, 2) - 1
    		$88 = $7u[1][$1p]
    		$89 = $7u[0][$1p]
    		_tw(1149, "cleanedpath~~" & $87 & "~~$searchstring~~" & "^\b" & $88 & "\b" & "~~$replacestring:" & $89)
    		$87 = StringRegExpReplace($87, "(?i)^" & $88 & "", ";;;;" & $89)
    		$8a = @error
    		If @extended And $7m Then _tw(1152, "~~replaced:$toclean~~" & $86 & "~~$cleaned~~" & $87)
    		If $8a Then
    			_tw(1154, "~~pathconversion~~@error~~" & @error & "~~extended~~" & @extended)
    			Return 0
    		EndIf
    	Next
    	Return $87
    EndFunc   ;==>_tq
    Func _tr($8b, $7t = "g:;;skydrive;;conf;;lang;;autoit;;tamx2txt")
    	$8c = _tq($8b, $7p)
    	_tw(1162, "input:$txtpath~~" & $8c & "~~$searchstring~~" & "(?:;;{2})(" & $7p & ".*)" & "~~replace~~" & $7t & ";;" & "$1" & ".txt")
    	$8c = StringRegExpReplace($8c, "(?:;;{2})(" & $7p & ".*)", $7t & ";;" & "$1" & ".txt")
    	$8a = @error
    	If @extended And $7m Then _tw(1165, "~~replaced $tamxpath~~" & $8b & "~~$txtpath~~" & $8c)
    	If $8a Then
    		_tw(1167, "~~pathconversion~~$tamxpath~~" & $8b & "~~@error~~" & @error & "~~extended~~" & @extended)
    		Return 0
    	Else
    		If $7m Then _tw(1170, "result:$txtpath~~" & $8c)
    		Return $8c
    	EndIf
    EndFunc   ;==>_tr
    Func _ts($8c, $7t = "g:;;skydrive;;conf;;lang;;autoit;;tamx2txt")
    	$8b = _tq($8c, $7q)
    	_tw(1176, "~~pathconversion~~$tamxpath~~" & $8b & @CRLF)
    	_tw(1177, "$tamxpath~~" & $8b & "~~$searchstring" & "(?i:)(?:;;{2})(" & $7t & ";;" & $7p & ".*)" & ".(txt|tax)" & "~~$replacestring~~" & "$1" & ".tamx")
    	$8b = StringRegExpReplace($8b, "(?i:)(?:;;{2})" & $7t & ";;(" & $7p & ".*)" & ".(txt|tax)", "$1" & ".tamx")
    	$8a = @error
    	If @extended Or $7m Then _tw(1180, "~~replaced $txtpath~~" & $8c & "~~to $tamxpath~~" & $8b)
    	If $8a Then
    		_tw(1182, "~~pathconversion~~$txtpath~~" & $8c & "~~@error~~" & @error & "~~extended~~" & @extended)
    		Return 0
    	Else
    		Return $8b
    	EndIf
    EndFunc   ;==>_ts
    Func _tt($8d, $7z = 1)
    	Local $8c, $8b, $8e, $8f, $8g, $7i
    	$7i = _tu($8d, $8c, $8b)
    	If ($7i = 0) Then
    		_tw(1192, "getistoeclude return for $path~~" & $8d & "~~WARNING: cannot convert")
    		Return 1
    	EndIf
    	$8g = Not (FileExists($8b))
    	If $8g Then
    		_tw(1197, "getistoeclude return for $path~~" & $8d & "~~WARNING: excluding not found $tamxpath~~" & $8b)
    		Return 1
    	EndIf
    	$8f = Not (FileExists($8c))
    	If $8f Then
    		_tw(1202, "getistoeclude:$txtdoesnotexist: let's include it to make it exist~~" & $8c)
    		Return 0
    	Else
    		$8h = FileGetTime($8b, $26, $27)
    		$8i = FileGetTime($8c, $26, $27)
    		$8e = ($8h <= $8i) And (Not $7z) Or ((Not ($8h > $8i)) And $7z)
    		_tw(1208, "getistoeclude return for $path~~" & $8d & "~~$isnotupdated~~" & $8e)
    		Return $8e
    	EndIf
    EndFunc   ;==>_tt
    Func _tu($8d, ByRef $8c, ByRef $8b)
    	$8j = _tq($8d, $7q)
    	_tw(1214, "~~pathconversion~~$path~~" & $8d & "~~$cleanedpath~~" & $8j)
    	If ($7z And (StringRight($8d, 5) = ".tamx")) Then
    		$8b = $8d
    		$8c = _tr($8d)
    	Else
    		If (Not $7z) And ((StringRight($8d, 4) = ".txt") Or (StringRight($8d, 4) = ".tax")) Then
    			$8c = $8d
    			$8b = _ts($8d)
    		Else
    			_tw(1223, "~~bad path~~@error~~" & $8d & @CRLF)
    			Return 0
    		EndIf
    	EndIf
    	Return 1
    EndFunc   ;==>_tu
    Func _tv($7y, $7z = 1)
    	$7x = $7h * $7x
    	_1x($7r, $7k, 0)
    	Local $8j
    	Local $8k = 0
    	Local $8l = 0
    	Local $8m = (UBound($7k) - 1)
    	_tw(1236, "$upper" & $8m)
    	For $1p = $8m To 0 Step -1
    		$8j = _tq($7k[$1p], $7u)
    		_tw(1239, "$cleanedpath~~" & $8j)
    		$8k = Not (StringRegExp($8j, $7y, $i))
    		If Not $8k Then $8l = _tt($8j, $7z)
    		If $8k Or $8l Then
    			_tw(1243, "~~At least 1 Sanity Check failed for:~~" & $7k[$1p] & "~~$isexcludedbyfilemaskregex~~" & $8k & "~~$istoExclude~~" & $8l)
    			$7i = _r($7k, $1p)
    			If @error Then
    				_tw(1246, "~~deleting~~" & $7k[$1p] & "~~@error~~" & @error & "~~extended~~" & @extended & @CRLF)
    			Else
    				_tw(1248, "~~deleted~~" & $8j & "~~files left:" & $7i)
    			EndIf
    		Else
    			$7k[$1p] = $8j
    		EndIf
    	Next
    	For $1p = 0 To UBound($7k) - 1
    		Local $8n = $7k[$1p]
    		_tw(1256, "Worker thread for $filepath~~" & $8n)
    		$8o = FileReadToArray($7s)
    		If @error Then
    			_tw(1259, "error opening~~" & $7s)
    		Else
    			If (_14($8o, $8n) > 0) Then
    				_tw(1262, "skipping~~" & $8n)
    				ContinueLoop
    			EndIf
    		EndIf
    		$7v = ProcessExists($84)
    		_tw(1267, "for clean slate close $taepid ~~" & $7v)
    		While $7v
    			ProcessClose($7v)
    			_tw(1270, "processclosed for:" & $7v)
    			$7v = ProcessExists($84)
    			If @error Then _tw(1272, "prcoessclose error~~" & @error)
    			_tw(1273, "processexists still?~~" & $7v)
    			If @error Then _tw(1274, "prcoessclose error~~" & @error)
    		WEnd
    		Local $8p
    		If (StringLen($83) > 0) Then $8p = "\"
    		$8q = '"' & $83 & $8p & $84 & '" "' & $8n & '"'
    		$7v = Run($8q)
    		_tw(1280, "opened $taepid~~" & $7v)
    		If $7z Then
    			If $80 Then
    				Local $8c, $8b
    				$7i = _tu($8n, $8c, $8b)
    				If ($7i = 0) Or $7m Then
    					_tw(1286, "~~converting $filepath~~" & $8n & "~~ result $ret~~" & $7i & "~~to $txtpath~~" & $8c & "~~$tamxpath~~" & $8b)
    				EndIf
    				If Not $82 Then
    					$7i = WinActivate($85, "")
    					_tw(1290, " winactivate $ret~~" & $7i & @CRLF)
    					Sleep($7x)
    					Send("{ALTDOWN}")
    					Sleep($7x)
    					Send("f")
    					Sleep($7x)
    					Send("t")
    					Sleep($7x)
    					Send("{ALTUP}")
    					Sleep($7x)
    					$7i = WinActivate("Save as text File", "")
    					_tw(1301, " winactivate $ret~~" & $7i & @CRLF)
    					Sleep($7x)
    					$7i = ControlSetText("Save as text File", "", "WindowsForms10.EDIT.app.0.ea7f4a_r11_ad11", $8c)
    					_tw(1304, " controlsettext $ret~~" & $7i & @CRLF)
    					Sleep($7x)
    					$7i = ControlClick("Save as text file", "", "WindowsForms10.BUTTON.app.0.ea7f4a_r11_ad13")
    					_tw(1307, "controlclick $ret~~" & $7i & @CRLF)
    					Sleep($7x)
    					Local $7w
    					$7w = ProcessExists("notepad.exe")
    					If $7w Then ProcessClose($7w)
    					If @error Then _tw(1312, "notepadclose error~~" & @error)
    				EndIf
    				If ($81) Then
    					$7i = WinActivate($85, "")
    					If $7i = 0 Then
    						_tw(1317, "cannot winactivate")
    						Sleep(5 * $7x)
    						$7i = WinActivate($85, "")
    						If $7i <> 0 Then _tw(1320, "could winactivate try2")
    					EndIf
    					If Not $82 Then
    						ControlClick("Testing Anywhere Client - Test Editor", "", "WindowsForms10.Window.8.app.0.ea7f4a_r11_ad125", "left", 96, 16)
    						Sleep(5 * $7x)
    					EndIf
    					Local $8r = True
    					Local $8s[1]
    					Local $8t = 0
    					Local $8u = 0
    					$7i = WinActivate($85, "")
    					If $7i = 0 Then
    						_tw(1332, "cannot winactivate")
    						Sleep(5 * $7x)
    						$7i = WinActivate($85, "")
    						If $7i <> 0 Then _tw(1335, "could winactivate try2")
    					EndIf
    					While ($8r)
    						$8t = $8t + 1
    						ReDim $8s[$8t + 1]
    						Sleep($7x)
    						Send("{end}")
    						Sleep($7x)
    						Send("{space}")
    						Sleep($7x)
    						Send("{left}")
    						Sleep($7x)
    						Send("+{home}")
    						Sleep($7x)
    						Send("^c")
    						Sleep($7x)
    						Send("{down}")
    						Sleep($7x)
    						Local $8v = ClipGet()
    						Sleep($7x)
    						$8v = StringStripWS($8v, 3)
    						If @error Then
    							_tw(1357, "error:Clipget $astrlines[$i] error~~" & @error)
    						EndIf
    						Sleep($7x)
    						$8s[$8t] = $8v
    						Local $8w, $8x, $8u = 0
    						If Mod($8t, 5) = 0 Then
    							_tw(1363, "$iteration~~" & $8t)
    							If ($8s[$8t] = $8s[$8t - 1]) Then
    								_tw(1365, "At $iteration, EQUAL~~" & $8t & "~~test~~" & $8s[$8t] & "<>?>" & $8s[$8t - 1])
    								If $8s[$8t] = $8s[$8t - 2] Then
    									_tw(1367, "At $iteration, EQUAL~~" & $8t & "~~test~~" & $8s[$8t] & "<>?>" & $8s[$8t - 1])
    									If $8s[$8t] = $8s[$8t - 3] Then
    										_tw(1369, "At $iteration, EQUAL~~" & $8t & "~~test~~" & $8s[$8t] & "<>?>" & $8s[$8t - 1])
    										If $8s[$8t] = $8s[$8t - 4] Then
    											_tw(1371, "At $iteration, EQUAL~~" & $8t & "~~test~~" & $8s[$8t] & "<>?>" & $8s[$8t - 1])
    											If $8s[$8t] = $8s[$8t - 5] Then
    												$8r = False
    												_tw(1374, "$notendoffile" & $8r)
    												$8u = 5
    												_tw(1376, "now:" & $8u)
    												If (UBound($8s) >= 9) Then
    													If $8s[$8t] = $8s[$8t - 6] Then
    														$8u = $8u + 1
    														_tw(1380, "now:" & $8u)
    														If $8s[$8t] = $8s[$8t - 7] Then
    															$8u = $8u + 1
    															_tw(1383, "now:" & $8u)
    															If $8s[$8t] = $8s[$8t - 8] Then
    																$8u = $8u + 1
    																_tw(1386, "now:" & $8u)
    																If $8s[$8t] = $8s[$8t - 9] Then
    																	$8u = $8u + 1
    																	_tw(1389, "now:" & $8u)
    																EndIf
    															EndIf
    														EndIf
    													EndIf
    												EndIf
    											EndIf
    										EndIf
    									EndIf
    								EndIf
    							Else
    								_tw(1400, "At $iteration, UNEQUAL~~" & $8t & "~~test~~" & $8s[$8t] & "<>?>" & $8s[$8t - 1])
    							EndIf
    						EndIf
    						_tw(1403, "$notendoffile before wend~~" & $8r)
    						Sleep($7x)
    					WEnd
    					Local $8x = 1
    					Local $2x = "", $2y = "", $2z = "", $30 = ""
    					Local $8y = _24($8n, $2x, $2y, $2z, $30)
    					If Not (FileExists($2x & "\" & $2y)) Then DirCreate($2x & "\" & $2y)
    					$8z = $2x & $2y & $2z & ".tax"
    					_tw(1411, "$filepathTAX~~" & $8z)
    					Sleep($7x)
    					For $8x = 1 To $8u
    						$8w = _r($8s, UBound($8s) - 1)
    					Next
    					Sleep($7x)
    					$7i = _1y($8z, $8s, 1)
    					If ($7i = 0) Then
    						_tw(1419, "_FileWriteFromArray @error~~" & _1y)
    					EndIf
    					Sleep($7x)
    					$7i = FileWriteLine($7s, $8n)
    					If $7i = 0 Then _tw(1423, "failed writing log~~" & $8n)
    				EndIf
    			EndIf
    		Else
    			Sleep($7x)
    			MsgBox(0, "Not implemented!", "and likely unimplementable! I will now eject you...")
    			Exit
    			$7i = WinActivate($85, "")
    			If $7i = 0 Then
    				$7i = WinActivate($85, "")
    				Sleep($7x)
    				If $7i = 0 Then
    					Send("{!TAB}")
    					Sleep($7x)
    					$7i = WinActivate($85, "")
    					_tw(1438, "@error=" + @error + ". comment: " + ("To activate, had to resort to ALT +TAB." & @CRLF))
    					If $7i = 0 Then
    						_tw(1440, "@error=" + @error + ". comment: " + ("Cannot activate " & $85 & "~~exiting!"))
    						Exit
    					EndIf
    				EndIf
    			EndIf
    			Sleep($7x)
    			If @error Then
    				_tw(1447, "~~@error~~" & @error & "~~Activated~~" & $85)
    			EndIf
    			Send("^a")
    			Sleep($7x)
    			Send("{DEL}")
    			Send("^a")
    			Sleep($7x)
    			Send("{DEL}")
    			Sleep($7x)
    			For $1p = 0 To UBound($8s) - 1
    				ClipPut($8s[$1p])
    				Send("{home}")
    				Sleep($7x)
    				Send("+{end}")
    				Send("^v")
    				Sleep($7x)
    				Send("{enter}")
    				Sleep($7x)
    				If @error Then _tw(1465, "@error=" + @error + ". comment: " + ($7j & "."))
    			Next
    			If Not ($82) Then
    				Send("^H")
    				Send("^S")
    			Else
    				Send("^s")
    			EndIf
    			MsgBox(0, "Not implemented!", "construction site! I will now eject you...")
    			Exit
    		EndIf
    		$7i = ProcessClose($7v)
    		Sleep($7x)
    		_tw(1478, "result closing test editor:" & $7i)
    		If @error Then _tw(1479, "processclose error~~" & @error)
    		Sleep($7x)
    		$7v = ProcessExists($84)
    		Sleep($7x)
    		$7i = ProcessClose($7v)
    		Sleep($7x)
    		_tw(1485, "2nd try: closing test editor:" & $7i)
    		If @error Then _tw(1486, "processclose error~~" & @error)
    	Next
    EndFunc   ;==>_tv
    Func _tw($90 = 1489, $91 = "Error")
    	Local $92
    	Local $93
    	Local $94
    	$94 = @TempDir
    	If $94 == "" Then
    		If Not FileExists($7n) Then DirCreate($7n)
    		$94 = $7n
    	EndIf
    	$92 = $90 & "~" & _rf() & "~" & $91
    	If $7o = "debug" Then
    		Local $95 = WinGetTitle("")
    		MsgBox(0, "debug", $92)
    		WinActivate($95)
    	ElseIf $7o = "debugconsole" Then
    		ConsoleWrite($92 & Chr(13))
    	ElseIf $7o = "run" Then
    		If $94 == "" Then $94 = $7n
    		$93 = _tx($92, $94) & ".jpg"
    		_p6($93)
    		_8($92)
    	ElseIf $7o = "debugconsolescreen" Then
    		ConsoleWrite($92 & Chr(13))
    		$93 = _tx($92, $94) & ".jpg"
    		_p6($93)
    	ElseIf $7o = "releasetextlog" Then
    		If $7l == "" Then $7l = @TempDir & "\" & "autoitlogfile.log"
    		$96 = FileOpen($7l, 1)
    		If $7i = 0 Or @error Then Exit
    		$7i = FileWriteLine($96, $92 & Chr(13))
    		If $7i = 0 Or @error Then Exit
    		$7i = FileClose($96)
    	ElseIf $7o = "releasewordpad" Then
    	Else
    		SetError(1)
    	EndIf
    EndFunc   ;==>_tw
    Func _tx($97, $94)
    	$97 = StringReplace($97, ":", "_")
    	$97 = StringReplace($97, ">", "larger_than")
    	$97 = StringReplace($97, "<", "smaller_than")
    	$97 = StringReplace($97, " ", "_")
    	$97 = StringReplace($97, "/", "&")
    	$97 = StringReplace($97, "/", "+")
    	$97 = StringReplace($97, "&", "+")
    	$97 = StringReplace($97, Chr(9), "_")
    	$97 = StringReplace($97, "?", "questionmark")
    	$97 = StringReplace($97, "!", "exclamationmark")
    	$97 = StringReplace($97, "'", "quotationmark")
    	$97 = StringReplace($97, Chr(34), "doublequotationmark")
    	$97 = StringReplace($97, "__", "_")
    	$97 = StringReplace($97, "__", "_")
    	$97 = StringReplace($97, "__", "_")
    	$97 = StringReplace($97, "__", "_")
    	$97 = $94 & "\" & $97
    	Return $97
    EndFunc   ;==>_tx
    
      

    Extending an automated testing infrastructure through an Outlook Add-In to save, rename email attachments into a searchable archive

    1. Begin confronted with on average 250 daily emailed notification files  per day, from varying sources – both custom test result messages and built-in default automation error messages –
    2. imageI resorted to writing an outlook add-in that stores these attachments in a central repository that can be searched – both names following a more meaning full naming convention, and full text – with more powerful (regular expression capable) tools, like grepWin:
    3. image

    4. The rules details evolved further, but here is an early version:
     
    Public Sub SaveAttachmentsForSelectedMessagesToMyDocuments()
        Dim objOL As Outlook.Application
        Dim objMsg As Outlook.MailItem    'Object
        Dim objAttachments As Outlook.Attachments
        Dim objSelection As Outlook.Selection
        Dim I As Long
        Dim lngCount As Long
        Dim strFilePath As String
        Dim strFileName As String
        Dim strFolderPath As String
        Dim strDeletedFiles As String
        'add msgdate to atttachment
        Dim dtDate As Date
        Dim strFileExtendedName As String
        Dim strFileBasename As String
        Dim strExt As String
        Dim strSentTag As String
        Dim strSubject As String
        Dim strBody As String
        Dim strBasenamedate As String
        Dim strTESTCategory    'fail, warn, pass, finished=autom-error
        Dim allMatches As Object
        Dim objRE As Object
        Dim strTestnamefrombody As String
    
    
    
        ' Get the path to your My Documents folder
        strFolderPath = CreateObject("WScript.Shell").SpecialFolders(16)
        On Error Resume Next
    
        ' Instantiate an Outlook Application object.
        Set objOL = CreateObject("Outlook.Application")
    
        ' Get the collection of selected objects.
        Set objSelection = objOL.ActiveExplorer.Selection
    
        ' The attachment folder needs to exist
        ' You can change this to another folder name of your choice
    
        ' Set the Attachment folder.
        strFolderPath = strFolderPath & "\Outlook Files\"
    
        ' Check each selected item for attachments.
        For Each objMsg In objSelection 'msgs
    
            Set objAttachments = objMsg.Attachments
            lngCount = objAttachments.Count
    
    
            If (objMsg.SenderEmailAddress = "tdscautomation@gmail.com") And lngCount > 0 Then 'some other senders'mesages also end up in this folder
                strTESTCategory = ""
                strSourceCategory = ""
                Set objRE = CreateObject("vbscript.regexp")
                objRE.Global = True
                objRE.IgnoreCase = False
                objRE.Pattern = "(WARN|FAIL|PASS|finished)"    'ex: Testing Anywhere finished executing the test. / Version 5.2.1068 :- SQL03_TA_50 - STATUS= WARN / Version 5.2.1068 - System Tests - STATUS = PASS
                Set allMatches = objRE.Execute(objMsg.Subject)
                strTESTCategory = allMatches.Item(0).SubMatches.Item(0) + "~"
    
                objRE.Pattern = "(System|SQL03)"    'ex: Testing Anywhere finished executing the test. / Version 5.2.1068 :- SQL03_TA_50 - STATUS= WARN / Version 5.2.1068 - System Tests - STATUS = PASS / Version 5.2.1068 :- SQL03_TA_50 - STATUS= FAIL
                Set allMatches = objRE.Execute(objMsg.Subject)
                strSourceCategory = allMatches.Item(0).SubMatches.Item(0)
                If (LCase(strSourceCategory) = "system") Then
                    strSourceCategory = "Server~"
                End If
                If (LCase(strSourceCategory) = "sql03") Then
                    strSourceCategory = "Thinclient~"
                End If
                If (LCase(strSourceCategory) = "") Then
                    strSourceCategory = "Testany~" ' correct: Testany~finished~Variable~sent-on~2016-02-12_18-39-21.txt
                End If
    
                objRE.IgnoreCase = True
    
                strSubjectOri = objMsg.Subject
                Debug.Print strSubjectOri
                
                
    
                For I = lngCount To 1 Step -1    'attachments
                    ' Get the file name and other naming components for this attachment
                    strFileName = objAttachments.Item(I).FileName
                    strFileBasename = Mid(strFileName, 1, InStr(1, strFileName, ".") - 1)
                    'Debug.Print strFileBasename
                    strExt = Mid(strFileName, InStrRev(strFileName, "."), Len(strFileName))
                    strBody = objMsg.Body
                    dtDate = objMsg.SentOn    'add the msg date, to prevent overwriting undated files like testsuite.txt
                    strSentTag = "~sent-on~" & Format(dtDate, "yyyy-mm-dd", vbUseSystemDayOfWeek, vbUseSystem) & "_" & Format(dtDate, "hh-mm-ss", vbUseSystemDayOfWeek, vbUseSystem)
                    'excel can parse this date fromat to dtm , but not the time (all supported have chars illegal in filenames) - so go for sort and use excvel formula
                    strSubject = ""    ' only 1 subject per message, but we don't check it for each attachment, and want it empty for some
                    strBasenamedate = ""
                    strTestnamefrombody = ""
    
                    If (LCase(strExt) = ".zip") Then    'QA zip attachments don't indicate test script and date: we add from the subject (which does indicate) and msg
                        strSubject = Trim(strSubjectOri)
                        'strFileExtendedName = strSubject + strFileBasename + strSentTag + strExt
                    Else
                        If (LCase(strExt) = ".txt") Then
                            If (LCase(strFileBasename) = "testsuite") Then    ' ex: attachment testsuite.txt"
                                'add no test name, since testsuite = summary for all tests
                                'add an extra ~ delimiter for excel column
                                'strSentTag = "~" + strSentTag
                                'todo: have to temp revert to regular send tag until i have more info about testsuite
                                'totest: sort by date asc: does not seem to work eith,er however, the testsuite is a mess anyway
                                'noworkie, saves from newest: so that most recent suite.txt overwrites previous summaries for this day (requires order by receiveddate desc display in outlook which is the norm)
                                'strFileExtendedName = strFileBasename + strSentTag + strExt
                                strSentTag = "~~sent-on~" & Format(dtDate, "yyyy-mm-dd", vbUseSystemDayOfWeek, vbUseSystem)    'using different strSentTag
                            Else    'not testsuite, but txt -> might (variable.txt) have a testname in the subject - split the tesname  out from what follows it
                            'todo: still
                                objRE.Pattern = "\_(January|February|March|April|May|June|July|August|September|October|November|December|\d{2,}\-)"    'need only start of datestring, for prepending delimiter
                                'done: not matching , is htis the inputSMAP_TestResult_50TA_02-07-2016_23_53_04
    
                                'no consistent formatmask: ex: SCE_OA_TestResult_50TA_02-11-2016_03_10_26
                                'BasicPDF_TestResult_50TA_01-04-2016 11_57_03.txt
                                'ST_HistoryTabs1_TestResult_SQL03_TA_50_January042016.txt
                                 'ex: Testing Anywhere finished executing the test. / Version 5.2.1068 :- SQL03_TA_50 - STATUS= WARN / Version 5.2.1068 - System Tests - STATUS = PASS
                                Set allMatches = objRE.Execute(strFileBasename)
                                strBasenamedate = allMatches.Item(0).SubMatches.Item(0)
                                If (Len(strBasenamedate) > 0) Then strFileBasename = Replace(strFileBasename, "_" + strBasenamedate, "~" + strBasenamedate)  'todo:hack, use regex
    
                            End If
                        Else
                            If (LCase(strExt) = ".jpg") Then
                                If (LCase(strFileBasename) = "gogreen") Then    ' we know already, TU
                                    GoTo NextIteration:    ' not having continueloop considered harmful
                                End If
                                'we do not seem to receive other jpg's?
                            Else
                                If (LCase(strExt) = ".png") Then
                                    'TA's automation failure attachments have no originating script in filename, but the message body contains it
                                    objRE.Pattern = "Test Name\s+:\s+(\S+)"    'ex: Test Name : Top10_INFO001.tamx
                                    Set allMatches = objRE.Execute(strBody)
                                    If allMatches.Count <> 0 Then
                                        strTestnamefrombody = allMatches.Item(0).SubMatches.Item(0)
                                    End If
                                End If
                            End If
                        End If
                    End If
    
                    'components only initialized as "" will output nothing
                    'prefer to add senton to all txt since even the ones that have a date have a hard to read/sort format mask
                    ' add ~ as delimiters for  later parsing
                    If (Len(strTestnamefrombody) > 0) Then
                        strTestnamefrombody = strTestnamefrombody + "~"
                    End If
                    If (Len(strSubject) > 0) Then
                        strSubject = strSubject + "~"
                    End If
                    strFileExtendedName = strSourceCategory + strTESTCategory + strTestnamefrombody + strSubject + strFileBasename + strSentTag + strExt
                    strFileExtendedName = Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(strFileExtendedName, "/", "_"), "\", "_"), "|", "_"), "<", "_"), ">", "_"), ":", "_"), "*", "_"), "?", "_"), """", "_"), "''", "_"), ",", "_"), " ", "_"), "__", "_"), "__", "_")
                    ' Combine with the path to the folder.
                    strFilePath = strFolderPath & strFileExtendedName
                    If Dir(strFilePath) Then
                        If (FileLen(strFilePath) > objAttachments.Item(I).Size) Then
                        'todo: save attachment to temporary file  to compare sizes properly: keep only the largest = most recent one of undated files - should apply only testsuite.txt
                        Else
                        objAttachments.Item(I).SaveAsFile strFilePath
                        End If
                    Else
                    ' Save the attachment as a file.
                    objAttachments.Item(I).SaveAsFile strFilePath
                    End If
                    'Debug.Print strFilePath + vbCrLf
    
    NextIteration:
                Next I    'attachment
            End If 'if attachments
        Next    'message
    
    ExitSub:
    
        Set objAttachments = Nothing
        Set objMsg = Nothing
        Set objSelection = Nothing
        Set objOL = Nothing
        Set objRE -= Nothing 
    End Sub
    

    PowerShell Script to convert your Testing Anywhere run logs into a Excel pivot table data source

      1. If confronted with a sizable Testing Anywhere test script codebase which has been marginally, but not substantially enhanced/cleaned up in several years while producing a barrage of automation errors daily,
      2. you may find that the run suite errors that Testing Anywhere logs automatically in its rlgx files are your best data source  for monitoring and designing a plan of attack:
        1. Any oft-failing scripts should be put last during the daily run? how about length script needs to run?
        2. Any failing  script parts could be modularized and during the daily run? rlgx-excel-pivot-scripts-avg-duration-percentage
        3. any oft-failing scripts? E.g. here the top 8% of failing scripts have almost 30% of the errors. image
        4. Any oft-failing approaches that might benefit from refactoring? Starting with which  scripts? Main actions, then sub-actions:rlgx-excel-pivot-scripts-error-type-countrlgx-excel-pivot-scripts-error-type-count
        5. etc.
      3. Then this PowerShell script may help which
        1. extracts the non binary <runlog> items out of the binary rlgx files,
        2. and merges them into a single file
        3. which it wraps with an XML declaration and root level node that Excel can work with.
     
    add-content -value '' -path C:\td\testinganywhere\files\rlgx\all-a-rlgx.xml -Encoding UTF8 Get-childitem -path C:\td\testinganywhere\files\rlgx\arnold-pc1 |
    ? {$_.Extension -eq ".rlgx"} |  
    % { $file = convertto-string $_.FullName  
    $match = [regex]::Match($file,'\s+(.*)\s+',"SingleLine,IgnoreCase").value    
    add-content $match -path C:\td\testinganywhere\files\rlgx\all-a-rlgx.xml -Encoding UTF8 } 
    add-content '' -path C:\td\testinganywhere\files\rlgx\all-a-rlgx.xml -Encoding UTF8 
    
    1. Make this PowerShell script a Scheduled Task,
    2. So that you can auto-update said XML which you made the  data source for your Excel monitoring/planning work book.
      1. The post-processing of the default error log messages that makes meaningful pivoting actually possible, is left as an exercise to the reader by Testing Anywhere Smiley .
    Follow

    Get every new post delivered to your Inbox.

    Join 102 other followers