SaveVersion is a little kludge that copies ahk au3 and exe files that have file version info, to a filename with the version numbers added to the base filename. For example test.au3 version 1.0.0.0 would be copied to test_1_0_0_0.au3.
Mainly it's designed as an alternative to using Save A Copy inside SciTE. You may put a shortcut in SendTo folder to allow multiple file seletion then invoke via right click SendTo.
Usage:
SaveVersion /?
displays About Dialog
SaveVersion file1 file2 file3...
loops through the files prompting to save each. An error is displayed if no file version info found.
This usage has a sanity check. If more than 5 files on command line you are prompted to continue.
SaveVersion - with no args displays File Open Dialog where multiple files may be selected.
Note that for source files it's just a simple substring search. au3 files must have compile directives. Particularly the one with _FileVersion=. ahk files the directive section of the source must start with /* as the first line at start of line, and end with */
the string File_Version= is hunted for to get the file version numbers. If tools change to insert different strings as directives or you wish to enhance the program, that's why the source is provided. For me, simple like this works fine. It's just a convenience so I don't have to save my files with _SAVE or some other klunky device, and has the advantage the version numbers are out where I can see them.
exe files must be compiled with file version info. The dots in the numbers are changed to underscores just in case some code isn't "multi-dot aware" and assumes a dot is automatically followed by the file extension.
(Note the 2nd source file, MilesAheadMisc.au3 contains general purpose functions I include in my scripts. The program uses enough of these that it's better just to include the file instead of pasting at the bottom of the main program.)
Main program - SaveVersion.au3
edit: updated to 1.3.1.0 added All Files fo FileOpenDialog to allow choosing a mix of file types.
AutoIt
#NoTrayIcon #region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_icon=floppy.ico #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Res_Fileversion=1.3.1.0 #AutoIt3Wrapper_Res_LegalCopyright=2012 www.favessoft.com #AutoIt3Wrapper_Res_Language=1033 #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <MilesAheadMisc.au3> Global $version = _ScriptVersion() Global $fileName = "", $fileArray Global $msg = _ScriptBaseName() & " " & $version & " Copyright © " & @YEAR & " www.favessoft.com" & @CRLF & @CRLF $msg &= "Usage: SaveVersion [ /? ] or [ filename1 .. filename2 ... ]" & @CRLF & @CRLF $msg &= "filename must be ..exe, .au3 or .ahk with file version info" & @CRLF & @CRLF $msg &= "Au3 and Ahk requre source directives. Exe must be compiled with file version information" & @CRLF & @CRLF $msg &= "Copies filname.ext to filename_n_n_n_n.ext (n being version numbers)" & @CRLF & @CRLF $msg &= "SaveVersion /? shows this About Dialog" & @CRLF & @CRLF $msg &= "SaveVersion ( no args displays File Open Dialog )" If $CmdLine[0] = 1 And $CmdLine[1] = "/?" Then _ShowUsage($msg) EndIf If Not $CmdLine[0] Or Not FileExists($CmdLine[1]) Then $fileName = FileOpenDialog("Select File(s) to Save Versioned", @WorkingDir, "Ahk Files (*.ahk)|Au3 Files (*.au3)|Exe Files (*.exe) |All Files (*.*)", 7) If @error Then _ShowError("No File Selected") EndIf If Not StringInStr($fileName, "|") Then _CopyVersioned($fileName) Else $fileArray = StringSplit($fileName, '|') For $x = 2 To $fileArray[0] _CopyVersioned($fileArray[1] & "" & $fileArray[$x]) Next EndIf Exit EndIf ; Sanity check If $CmdLine[0] > 5 Then If MsgBox(0x1024, _ScriptBaseName(), $CmdLine[0] & " Files On Command Line: Process ??") = 7 Then _ShowUsage("User Terminated Processing") EndIf EndIf For $x = 1 To $CmdLine[0] _CopyVersioned($CmdLine[$x]) Next Func _CopyVersioned($inFile) Local $outFile = _FileVersioned($inFile) If $inFile = $outFile Then _ShowError("No File Version Info Found for:" & @CRLF & @CRLF & $inFile, "", False) Return EndIf If MsgBox(0x1024, _ScriptBaseName(), "Copy " & $inFile & @CRLF & @CRLF & " to " & @CRLF & @CRLF & $outFile) = 6 Then If Not FileCopy($inFile, $outFile, 1) Then _ShowError("Error Saving Versioned Copy of: " & @CRLF & @CRLF & $inFile, "", False) EndIf EndIf EndFunc ;==>_CopyVersioned
general purpose include file - MilesAheadMisc.au3
AutoIt
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Res_Fileversion=1.1.1.1 #AutoIt3Wrapper_Res_LegalCopyright=2012 www.favessoft.com #AutoIt3Wrapper_Res_Language=1033 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ;MilesAheadMisc.au3 ; ;misc useful functions for ;inclusion in scripts. ; ;some functions are totatlly original. ;where adapted or used directly I give ;attribution when possible. ; ;MilesAhead ; ;Note: v.1.1.1.1 set arbitrarily on 2012/05/13 to use with my ;SaveVersion program ; #include-once #include <array.au3> #include <file.au3> #include <winapi.au3> #include <apiconstants.au3> #include <winapiex.au3> ; by ProgAndy on AutoIt3 forums ; returns Int($i) or 0 and sets @error to 1 on invalid input ; ; <a href='http://www.autoitscript.com/forum/topic/136142-integer-sets-error/page__view__findpost__p__951086' class='bbc_url' title=''>http://www.autoitscript.com/forum/topic/136142-integer-sets-error/page__view__findpost__p__951086</a> ; Func _Integer($i) If StringRegExp($i, "^s*[-+]?.?d") Then Return Int($i) Return SetError(1, 0, 0) EndFunc ;==>_Integer ;~ ; Empty Tray Icon Queue of events ;~ Func _EmptyTrayQ() ;~ Local $m = 0 ;~ Do ;~ $m = TrayGetMsg() ;~ Until $m = 0 ;~ EndFunc ;==>_EmptyTrayQ ; Empty Tray Icon Queue of events Func _EmptyTrayQ() While TrayGetMsg() WEnd EndFunc ;==>_EmptyTrayQ ;use Scripting.Dictionary object for simple associative arrays Func _AssocArray() Local $aArray = ObjCreate("Scripting.Dictionary") If @error Then Return SetError(1, 0, 0) EndIf $aArray.CompareMode = 1 Return $aArray EndFunc ;==>_AssocArray Func _AssocArrayDestroy(ByRef $aArray) If Not IsObj($aArray) Then Return False EndIf $aArray.RemoveAll() $aArray = 0 Return True EndFunc ;==>_AssocArrayDestroy ;filter out empty array strings ("") Func _ArrayDelBlanks(ByRef $someArray) Local $index = -1 While UBound($someArray) > 0 $index = _ArraySearch($someArray, "") If $index > -1 Then _ArrayDelete($someArray, $index) Else ExitLoop EndIf WEnd EndFunc ;==>_ArrayDelBlanks ; $val is a string read by IniRead that ; should indicate if an option is ; enabled or disabled. The user can ; set it to True or 1 for enabled. ; (e.g. UseMiddleMouseClick=True) ; ; returns True if $val is "True" or "1" ; otherwise returns False ; Func _IniBool($val) If $val = "True" Or $val = "1" Then Return True Return False EndFunc ;==>_IniBool ; When this is called the Active Window should be ; an Explorer Folder Window ; ; Success: Returns path of current folder ; ; Fail: Returns "" and sets @error ; @error = 1 if window is not an Explorer Window ; otherwise @error is set to 2 ; Func _ActiveFolderPath() Local $oldOption = AutoItSetOption("WinTitleMatchMode", 4) Local $handle = WinGetHandle("[Active]") Local $className = _WinAPI_GetClassName($handle) AutoItSetOption("WinTitleMatchMode", $oldOption) If $className <> "ExploreWClass" And $className <> "CabinetWClass" Then Return SetError(1, 0, "") EndIf Local $urlPath = _ExplorerURL($handle) If $urlPath <> "" Then Return _WinAPI_PathCreateFromUrl($urlPath) EndIf Return SetError(2, 0, "") EndFunc ;==>_ActiveFolderPath ; Gets URL path of window that matches $handle ; or "" if no match ; Func _ExplorerURL($handle) Local $shApp = ObjCreate("Shell.Application") Local $windows = $shApp.Windows For $item In $windows ;If Not $item Then ContinueLoop If ($item.hwnd = $handle) Then Return $item.LocationURL EndIf Next Return "" EndFunc ;==>_ExplorerURL ; _PassKey() : Temporarily disables a hotkey, sends ; the key, then enables again. ; ; Returns 0 if either param is blank. ; ; Otherwise Returns the result of the HotKeySet() ; attempt to reset the hotkey. ; ; Not ready for Prime Time due to AutoIt saving state ; of modifier keys ; ;~ Func _PassKey($funcName, $hKey = @HotKeyPressed) ;~ If $funcName = "" Or $hKey = "" Then ;~ Return 0 ;~ EndIf ;~ HotKeySet($hKey) ;~ Send($hKey) ;~ Return HotKeySet($hKey, $funcName) ;~ EndFunc ;==>_PassKey ;confirms that input consists only of valid chars Func _ValidateInput($inputStr, $validChars) For $x = 1 To StringLen($inputStr) If Not StringInStr($validChars, StringMid($inputStr, $x, 1)) Then Return False EndIf Next Return True EndFunc ;==>_ValidateInput ;InputBox to allow user to change hotkey modifier key ;ModKey chars must all be in $validChars string ;Returns $curModKey if user aborts entry Func _EditHotkeyModifier($curModKey, $validChars) Local $newModKey = "" $prompt = "Usable Modifiers include:" & @CRLF $prompt &= "# for Win Key" & @CRLF $prompt &= "! for Alt Key" & @CRLF $prompt &= "^ for Control Key" & @CRLF $prompt &= "^! for Control-Alt etc.." & @CRLF $newModKey = InputBox("Enter HotKey Modifier", $prompt, $curModKey) If $newModKey = "" Or $newModKey = $curModKey Then Return $curModKey If Not _ValidateInput($newModKey, $validChars) Then _ShowError("Invalid Hotkey Modiifer Specified : Keeping Current!", "", False) Return $curModKey EndIf Return $newModKey EndFunc ;==>_EditHotkeyModifier ;return the Windows version as a number or string ;according to $retAsString param. ;example 6.1 for Windows7, 6 for Vista, ;5.1 for XP etc.. as number, as string the ;minor version will be preserved even if .0 ;(Vista returns "6.0" etc.) ; Func _WinVersion($retAsString = 0) Local $dwVersion = DllCall("kernel32.dll", "dword", "GetVersion") Local $versionStr = String(BitAND($dwVersion[0], 0x00FF)) $versionStr &= "." & String(BitShift(BitAND($dwVersion[0], 0xFF00), 8)) If $retAsString Then Return $versionStr Return Number($versionStr) EndFunc ;==>_WinVersion ;_GetVersionEx() ; ;It calls the Ansi version of GetVersionEx() WinAPI ; ;On success returns zero based 5 element array of strings ;element 0 = OS Major;1 = OS Minor; 2 = build; 3 = platform; 4 = Version String ;note Version String may be an empty string or something like "Service Pack 1" ; ;On error returns 0 and sets @error to the value contained in @error macro. ;Sets @extended to 1 if error occurred in DllStructCreate(), 2 if error ;occurred in DllStructSetData(), or 3 if error occurred in DllCall() ; Func _GetVersionEx() Local $OsArray[5] = [""] Local $osvi = DllStructCreate("dword size;dword OsMajor;dword OsMinor;dword build;dword platform;char verString[128]") If @error Then Return SetError(@error, 1, 0) EndIf DllStructSetData($osvi, "size", 148) If @error Then $osvi = 0 Return SetError(@error, 2, 0) EndIf Local $retVal = DllCall("Kernel32.dll", "int", "GetVersionExA", "ptr", DllStructGetPtr($osvi)) If @error Then $osvi = 0 Return SetError(@error, 3, 0) EndIf $OsArray[0] = String(DllStructGetData($osvi, "OsMajor")) $OsArray[1] = String(DllStructGetData($osvi, "OsMinor")) $OsArray[2] = String(DllStructGetData($osvi, "build")) $OsArray[3] = String(DllStructGetData($osvi, "platform")) $OsArray[4] = DllStructGetData($osvi, "verString") $osvi = 0 Return $OsArray EndFunc ;==>_GetVersionEx ; Call EmptyWorkingSet() API ; Returns Func _EmptyWorkingSet() Local $result = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1) Return $result[1] EndFunc ;==>_EmptyWorkingSet ; Reduce memory usage via EmptyWorkingSet() ; Author wOuter ( mostly ) on AutoIt3 forum Func _ReduceMemory($i_PID = -1) If _WinVersion() < 5 Then Return False If $i_PID <> -1 Then Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID) Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0]) DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0]) Else Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1) EndIf Return $ai_Return[0] EndFunc ;==>_ReduceMemory ;returns non 0 if Glass is enabled on Vista/W7 Func _GlassEnabled() $retValue = DllCall("dwmapi.dll", "int", "DwmIsCompositionEnabled", "int*", "") If @error Then Return 0 Return $retValue[1] EndFunc ;==>_GlassEnabled ;from Michael Michta on AutoIt3 forum Func EnableBlurBehind($hWnd) Const $DWM_BB_ENABLE = 0x00000001 $Struct = DllStructCreate("dword;int;ptr;int") DllStructSetData($Struct, 1, $DWM_BB_ENABLE) DllStructSetData($Struct, 2, "1") DllStructSetData($Struct, 4, "1") DllCall("dwmapi.dll", "int", "DwmEnableBlurBehindWindow", "hwnd", $hWnd, "ptr", DllStructGetPtr($Struct)) EndFunc ;==>EnableBlurBehind ;if $Str contains a space wrap in double quotes ; ;useful for command line params of files that have ;a space in the file path ; Func _QuoteStr($str) If StringInStr($str, " ") Then Return '"' & $str & '"' EndIf Return $str EndFunc ;==>_QuoteStr ; _WinAPI_PathFileExists($sFilePath) ; returns 1 if path exists, 0 otherwise ; ; alternative to FileExists function ; ; from guinness on AutoIt3 Forum ; <a href='http://www.autoitscript.com/forum/topic/19370-autoit-wrappers/page__view__findpost__p__953856' class='bbc_url' title=''>http://www.autoitscript.com/forum/topic/19370-autoit-wrappers/page__view__findpost__p__953856</a> Func _WinAPI_PathFileExists($sFilePath) Local $aReturn = DllCall('shlwapi.dll', 'int', 'PathFileExistsW', 'wstr', $sFilePath) If @error Then Return SetError(1, 0, 0) EndIf Return $aReturn[0] EndFunc ;==>_WinAPI_PathFileExists ;returns True if $path is a directory Func _DirectoryExists($path) If Not FileExists($path) Then Return False If StringInStr(FileGetAttrib($path), "D") > 0 Then Return True Return False EndFunc ;==>_DirectoryExists ;return True if $path exists and contains "D" directory attribute Func _IsFolder($path) Local $attr = FileGetAttrib($path) If $attr = "" Then Return SetError(1, 0, False) ElseIf StringInStr($attr, "D") Then Return True Else Return False EndIf EndFunc ;==>_IsFolder ; returns 1 if path is valid, 0 otherwise ; Func _ValidPath($path) If StringLeft($path, 2) = "" And Not StringInStr($path, ".") Then Return FileExists($path) EndIf Return _WinAPI_PathFileExists($path) EndFunc ;==>_ValidPath ; A drive passed in that consists of a letter and colon ; ( x: ) will be set to Upper Case and a slash appened ( X: ) ; ; A drive passed in as x: will be set to Upper Case. ; ; The Function returns nothing. Any changes are made to the ; input param. ; Func _DriveUpSlash(ByRef $drive) If StringLen($drive) = 2 And StringRight($drive, 1) = ":" Then $drive = StringUpper($drive) & "" ElseIf StringRight($drive, 2) = ":" Then $drive = StringUpper($drive) EndIf EndFunc ;==>_DriveUpSlash ; return the basename part of a file path ; works only for files with extension ; e.g. returns "test" for c:foldertest.exe path ; Func _FileBaseName($path) If $path = "" Then Return "" If StringLen($path) < 3 Then Return "" Local $pos = StringInStr($path, "", 0, -1) $pos += 1 Local $tmp = StringMid($path, $pos) Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1) EndFunc ;==>_FileBaseName ; Return Directory part of path with trailing slash Func _FileDirWSlash($path) Return StringLeft($path, StringInStr($path, "", 0, -1)) EndFunc ;==>_FileDirWSlash ; Return Directory part of path without trailing slash Func _FileDirNoSlash($path) Return StringLeft($path, StringInStr($path, "", 0, -1) - 1) EndFunc ;==>_FileDirNoSlash ; return _FileBaseName with hash appended instead of using full path ; Func _BaseFileStr($path) Return _FileBaseName($path) & _HashString32($path) EndFunc ;==>_BaseFileStr ; return the '.ext' part of path no matter how long the ext ; as in image.jpg returns '.jpg' or image.jpeg returns '.jpeg' ; Func _FileExt($path) If $path = "" Then Return "" Local $pos = StringInStr($path, ".", 0, -1) If $pos = 0 Then Return "" Return StringMid($path, $pos) EndFunc ;==>_FileExt ; return entire path without last extension ; (e.g. c:FolderText.txt returns c:FolderText) ; Func _PathNoExt($path) If Not StringInStr($path, ".") Then Return $path Return StringLeft($path, StringInStr($path, ".", 0, -1) - 1) EndFunc ;==>_PathNoExt ;returns filename without drive or path Func _FileNoPath($path) Local $pos = StringInStr($path, "", 0, -1) If Not $pos Then $pos = StringInStr($path, ":") EndIf If Not $pos Then Return $path Return StringMid($path, $pos + 1) EndFunc ;==>_FileNoPath ;filter out percent signs, spaces, and illegal filename chars ;and substitute underscores. Optionally chop off return str ;at $maxLen chars. ; ; Func _NormalizeFilename($inFilename, $maxLen = 0) Local Const $illegalFilenameChars = "?[]/=+<>:;"",* %" Local $c = "" Local $fixedFilename = "" For $x = 1 To StringLen($inFilename) $c = StringMid($inFilename, $x, 1) If StringInStr($illegalFilenameChars, $c) Then $c = "_" EndIf $fixedFilename &= $c Next If $maxLen Then Return StringLeft($fixedFilename, $maxLen) EndIf Return $fixedFilename EndFunc ;==>_NormalizeFilename ;return @ScriptName without extension ;useful for MsgBox titles or path ;building ; Func _ScriptBaseName() Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1)) EndFunc ;==>_ScriptBaseName ;a one-liner but saves thinking about it :) ; Func _ScriptIniFileName() Return @ScriptDir & "" & _ScriptBaseName() & ".ini" EndFunc ;==>_ScriptIniFileName ; _ScriptVersion($Script = @ScriptFullPath) ; Returns File Version string from .exe, .au3 or .ahk script. ; Returns "" if no version info available. ; ; Note: The .au3 or .ahk script must contain compiler ; directives with file version info or "" is returned. ; ; Sets @error: 1 = file open error : 2 = unsupported file type ; Func _ScriptVersion($Script = @ScriptFullPath) Local $ver = "", $scriptHandle = -1, $found = False, $sPos = 0 If StringRight($Script, 4) = ".exe" Then Return FileGetVersion($Script) ElseIf StringRight($Script, 4) = ".au3" Then $scriptHandle = FileOpen($Script) If $scriptHandle = -1 Then Return SetError(1, 0, "") Do $ver = FileReadLine($scriptHandle) $sPos = StringInStr($ver, "Fileversion=") If $sPos Then $ver = StringMid($ver, $sPos + StringLen("Fileversion=")) $found = True ExitLoop EndIf Until StringLeft($ver, 1) <> "#" FileClose($scriptHandle) ElseIf StringRight($Script, 4) = ".ahk" Then $scriptHandle = FileOpen($Script) If $scriptHandle = -1 Then Return SetError(1, 0, "") $ver = FileReadLine($scriptHandle) If StringLeft($ver, 2) <> "/*" Then Return "" ; lacks directives Do $ver = FileReadLine($scriptHandle) $sPos = StringInStr($ver, "File_Version=") If $sPos Then $ver = StringMid($ver, $sPos + StringLen("File_Version=")) $found = True ExitLoop EndIf Until StringLeft($ver, 2) = "*/" FileClose($scriptHandle) Else SetError(2, 0, "") EndIf If Not $found Then $ver = "" Return $ver EndFunc ;==>_ScriptVersion ; Returns script with version suffix added before ; the extension. (e.g. script.au3 would return ; script_1_0_0_0.au3 if file version 1.0.0.0 ; ; Requires .exe with file version info, au3 or ; .ahk with compiler directives containing ; file version info. ; ; Sets @error to _ScriptVersion() error code. ; If no file info returns $Script unmodified. ; Func _FileVersioned($Script) Local $suffix = _ScriptVersion($Script) If @error Or Not $suffix Then Return SetError(@error, 0, $Script) Return _PathNoExt($Script) & "_" & StringReplace($suffix, ".", "_") & _FileExt($Script) EndFunc ;==>_FileVersioned ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileInPath ; Description ...: Returns the location in the PATH environment variable containing a file ; Syntax.........: _FileInPath( $sFilename ) ; Parameters ....: $sFilename - The file to search for (filename only, no folders) ; Return values .: Success - Returns the path to the file and set @error=0 (@extended=1 a specified path and the file is there) ; Failure - Returns "" and sets @error: ; |1 - File not found in @WorkingDir or the PATH (@extended=1 if PATH is blank) ; |2 - Could not StringSplit the PATH ; Author ........: Gigglestick (c0deWorm) ; Modified.......: Comments added and logic modified ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _FileInPath($asFilename) If StringInStr($asFilename, "") Then If FileExists($asFilename) Then ; if a full or relative path was specified and the file exists then return the path Return SetError(0, 1, $asFilename) Else ; if a path was specified and the file does not exist then return "file not found" error Return SetError(1, 0, "") EndIf EndIf ; if the file is found in the current working directory then return the absolute file path If FileExists(@WorkingDir & "" & $asFilename) Then Return SetError(0, 0, @WorkingDir & "" & $asFilename) Local $i, $lasPath, $lsPath = EnvGet("PATH") ; if variable containing PATH is empty then return "file not found" error and @extended=2 If StringLen($lsPath) = 0 Then Return SetError(1, 1, "") ; if PATH is set but only has one entry then check it If StringLen($lsPath) > 0 And Not StringInStr($lsPath, ";") Then If FileExists($lsPath & "" & $asFilename) Then ; if the filename is found in the single PATH entry then return the file path Return SetError(0, 0, $lsPath & "" & $asFilename) Else ; if PATH is a single entry and does not contain the filename then return "file not found" error Return SetError(1, 0, "") EndIf EndIf ; remove any blank entries (double semicolons) While StringInStr($lsPath, ";;") $lsPath = StringReplace($lsPath, ";;", ";") WEnd ; split variable containing PATH into an array of single paths $lasPath = StringSplit($lsPath, ";") ; if ";" not found in split then return error If @error Then Return SetError(2, 0, "") ; loop through array of single paths, searching for absolute file path and return absolute file path if found For $i = 1 To $lasPath[0] If FileExists($lasPath[$i] & "" & $asFilename) Then Return SetError(0, 0, $lasPath[$i] & "" & $asFilename) Next ; unable to find filename in current working directory or PATH so return error Return SetError(1, 0, "") EndFunc ;==>_FileInPath ; Ascend4nt on AutoIt3 forum ; Open Property Page to specified Tab ; e.g. _FileOpenPropertiesDialog("notepad.exe","Details") ; ; <a href='http://www.autoitscript.com/forum/topic/118673-open-a-files-properties-window/page__view__findpost__p__825420' class='bbc_url' title=''>http://www.autoitscript.com/forum/topic/118673-open-a-files-properties-window/page__view__findpost__p__825420</a> ; Func _FILEPropertiesDialog($sObjName, $sPropPage = "", $iObjType = 0x02, $hWnd = 0) Local $sPropPageType = "ptr" If IsString($sPropPage) And $sPropPage <> "" Then $sPropPageType = "wstr" Else $sPropPage = 0 EndIf Local $aRet = DllCall("shell32.dll", "bool", "SHObjectProperties", "hwnd", $hWnd, "dword", $iObjType, "wstr", $sObjName, $sPropPageType, $sPropPage) If @error Then Return SetError(2, @error, False) If Not $aRet[0] Then Return SetError(3, 0, False) Return True EndFunc ;==>_FILEPropertiesDialog ;Check FavesSoft Server for newer version with optional download ;If user downloads, the script directory and zip file will be ;opened, and the calling program exited. ; Func _Check4Update($verIniFile = "FavesVersions.ini", $url = "<a href='http://www.favessoft.com/' class='bbc_url' title='External link' rel='nofollow external'>http://www.favessoft.com/"</a>, $maxCount = 10) Local $count = 0 Local $iniFile = @ScriptDir & "" & $verIniFile Local $hDownload = InetGet($url & $verIniFile, $iniFile, 1, 1) Local $localFile = "" Do $count += 1 If $count > $maxCount Then ExitLoop Sleep(250) Until InetGetInfo($hDownload, 2) InetClose($hDownload) If $count > $maxCount Then _ShowError("Server Access Failed!", "", False) Return False EndIf Local $v = IniRead($iniFile, "Versions", _ScriptBaseName(), "") If $v = "" Then _ShowError("Version Info Not Found!", "", False) If FileExists($iniFile) Then FileDelete($iniFile) EndIf Return False EndIf Local $t = FileGetVersion(@ScriptFullPath) If $v > $t Then If MsgBox(0x1044, _ScriptBaseName(), "Current Version is " & $t & " Online Version is " & $v & " : Download?") = 6 Then $d = IniRead($iniFile, "Downloads", _ScriptBaseName(), "") If $d <> "" Then $localFile = @ScriptDir & "" & $d $hDownload = InetGet($url & $d, $localFile, 1, 1) $count = 0 Do $count += 1 If $count > $maxCount Then ExitLoop Sleep(250) Until InetGetInfo($hDownload, 2) InetClose($hDownload) If $count <= $maxCount Then ShellExecute($localFile) ShellExecute(@ScriptDir) If FileExists($iniFile) Then FileDelete($iniFile) EndIf Exit Else _ShowError("Download Attempt Failed!", "", False) If FileExists($iniFile) Then FileDelete($iniFile) EndIf Return False EndIf Else _ShowError("Download Info Not Found!", "", False) If FileExists($iniFile) Then FileDelete($iniFile) EndIf Return False EndIf Else If FileExists($iniFile) Then FileDelete($iniFile) EndIf Return True EndIf Else MsgBox(0x1040, _ScriptBaseName(), $t & " is the latest version") EndIf If FileExists($iniFile) Then FileDelete($iniFile) EndIf EndFunc ;==>_Check4Update ;show an error msg and optionally quit, with optional timeout Func _ShowError($errorMsg, $title = "", $quit = True, $timeOut = 0) If $title = "" Then $title = _ScriptBaseName() MsgBox(0x1010, $title, $errorMsg, $timeOut) If $quit Then Exit EndFunc ;==>_ShowError ;show usage msg and optionally quit with optional timeout Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0) If $title = "" Then $title = _ScriptBaseName() MsgBox(0x1040, $title, $usageMsg, $timeOut) If $quit Then Exit EndFunc ;==>_ShowUsage ;write AssocArray to IniFile Section ;returns 1 on success - sets @error on failure Func _WriteAssocToIni($myAssoc, $myIni, $mySection) $retVal = 0 If $myAssoc.Count() < 1 Then Return SetError(1, 0, 0) EndIf Local $iArray[$myAssoc.Count()][2] Local $aArray = $myAssoc.Keys() For $x = 0 To UBound($aArray) - 1 $iArray[$x][0] = $aArray[$x] $iArray[$x][1] = _MakePosString($myAssoc($aArray[$x])) Next $retVal = IniWriteSection($myIni, $mySection, $iArray, 0) Return SetError(@error, 0, $retVal) EndFunc ;==>_WriteAssocToIni ;read AssocArray from IniFile Section ;returns number of items read - sets @error on failure Func _ReadAssocFromIni(ByRef $myAssoc, $myIni, $mySection) Local $sectionArray = IniReadSection($myIni, $mySection) If @error Then Return SetError(1, 0, 0) Local $posA[9] Local $posS For $x = 1 To $sectionArray[0][0] $posS = _MakePosArray($sectionArray[$x][1]) For $y = 0 To UBound($posS) - 1 $posA[$y] = Number($posS[$y]) If $posA[$y] < 0 Then ContinueLoop 2 Next $myAssoc($sectionArray[$x][0]) = $posA Next Return $sectionArray[0][0] EndFunc ;==>_ReadAssocFromIni ;from _SDBM32 by trancexx on AutoIt3 forum Func _HashString32($sString) Local $aArray = StringToASCIIArray($sString) Local $iHash = 0 For $i = 0 To UBound($aArray) - 1 $iHash = $aArray[$i] + BitShift($iHash, -6) + BitShift($iHash, -16) - $iHash Next Return Hex($iHash) EndFunc ;==>_HashString32 ;makes a Position string using '#' number separator Func _MakePosString($posArray) Local $str = "" For $x = 0 To UBound($posArray) - 2 $str &= String($posArray[$x]) & "#" Next $str &= String($posArray[UBound($posArray) - 1]) Return $str EndFunc ;==>_MakePosString ;makes a Position array from a Position string Func _MakePosArray($posString) Return StringSplit($posString, "#", 2) EndFunc ;==>_MakePosArray ;show msgbox without sound and optionally quit with optional timeout Func _ShowSilent($usageMsg, $title = "", $quit = True, $timeOut = 0) If $title = "" Then $title = _ScriptBaseName() MsgBox(0xA0, $title, $usageMsg, $timeOut) If $quit Then Exit EndFunc ;==>_ShowSilent ; Get the execuatble path of a window ; Author gafrost on AutoIt3 forum Func _WinGetPath($title = "", $strComputer = 'localhost') Local $win = WinGetTitle($title) Local $pid = WinGetProcess($win) Local $wbemFlagReturnImmediately = 0x10 Local $wbemFlagForwardOnly = 0x20 Local $colItems = "" Local $objWMIService = ObjGet("winmgmts:" & $strComputer & "rootCIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId = " & $pid, "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems If $objItem.ExecutablePath Then Return $objItem.ExecutablePath Next EndIf Return "" EndFunc ;==>_WinGetPath ; _GetWindowExePath($WindowTitle = "[ACTIVE]") ; ; Returns complete path to Exe that owns window ; on error sets @error and returns "" ; Func _GetWindowExePath($WindowTitle = "[ACTIVE]") Local $pid = WinGetProcess($WindowTitle) If $pid = -1 Then Return SetError(1, 0, "") Local $pHandle = _WinAPI_OpenProcess(0x410, False, $pid) If @error Then Return SetError(1, 1, "") Local $result = _WinAPI_GetModuleFileNameEx($pHandle) _WinAPI_CloseHandle($pHandle) If $result = "" Then Return SetError(@error, 2, "") Return $result EndFunc ;==>_GetWindowExePath ; _GetWindowExeCommandLine($WindowTitle = "[ACTIVE]") ; ; Returns command line for program associated with ; window $WindowTitle, if there is one. Sets @error ; on failure. ; Func _GetWindowExeCommandLine($WindowTitle = "[ACTIVE]") Local $procCmdLine = "" Local $pid = WinGetProcess($WindowTitle) If $pid = -1 Then Return SetError(1, 0, "") Local $pHandle = _WinAPI_OpenProcess(0x410, False, $pid) If @error Then Return SetError(1, 1, "") $procCmdLine = _WinAPI_GetProcessCommandLine($pid) _WinAPI_CloseHandle($pHandle) Return $procCmdLine EndFunc ;==>_GetWindowExeCommandLine ; _WindowExeInfo(ByRef $exePath, ByRef $cmdTail, ByRef $workDir, $WindowTitle = "[ACTIVE]") ; on success sets $exePath to executable path of program associated with ; window $WindowTitle and $cmdTail with it's command line args, if any. ; ; Returns 1 on success, 0 otherwise and sets @error. ; Func _WindowExeInfo(ByRef $exePath, ByRef $cmdTail, ByRef $workDir, $WindowTitle = "[ACTIVE]") $exePath = "" $cmdTail = "" $workDir = "" Local $pid = WinGetProcess($WindowTitle) If $pid = -1 Then Return SetError(1, 0, 0) Local $pHandle = _WinAPI_OpenProcess(0x410, False, $pid) If @error Then Return SetError(1, 1, 0) $exePath = _WinAPI_GetModuleFileNameEx($pHandle) If $exePath = "" Then _WinAPI_CloseHandle($pHandle) Return SetError(1, 2, 0) EndIf $workDir = _WinAPI_GetProcessWorkingDirectory($pid) If @error Then _WinAPI_CloseHandle($pHandle) Return SetError(1, 3, 0) EndIf $cmdTail = _WinAPI_GetProcessCommandLine($pid) _WinAPI_CloseHandle($pHandle) Return 1 EndFunc ;==>_WindowExeInfo ;AutoIt3 Forum code to get Desktop WorkArea Func _GetDesktopWorkArea(ByRef $left, ByRef $top, ByRef $right, ByRef $bottom) Local Const $SPI_SETWORKAREA = 47 Local Const $SPI_GETWORKAREA = 48 Local $tRcWA = DllStructCreate($tagRECT) If _WinAPI_SystemParametersInfo($SPI_GETWORKAREA, 0, DllStructGetPtr($tRcWA)) Then $left = DllStructGetData($tRcWA, "Left") $right = DllStructGetData($tRcWA, "Right") $top = DllStructGetData($tRcWA, "Top") $bottom = DllStructGetData($tRcWA, "Bottom") Return True EndIf Return False EndFunc ;==>_GetDesktopWorkArea Func _SetDesktopWorkArea($left, $top, $right, $bottom) Local Const $SPI_SETWORKAREA = 47 Local Const $SPI_GETWORKAREA = 48 Local $tRcWA = DllStructCreate($tagRECT) DllStructSetData($tRcWA, "Left", $left) DllStructSetData($tRcWA, "Top", $top) DllStructSetData($tRcWA, "Right", $right) DllStructSetData($tRcWA, "Bottom", $bottom) Return _WinAPI_SystemParametersInfo($SPI_SETWORKAREA, 0, DllStructGetPtr($tRcWA)) EndFunc ;==>_SetDesktopWorkArea Func _DesktopMarginArea(ByRef $left, ByRef $top, ByRef $right, ByRef $bottom, $margin = 4) Local $l, $t, $r, $b Local $m = Int($margin) If $m < 0 Or $m > 12 Then $m = 4 If $m = 0 Then _GetDesktopWorkArea($left, $top, $right, $bottom) Else _GetDesktopWorkArea($l, $t, $r, $b) $left = $l + $m $top = $t + $m $right = $r - $m $bottom = $b - $m EndIf EndFunc ;==>_DesktopMarginArea Func _DesktopTaskbarGap(ByRef $left, ByRef $top, ByRef $right, ByRef $bottom, $percentMargin = 5) _GetDesktopWorkArea($left, $top, $right, $bottom) If $right - $left = @DesktopWidth And $bottom - $top = @DesktopHeight Then Return EndIf If $bottom < @DesktopHeight Then $bottom -= Int($bottom / 100 * $percentMargin) ElseIf $top > 0 Then $top += Int(($bottom - $top) / 100 * $percentMargin) ElseIf $left > 0 Then $left += Int(($right - $left) / 100 * $percentMargin) Else $right -= Int(($right - $left) / 100 * $percentMargin) EndIf EndFunc ;==>_DesktopTaskbarGap ; Set Desktop Work Area with percent gap next to Taskbar Func _DesktopSetTaskbarGap($percentMargin = 5) Local $l, $t, $r, $b _DesktopTaskbarGap($l, $t, $r, $b, $percentMargin) Return _SetDesktopWorkArea($l, $t, $r, $b) EndFunc ;==>_DesktopSetTaskbarGap ; _ShowFolders($folders, $percentGap = 5) ; ; Show folders leaving TaskBar Gap ; --------------------------------- ; $folders[0] must have the folder count ; $percentGap is the percent of screen width ; or height to leave next to the Taskbar. ; If TaskbarGap.exe is running, $percentGap ; is set to 0 since it is assumed TaskbarGap ; has set the work area to allow for the gap. ; ; Does not Return a value ; Func _ShowFolders($folders, $percentGap = 5, $moveOnly = False) If Not IsArray($folders) Then Return Local $l = -1, $t = -1, $r = -1, $b = -1 Local $oldMatchMode = AutoItSetOption("WinTitleMatchMode", -3) If ProcessExists("TaskbarGap.exe") Then $percentGap = 0 EndIf _DesktopTaskbarGap($l, $t, $r, $b, $percentGap) Local $sleepVal = 2500 Local $s = $folders[0] Local $h = $b - $t Local $w = ($r - $l) / $s Local $w3 = 0, $w4 = 0 $w3 = ($r - $l) / 3 $w4 = ($r - $l) / 4 If $s > 4 Then $sleepVal = 4000 If $s > 6 Then $sleepVal = 4500 If $s >= 4 Then $h = ($b - $t) / 2 EndIf If $s > 8 Then WinMinimizeAll() Sleep(50) EndIf If Not $moveOnly Then For $x = 1 To $s ShellExecute("explorer.exe", "/e," & $folders[$x], "", "open") Next Sleep($sleepVal) WinWait($folders[$s], "", 8) EndIf If $s > 8 Then _TileHorizontal() ElseIf $s = 8 Then $w *= 2 WinMove($folders[1], "", $l, $t, $w - 1, $h - 2) WinMove($folders[2], "", $l + $w, $t, $w - 1, $h - 2) WinMove($folders[3], "", $l + 2 * $w, $t, $w - 1, $h - 2) WinMove($folders[4], "", $l + 3 * $w, $t, $w - 1, $h - 2) WinMove($folders[5], "", $l, $t + $h, $w - 1, $h - 2) WinMove($folders[6], "", $l + $w, $t + $h, $w - 1, $h - 2) WinMove($folders[7], "", $l + 2 * $w, $t + $h, $w - 1, $h - 2) WinMove($folders[8], "", $l + 3 * $w, $t + $h, $w - 1, $h - 2) ElseIf $s = 7 Then WinMove($folders[1], "", $l, $t, $w3 - 1, $h - 2) WinMove($folders[2], "", $l + $w3, $t, $w3 - 1, $h - 2) WinMove($folders[3], "", $l + 2 * $w3, $t, $w3 - 1, $h - 2) WinMove($folders[4], "", $l, $t + $h, $w4 - 1, $h - 2) WinMove($folders[5], "", $l + $w4, $t + $h, $w4 - 1, $h - 2) WinMove($folders[6], "", $l + 2 * $w4, $t + $h, $w4 - 1, $h - 2) WinMove($folders[7], "", $l + 3 * $w4, $t + $h, $w4 - 1, $h - 2) ElseIf $s = 6 Then $w *= 2 WinMove($folders[1], "", $l, $t, $w - 1, $h - 2) WinMove($folders[2], "", $l + $w, $t, $w - 1, $h - 2) WinMove($folders[3], "", $l + 2 * $w, $t, $w - 1, $h - 2) WinMove($folders[4], "", $l, $t + $h, $w - 1, $h - 2) WinMove($folders[5], "", $l + $w, $t + $h, $w - 1, $h - 2) WinMove($folders[6], "", $l + 2 * $w, $t + $h, $w - 1, $h - 2) ElseIf $s = 5 Then WinMove($folders[1], "", $l, $t, $w3 - 1, $h - 2) WinMove($folders[2], "", $l + $w3, $t, $w3 - 1, $h - 2) WinMove($folders[3], "", $l + 2 * $w3, $t, $w3 - 1, $h - 2) WinMove($folders[4], "", $l, $t + $h, (($r - $l) / 2) - 1, $h - 2) WinMove($folders[5], "", $l + ($r - $l) / 2, $t + $h, (($r - $l) / 2) - 1, $h - 2) ElseIf $s = 4 Then $w *= 2 WinMove($folders[1], "", $l, $t, $w - 1, $h - 2) WinMove($folders[2], "", $l + $w, $t, $w - 1, $h - 2) WinMove($folders[3], "", $l, $t + $h, $w - 1, $h - 2) WinMove($folders[4], "", $l + $w, $t + $h, $w - 1, $h - 2) Else For $x = 1 To $s WinMove($folders[$x], "", $l, $t, $w - 1, $h - 2) $l += $w Next EndIf AutoItSetOption("WinTitleMatchMode", $oldMatchMode) EndFunc ;==>_ShowFolders ;tile windows horizontally Func _TileHorizontal() DllCall("user32.dll", "int", "TileWindows", "int", 0, "int", 1, "int", 0, "int", 0, "int", 0) EndFunc ;==>_TileHorizontal Func _TileVertical() DllCall("user32.dll", "int", "TileWindows", "int", 0, "int", 0, "int", 0, "int", 0, "int", 0) EndFunc ;==>_TileVertical ;AutoIt3 Forum code to get multiple monitor metrics Func _GetVirtualMetrics(ByRef $vWidth, ByRef $vHeight) Local Const $SM_VIRTUALWIDTH = 78 Local Const $SM_VIRTUALHEIGHT = 79 Local $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALWIDTH) Local $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALHEIGHT) $vWidth = $VirtualDesktopWidth[0] $vHeight = $VirtualDesktopHeight[0] EndFunc ;==>_GetVirtualMetrics ; by SmOke_N on AutoIt3 Forum ; <a href='http://www.autoitscript.com/forum/topic/41639-windows-from-process/page__view__findpost__p__310089' class='bbc_url' title=''>http://www.autoitscript.com/forum/topic/41639-windows-from-process/page__view__findpost__p__310089</a> ; set $iPID to program name such as "notepad.exe" ; $nArray = 0 will return 1 base array; leaving it 1 will return the first visible window it finds Func _WinGetByPID($iPID, $nArray = 1) If IsString($iPID) Then $iPID = ProcessExists($iPID) Local $aWList = WinList(), $sHold For $iCC = 1 To $aWList[0][0] If WinGetProcess($aWList[$iCC][1]) = $iPID And _ BitAND(WinGetState($aWList[$iCC][1]), 2) Then If $nArray Then Return $aWList[$iCC][0] $sHold &= $aWList[$iCC][0] & Chr(1) EndIf Next If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), Chr(1)) Return SetError(1, 0, 0) EndFunc ;==>_WinGetByPID
Edited by MilesAhead, 17 May 2012 - 01:16 AM.




