/* ****************************************************************************** @SriptName: App launcher.xys @Author: IT Services & Consulting Ulf Kohlmorgen @Created on: 2015-10-15 13:20:49 @Last modified: 2018-07-13 18:59:27 @Function: Find and lauch applications (from a filterable window) @Current version: v0.7 ****************************************************************************** */ end compare(, "19.00.0302", "v") == -1, "This script requires at least v19.00.0302, terminating now!"; $curVer = gettoken(regexmatches(readfile(self("file")), "^@Current version: v[0-9.]+"), 2, ": v"); $iniFile = self("path") . "\" . self("base") . ".ini"; $argsFile = self("path") . "\" . self("base") . "_CLI.txt"; $iniContent = <<<>>> [General] Version=$curVer Window_Width=400 Window_Height=700 Remove_Lnk_Extension=1 Remove_Exe_Extension=1 Default_Extensions=exe;lnk Use_Separators=1 Separator_Above=1 Separator_String=---------- [#SectionName#] ---------- Separator_Icon=:blank Ask_For_Args=1 Detect_Args_Via=file Args_Keyword=[cli] ; Paths = Single or multiple paths, must be separated by "|" ; Recursive = -1: No recursion. 0: No recursion limit. Equal or larger than 1: Limit to that depth ; Extensions = Single or multiple extensions, separated by ";" or "|". "*." will be auto-affixed if missing ; Excluded_Paths = Single or multiple paths, separated by "|". No automatic wildcard embracing! ; Excluded_Files = Single or multiple files, separated by "|". No automatic wildcard embracing! ; Excluded files will be REMOVED from all other found files! ; Included_Files = Single or multiple files, separated by "|". No automatic wildcard embracing! ; ONLY these files will be displayed (minus Excluded_Files)! ; Section names = Only use the letters [a-zA-Z0-9] and/or "_", "-"! ; The order of the sections (apart from "General") matters! [Windows] Paths=%WINDIR% Recursive=-1 Extensions=exe Excluded_Files=bfsvc.exe ;[System32] ;Paths=%WINDIR%\System32 ;Recursive=-1 ;Extensions=exe ;Excluded_Paths=\wbem|\oobe ;Excluded_Files=dxdiag.exe|eventvwr.exe ;Included_Files=calc.exe|cleanmgr.exe|cmd.exe|control.exe|dxdiag.exe|eventvwr.exe|msinfo32.exe|mspaint.exe|notepad.exe|perfmon.exe ;[Tools] ;Paths=D:\Tools\@Shortcuts ;Recursive=-1 ;Extensions=*.lnk ;[User_Tools] ;Paths=D:\Users\%USERNAME%\Tools\@Shortcuts ;Recursive=-1 ;Extensions=*.lnk >>>; if (exists($iniFile) != 1) { writefile($iniFile, $iniContent, , "tu"); } if (exists($argsFile) != 1) { writefile($argsFile, "", , "utf8"); } $sections = formatlist(getsectionlist(, $iniFile), "f", , "!General"); $version = getkey("Version", "General", $iniFile); $windowWidth = getkey("Window_Width", "General", $iniFile); $windowHeight = getkey("Window_Height", "General", $iniFile); $removeLnkExtension = getkey("Remove_Lnk_Extension", "General", $iniFile); $removeExeExtension = getkey("Remove_Exe_Extension", "General", $iniFile); $defaultExtensions = getkey("Default_Extensions", "General", $iniFile); $useSeparators = getkey("Use_Separators", "General", $iniFile); $separatorAbove = getkey("Separator_Above", "General", $iniFile); $separatorString = getkey("Separator_String", "General", $iniFile); $separatorIcon = getkey("Separator_Icon", "General", $iniFile); // Version check $curVerIsNewer = (compare($curVer, $version, "v") == 1) ? true : false; if ($curVerIsNewer) { setkey $curVer, "Version", "General", $iniFile; // .ini upgrades if ($version == "" || $version < "0.5") { setkey "1", "Ask_For_Args", "General", $iniFile; setkey "file", "Detect_Args_Via", "General", $iniFile; setkey "[cli]", "Args_Keyword", "General", $iniFile; } if ($version < "0.6") { $content = readfile($iniFile); $find = <<<>>> ; Recursive = Empty or 0: No recursion; Anything else: Recursive >>>; $replace = <<<>>> ; Recursive = Empty or 0: No recursion; Larger than 0: Limit to that depth. "u" = unlimited recursion >>>; if (regexmatches($content, $find)) { $content = regexreplace($content, $find, $replace); writefile($iniFile, $content, , "tu"); } } if ($version < "0.7") { $content = readfile($iniFile); $find = <<<>>> ; Recursive = Empty or 0: No recursion; Larger than 0: Limit to that depth. "u" = unlimited recursion >>>; $replace = <<<>>> ; Recursive = -1: No recursion. 0: No recursion limit. Equal or larger than 1: Limit to that depth >>>; $content = regexreplace($content, $find, $replace); $content = regexreplace($content, "^Recursive=0", "Recursive=-1"); $content = regexreplace($content, "^Recursive=u", "Recursive=0"); writefile($iniFile, $content, , "tu"); } } $askForArgs = getkey("Ask_For_Args", "General", $iniFile); $detectArgsVia = getkey("Detect_Args_Via", "General", $iniFile); $argsKeyword = getkey("Args_Keyword", "General", $iniFile); // Default values if necessary $windowWidth = ($windowWidth) ? $windowWidth : 400; $windowHeight = ($windowHeight) ? $windowHeight : 700; $defaultExtensions = ($defaultExtensions) ? $defaultExtensions : "*.exe;*.lnk"; $separatorIcon = ($separatorIcon) ? $separatorIcon : ":queue"; $separatorString = ($separatorString) ? "$separatorString||$separatorIcon" : strrepeat("-", 50) . "^||$separatorIcon"; $separator = ($useSeparators) ? . $separatorString . : ; $detectArgsVia = (regexmatches($detectArgsVia, "(file|name|tag)")) ? $detectArgsVia : "file"; $argsKeyword = ($argsKeyword != "") ? $argsKeyword : "[cli]"; $found = ""; foreach($section, $sections, , "e") { $paths = eval(quote(getkey("Paths", $section, $iniFile))); $recursive = getkey("Recursive", $section, $iniFile); $extensions = getkey("Extensions", $section, $iniFile); $excPaths = eval(quote(getkey("Excluded_Paths", $section, $iniFile))); $excFiles = getkey("Excluded_Files", $section, $iniFile); $incFiles = getkey("Included_Files", $section, $iniFile); // Non-recursive by default if ($recursive == -1) { $recursive = "/n"; } elseif ($recursive == 0) { $recursive = ""; } elseif (regexmatches($recursive, "[0-9]+")) { $recursive = "/maxdepth=$recursive"; } else { $recursive = "/n"; } // Handle extensions incl. auto-wildcarding $extensions = ($extensions) ? $extensions : $defaultExtensions; if (strpos($extensions, "*") == -1) { $extensions = trim(regexreplace($extensions, "^|(;|\|)", ";*."), ";"); } // Check multi-location path(s) existence $multiPaths = ""; foreach($path, $paths, "|", "e") { if (exists($path) == 2) { $multiPaths .= ($multiPaths ? "|" . $path : $path); } } // Set exclude flags $excPathsFlag = ($excPaths) ? " /excl=$excPaths" : " "; $excFilesFlag = ($excFiles) ? " /exclfile=$excFiles" : " "; // Find item(s) $items = quicksearch("$extensions $recursive" . $excPathsFlag . $excFilesFlag, $multiPaths, , "s"); // Include file(s) - Only these items will be listed (minus $excFiles)! if ($incFiles) { $items = formatlist($items, "f", , replace($incFiles, "|", ), "f"); } // Build the entry list if ($items) { if ($separatorAbove) { $found .= ((strpos($separatorString, "#SectionName#") != -1) ? replace($separator, "#SectionName#", $section) : $separator) . $items; } else { $found .= $items . ((strpos($separatorString, "#SectionName#") != -1) ? replace($separator, "#SectionName#", $section) : $separator); } } } if (!$found) { status "No items found, aborted!", "8B4513", "stop"; end true; } // Remove empty lines $found = formatlist($found, "e", ); // Build "Caption|Data|Icon" $found = regexreplace($found, "^([A-Z\\].+\\)(.*?)(?=\r?\n|$)", "$2|$1$2|$1$2"); // Remove .lnk in captions if ($removeLnkExtension) { $found = regexreplace($found, "^(.+?)(\.lnk)\|", "$1|"); } if ($removeExeExtension) { $found = regexreplace($found, "^(.+?)(\.exe)\|", "$1|"); } // Selection window $selected = inputselect("", $found, , 1+32+64+1024, , $windowWidth, $windowHeight); if ($selected == "") { status "No valid entry selected, aborted!", "8B4513", "stop"; end true; } $adminPermissions = (get("Shift") == 3) ? true : false; // A command line app? if ($askForArgs) { $args = ""; if ($detectArgsVia LikeI "file") { $argsFileContent = readfile($argsFile); $found = regexmatches($argsFileContent, "^" . regexreplace($selected, "([\\.+(){\[^$])", "\$1") . "=.*?(?=\r?\n|$)"); if ($found) { $args = input("Enter arguments...", 2:=eval(gettoken($found, 2, "=", , 2)), 3:="w", 4:="", 5:=600); } } else { if (($detectArgsVia LikeI "name" && strpos($selected, $argsKeyword) != -1) || ($detectArgsVia LikeI "tag" && strpos(tagitems("tag", , $selected), $argsKeyword) != -1)) { $args = input("Enter arguments...", 3:="w", 4:="", 5:=600); } } } // Execute with / without admin permissions $vbsFile = "%TEMP%\~OpenElevatedCMD.vbs"; $vbsContent = <<<>>> Set UAC = CreateObject("Shell.Application") UAC.ShellExecute "$selected", $args, "", "runas", 1 >>>; if ($adminPermissions) { writefile($vbsFile, regexreplace($vbsContent, "^[ \t]+"), , "utf8"); run """cscript"" ""$vbsFile"" //nologo", , 0, 0; } else { if ($args) { run """$selected"" $args"; } else { open $selected; } } if (exists($vbsFile) == 1) { delete 0, 0, $vbsFile; } /* @Changelog: +++ major new feature + new feature * changed feature - removed feature % improved performance ! fixed minor bug !!! fixed major bug v0.7 * "Recursive=" feature changed (again)! All values larger than 0 mean: Limit recursion to that scan depth (note: this was NOT changed). From now on, "0" will NOT turn off recursion (as in <= 0.6) but set recursion to on with NO limit to the recursion depth. -1 is now the internal default (if not defined in a section) and acts as the "NO recursion" switch. Changes to the .ini file should be handled automatically once you upgrade to v0.7... v0.6 + When "Ctrl + Shift" is hold while using the left mouse button to click the "OK" button the selected entry is started with admin permissions * "Recursive=" feature changed. All values larger than 0 mean: Limit recursion to that depth. The character "u" (for "u"nlimited) can be used to impose no limit to the recursion depth. "0" (NO recursion) is still the internal default value unless specified otherwise for a section entry v0.5 + Added three new settings in the "General" section: "Ask_For_Args=". Default = 1 "Detect_Args_Via=". Options = "file/name/tag". Default = "file" "Args_Keyword=". Default = "[cli]" These default settings allow it to execute command line apps with arguments If "Detect_Args_Via" is set to "name", the script will look for "" in the name of the file. If set to "tag", it will query the XY tag database to see if the file is tagged with "". Both options do NOT allow to set default arguments! The last option is "file". If the file ".\"' in the input field for the command line arguments C:\Windows\notepad.exe="""C:\Windows\System32\drivers\etc\hosts""" ; This would display the argument "C:\Windows\System32\drivers\etc\hosts" A note on these quoting rules: If a parameter which needs double quotes comes directly after the "=" it needs to be TRIPLE double quoted! If it comes later (as in the first example) it only needs single double quotes v0.4 ! Fixed a bug regarding the wrong spelling of "separator" Existing .ini files need a manual replacement of "Seperator_Icon=" with "Separator_Icon="! ! Fixed a regex bug reguarding the building of the "Caption|Data|Icon" stuff * Changed the default value of "Separator_Icon=" to ":blank" which will lead to an empty icon v0.3 + Added "Remove_Exe_Extension=" setting. Default = 1 * Changed default value for "Separator_String=" to: "---------- [#SectionName#] ----------" "#SectionName#" will be replaced with the belonging .ini section name... + Added "Separator_Above=" setting. Default = 1. When using 0, the separator lines come after the entries v0.2 ! Eval() was necessary to resolve environment variables from inside the .ini file v0.1 • Initial release */