|
#NoEnv |
|
#SingleInstance Force |
|
#NoTrayIcon |
|
|
|
SetBatchLines, -1 |
|
SetKeyDelay, -1, 1 |
|
SetMouseDelay, -1 |
|
SetWinDelay, -1 |
|
SetControlDelay, -1 |
|
|
|
class Utility { |
|
RequireAdmin() { |
|
FULL_COMMAND_LINE := DllCall("GetCommandLine", "str") |
|
if not (A_IsAdmin or RegExMatch(FULL_COMMAND_LINE, " /restart(?!\S)")) { |
|
try { |
|
FilePath := "" |
|
if A_IsCompiled |
|
FilePath := A_ScriptFullPath |
|
else |
|
FilePath := Format("{} /restart \\\""{}\\\""", A_AhkPath, A_ScriptFullPath) |
|
|
|
psScript = |
|
( |
|
param($param1) |
|
Start-Process powershell -WindowStyle Hidden -Verb RunAs -ArgumentList \"-Command Start-Process '$param1'\" |
|
) |
|
|
|
psScript := Format("powershell -Command &{{1}} '{2}'", psScript, FilePath) |
|
|
|
RunWait, % psScript,, Hide |
|
} |
|
ExitApp |
|
} |
|
} |
|
|
|
SetTimer(fn, period := -1) { |
|
SetTimer % fn, % period |
|
} |
|
} |
|
|
|
class AutoExecutor { |
|
static FolderName := "Apps" |
|
static ExtensionPattern := "exe|lnk|ahk|bat|cmd" |
|
|
|
__New() { |
|
Utility.RequireAdmin() |
|
|
|
this.Initialize() |
|
} |
|
|
|
Config() { |
|
this.ExitManager := new this.ExitManager() |
|
|
|
this.Pattern := "i).*\.(" . this.ExtensionPattern . ")$" |
|
this.SearchPath := A_ScriptDir . "\" . this.FolderName . "\*" |
|
} |
|
|
|
Initialize() { |
|
this.Config() |
|
|
|
this.RegisterSwitches() |
|
this.ExecuteSwitches() |
|
|
|
this.Search(this.SearchPath) |
|
|
|
this.Finalize() |
|
} |
|
|
|
Search(SearchPath) { |
|
Loop, Files, % SearchPath |
|
{ |
|
FileFullPath := A_LoopFileFullPath |
|
|
|
if !RegExMatch(FileFullPath, this.Pattern) |
|
continue |
|
|
|
FileName := A_LoopFileName |
|
SleepMatch := RegExMatch(FileName, "#(\d+)_", SleepMatch) |
|
HideFlagMatch := InStr(FileName, "!") ? 0 : 1 |
|
SleepTime := SleepMatch ? SleepMatch1 : "" |
|
|
|
if (SleepTime > 0) { |
|
this.LaunchAppDelayed(FileFullPath, SleepTime, HideFlagMatch) |
|
} else { |
|
this.LaunchApp(FileFullPath, HideFlagMatch) |
|
} |
|
|
|
} |
|
} |
|
|
|
LaunchAppDelayed(FileFullPath, Delay := -1, nShowCmd := 1) { |
|
this.ExitManager.QueueExecution() |
|
|
|
Utility.SetTimer(ObjBindMethod(this, "_ExitManagedLaunchApp", FileFullPath, nShowCmd), -1 * Delay) |
|
} |
|
|
|
_ExitManagedLaunchApp(FileFullPath, nShowCmd) { |
|
this.LaunchApp(FileFullPath, nShowCmd) |
|
|
|
this.ExitManager.FinishExecution() |
|
} |
|
|
|
LaunchApp(FileFullPath, nShowCmd := 1) { |
|
DllCall("Shell32\ShellExecute", "UInt", 0, "Str", "open", "Str", FileFullPath, "Str", "", "Str", "", "Int", nShowCmd) |
|
} |
|
|
|
Finalize() { |
|
this.ExitManager.AttemptExit() |
|
} |
|
|
|
RegisterSwitches() { |
|
this.switchTable := AutoExecutor.Metadata() |
|
|
|
this.switchesMap := {} |
|
for boundSwitch, switchObj in this.switchTable { |
|
this.switchesMap[boundSwitch] := ObjBindMethod(this.Bootstrapper, switchObj.fn) |
|
} |
|
|
|
; Map "/switch" to "-switch" for accessibility |
|
for boundSwitch, functionName in this.switchesMap { |
|
this.switchesMap[ StrReplace(boundSwitch, "/", "-") ] := this.switchesMap[boundSwitch] |
|
} |
|
} |
|
|
|
ExecuteSwitches() { |
|
totalArgs := A_Args.Length() |
|
if (totalArgs = 0) |
|
return false |
|
|
|
processedArguments := [] |
|
|
|
argPosition := 1 |
|
while (argPosition <= totalArgs) { |
|
argument := A_Args[ argPosition ] |
|
if (this.switchesMap.HasKey(argument)) { |
|
args := [] |
|
argPosition++ |
|
while (argPosition <= totalArgs && !this.switchesMap.HasKey(A_Args[ argPosition ])) { |
|
args.Push(A_Args[ argPosition ]) |
|
argPosition++ |
|
} |
|
|
|
processedArguments.Push({ boundSwitch: argument, arguments: args }) |
|
} else { |
|
argPosition++ |
|
} |
|
} |
|
|
|
if (!processedArguments.Length()) { |
|
MsgBox % ("Error: Unsupported command line switch has been used.") |
|
return false |
|
} |
|
|
|
for idx, argumentObject in processedArguments { |
|
boundSwitch := argumentObject.boundSwitch |
|
arguments := argumentObject.arguments |
|
|
|
this.switchesMap[boundSwitch].Call(arguments*) |
|
} |
|
|
|
ExitApp |
|
} |
|
|
|
class Metadata { |
|
static _ := AutoExecutor.Metadata := new AutoExecutor.Metadata() |
|
|
|
__New() { |
|
this.__metadata := {} |
|
|
|
return ObjBindMethod(this, "Register") |
|
} |
|
|
|
Register(__customScope, metadata := "") { |
|
if (!metadata) |
|
return this.Retrieve() |
|
|
|
this.__metadata[metadata.boundSwitch] := metadata |
|
} |
|
|
|
Retrieve() { |
|
return this.__metadata |
|
} |
|
} |
|
|
|
class Bootstrapper { |
|
static shortcutName := "Auto Executor.lnk" |
|
|
|
RegisterStartup() { |
|
static @ := AutoExecutor.Metadata({ boundSwitch: "/add-startup", fn: "RegisterStartup" }) |
|
|
|
this.Clean() |
|
|
|
FileCreateShortcut, % A_ScriptFullPath, % Format("{1}\{2}", A_Startup, this.shortcutName), % A_ScriptDir |
|
} |
|
|
|
UnregisterStartup() { |
|
static @ := AutoExecutor.Metadata({ boundSwitch: "/remove-startup", fn: "UnregisterStartup" }) |
|
|
|
FileDelete, % Format("{1}\{2}", A_Startup, this.shortcutName) |
|
} |
|
|
|
RegisterTaskScheduler() { |
|
static @ := AutoExecutor.Metadata({ boundSwitch: "/add-task", fn: "RegisterTaskScheduler" }) |
|
|
|
this.Clean() |
|
|
|
psScript = |
|
( |
|
param($param1) |
|
$taskTrigger = New-ScheduledTaskTrigger -AtLogon |
|
$taskAction = New-ScheduledTaskAction -Execute "$param1" |
|
$taskCompatibility = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -AllowStartIfOnBatteries -Compatibility \"Win8\" |
|
Register-ScheduledTask \"Run Auto Executor At Logon\" -Action $taskAction -Trigger $taskTrigger -Settings $taskCompatibility -RunLevel Highest |
|
) |
|
|
|
RunWait, % Format("powershell -Command &{{1}} '{2}'", psScript, A_ScriptFullPath),, Hide |
|
} |
|
|
|
UnregisterTaskScheduler() { |
|
static @ := AutoExecutor.Metadata({ boundSwitch: "/remove-task", fn: "UnregisterTaskScheduler" }) |
|
|
|
psScript = |
|
( |
|
Unregister-ScheduledTask -TaskName \"Run Auto Executor At Logon\" -Confirm:$false |
|
) |
|
|
|
RunWait, % Format("powershell -Command &{{1}}", psScript),, Hide |
|
} |
|
|
|
Clean() { |
|
this.UnregisterStartup() |
|
this.UnregisterTaskScheduler() |
|
} |
|
} |
|
|
|
class ExitManager { |
|
__New() { |
|
this.TOTAL_EXECUTIONS := 0 |
|
|
|
this.ExitFn := ObjBindMethod(this, "AttemptExit") |
|
} |
|
|
|
QueueExecution() { |
|
this.TOTAL_EXECUTIONS++ |
|
} |
|
|
|
FinishExecution() { |
|
this.TOTAL_EXECUTIONS-- |
|
} |
|
|
|
AttemptExit() { |
|
if (this.TOTAL_EXECUTIONS > 0) { |
|
Utility.SetTimer(this.ExitFn, -1000) |
|
return |
|
} |
|
|
|
this.Exit() |
|
} |
|
|
|
Exit() { |
|
ExitApp |
|
} |
|
} |
|
|
|
static _ := AutoExecutor := new AutoExecutor() |
|
} |
|
|
|
#If (WinActive("ahk_exe notepad++.exe") || WinActive("ahk_exe code.exe")) |
|
^R::Reload |