├── LICENSE ├── README.md ├── ScriptUp.ahk └── data ├── dlls ├── mini32.dll ├── mini64.dll ├── std32.dll └── std64.dll ├── functions.ahk ├── guiMake.ahk ├── guiSubs.ahk ├── imgs ├── ICONMX.ico ├── MXIII.png ├── b1.png ├── b2.png ├── b3.png ├── b4.png └── b5.png ├── menuSubs.ahk ├── optionSubs.ahk └── workerH.ahk /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ScriptUp 2 | Latest tested working version: AHK_L v1.1.29.01, DLL: 1.1.30.00-H001 3 | 4 | [AutoHotkey Forum Thread](https://autohotkey.com/boards/viewtopic.php?f=6&t=36656) 5 | 6 | Are you tired of having to see tons of AHK scripts running in the processes list? I was. So, I made this: ScriptUp! 7 | 8 | ![ScriptUp](https://i.imgur.com/8xRso8M.png) 9 | 10 | Easily add as many AHK scripts as you'd like, from any folder on your PC, and ScriptUp will house them all under its own process name. You can even compile it to have it run under a readable, separated process name! 11 | 12 | # Features 13 | 14 | - When adding a script, you can choose between using the standard, full-featured DLL, and the mini version. 15 | - You can reload each script individually or all at once. 16 | - Drag and drop files to add multiple scripts at once. 17 | - When it starts up, all scripts in the list immediately run. 18 | - When a file is added, it immediately runs. 19 | - When a file is removed, it immediately stops the script. 20 | - As a setting, it can start up at user login. 21 | - Scripts may be paused and suspended. 22 | - Each script state is listed and actively updated. 23 | 24 | # Limitations and other notes 25 | 26 | - Scripts must be compliant with AutoHotkey_H (usually no or very few issues if it was written for AHK v1.1). 27 | - If you have "Start on User Login" active and move ScriptUp, it will automatically fix the registry entry (restart ScriptUp from the new path to do so). 28 | - When running as a compiled script, you must have a shortcut (.lnk) to "Lib" in the same folder as ScriptUp to allow access to the [Standard Library](https://autohotkey.com/docs/Functions.htm#lib). 29 | - If using an onExit sub/function in one of the added scripts, it must not exceed 30s of process time. If something requires more than that amount of time, [set the value here](ScriptUp.ahk#L70). 30 | - Do NOT use any variation of #If except for #If. #IfWinActive, #IfWinExist, etc., will make the thread crash on exit. This is due to deprication in _H. 31 | - SetWorkingDir will be overridden. They will take on the working directory of the worker script, which is in the library. Full paths will need to be used in scripts. 32 | - With the release of v1, paths to scripts/DLLs may be relative to workerH. You can modify the path while adding a new script or change it in Lib\config.ini. 33 | 34 | # Dependencies (included) 35 | - [AutoHotkey_H v1](https://hotkeyit.github.io/v2/) - The DLL's are required for running the worker as well as the scripts. It will auto-set them initially to the included DLLs, but you can change them from the options tab. 36 | - [threadMan](https://github.com/Masonjar13/AHK-Library/blob/master/Lib/threadMan.ahk) 37 | - [_MemoryLibrary](https://github.com/Masonjar13/AHK-Library/blob/master/Required-Libraries/_MemoryLibrary.ahk) [by Hotkeyit](https://autohotkey.com/board/topic/77302-class-ahk-lv2-memorylibrary/) 38 | - [_Struct](https://github.com/Masonjar13/AHK-Library/blob/master/Required-Libraries/_Struct.ahk) [by Hotkeyit](https://autohotkey.com/board/topic/55150-class-structfunc-sizeof-updated-010412-ahkv2/) 39 | 40 | # Contribution 41 | If you'd like to contribute, fork, or make any personal edits, feel free to add your own name and link to the [About section](Lib/guiMake.ahk#L32). 42 | 43 | My only request is to keep my name and link in the About section. Other than that, have fun! 44 | 45 | 46 | # License 47 | MIT 48 | -------------------------------------------------------------------------------- /ScriptUp.ahk: -------------------------------------------------------------------------------- 1 | #singleInstance force 2 | #persistent 3 | #noEnv 4 | setWorkingDir,% a_scriptDir 5 | menu,tray,tip,ScriptUp 6 | 7 | ; compiled installs 8 | if(a_isCompiled){ 9 | fileCreateDir,data\dlls 10 | fileCreateDir,data\imgs 11 | fileInstall,data\dlls\mini32.dll,data\dlls\mini32.dll 12 | fileInstall,data\dlls\mini64.dll,data\dlls\mini64.dll 13 | fileInstall,data\dlls\std32.dll,data\dlls\std32.dll 14 | fileInstall,data\dlls\std64.dll,data\dlls\std64.dll 15 | fileInstall,data\imgs\b1.png,data\imgs\b1.png 16 | fileInstall,data\imgs\b2.png,data\imgs\b2.png 17 | fileInstall,data\imgs\b3.png,data\imgs\b3.png 18 | fileInstall,data\imgs\b4.png,data\imgs\b4.png 19 | fileInstall,data\imgs\b5.png,data\imgs\b5.png 20 | fileInstall,data\imgs\MXIII.png,data\imgs\MXIII.png 21 | fileInstall,data\workerH.ahk,data\workerH.ahk 22 | } 23 | 24 | ; setup config 25 | ;sini:=(siniD:=a_appData . "\..\Local\ScriptUp") . "\config.ini" 26 | sini:=a_scriptDir . "\data\config.ini" 27 | dlls:=a_scriptDir . "\data\dlls" 28 | imgs:=a_scriptDir . "\data\imgs" 29 | workerdll:=dlls . "\std" . (a_ptrSize*8) . ".dll" 30 | workerfile:=a_scriptDir . "\data\workerH.ahk" 31 | fileLastDir:=a_scriptDir 32 | if(!fileExist(sini)) 33 | firstRun:=1 34 | 35 | ; load settings 36 | iniRead,editPath,% sini,settings,editPath,0 37 | iniRead,hideDeleteWarning,% sini,settings,hideDeleteWarning,0 38 | regRead,loginRun,% regStartupPath:="HKCU\Software\Microsoft\Windows\CurrentVersion\Run",ScriptUp 39 | if(!errorLevel) ; auto-correct if the script has been moved 40 | if(loginRun!=a_scriptFullPath) 41 | regWrite,REG_SZ,% regStartupPath,ScriptUp,% a_scriptFullPath 42 | 43 | ; start worker 44 | #include %a_scriptDir%\data\guiMake.ahk 45 | worker:=ahkThread(workerfile,params,1,workerdll) 46 | onExit,cleanup 47 | 48 | ; set DLLs/open gui automatically for first run 49 | if(firstRun){ 50 | nDllType:="Std",nDllPath:="dlls\std" . (a_ptrSize*8) . ".dll" 51 | gosub setDllFinal 52 | nDllType:="Mini",nDllPath:="dlls\mini" . (a_ptrSize*8) . ".dll" 53 | gosub setDllFinal 54 | gosub showMain 55 | } 56 | setTimer,checkStates,1000 57 | return 58 | 59 | #include %a_scriptDir%\data\guiSubs.ahk 60 | #include %a_scriptDir%\data\optionSubs.ahk 61 | #include %a_scriptDir%\data\menuSubs.ahk 62 | #include %a_scriptDir%\data\functions.ahk 63 | 64 | checkStates: 65 | stateList:=worker.ahkGetVar["stateList"] 66 | loop,parse,stateList,`, 67 | { 68 | lv_getText(pstate,a_index,2) 69 | if(pstate!=a_loopField) 70 | lv_modify(a_index,,,a_loopField) 71 | } 72 | return 73 | 74 | cleanUp: 75 | worker.ahkTerminate[30000] 76 | exitApp 77 | -------------------------------------------------------------------------------- /data/dlls/mini32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/dlls/mini32.dll -------------------------------------------------------------------------------- /data/dlls/mini64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/dlls/mini64.dll -------------------------------------------------------------------------------- /data/dlls/std32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/dlls/std32.dll -------------------------------------------------------------------------------- /data/dlls/std64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/dlls/std64.dll -------------------------------------------------------------------------------- /data/functions.ahk: -------------------------------------------------------------------------------- 1 | ; https://autohotkey.com/boards/viewtopic.php?f=7&t=9919 2 | hideFocusBorder(wParam,lParam:="",msg:="",handle:=""){ ; by 'just me' 3 | static affected:=[] 4 | static WM_UPDATEUISTATE:=0x0128 5 | static SET_HIDEFOCUS:=0x00010001 ; UIS_SET << 16 | UISF_HIDEFOCUS 6 | static init:=onMessage(WM_UPDATEUISTATE,func("hideFocusBorder")) 7 | 8 | if(msg=WM_UPDATEUISTATE){ 9 | if(wParam=SET_HIDEFOCUS) 10 | affected[handle]:=true 11 | else if(affected[handle]) 12 | dllCall("user32\PostMessage","ptr",handle,"uint",WM_UPDATEUISTATE,"ptr",SET_HIDEFOCUS,"ptr",0) 13 | }else if(dllCall("IsWindow","ptr",wParam,"uint")) 14 | dllCall("user32\PostMessage","ptr",wParam,"uint",WM_UPDATEUISTATE,"ptr",SET_HIDEFOCUS,"ptr",0) 15 | } 16 | getFilename(path){ 17 | splitPath,path,,,,fname 18 | return fname 19 | } 20 | getFileext(path){ 21 | splitPath,path,,,ext 22 | return ext 23 | } -------------------------------------------------------------------------------- /data/guiMake.ahk: -------------------------------------------------------------------------------- 1 | ; main Window 2 | if(!a_isCompiled) 3 | menu,tray,icon,% imgs . "\ICONMX.ico",,,1 4 | gui,+hwndghwnd 5 | gui,color,c0c0c0 6 | gui,add,picture,x400 y200 w400 h-1,% imgs . "\MXIII.png" 7 | gui,add,tab3,xm ym,List|Options|About 8 | 9 | ; list tab 10 | gui,tab,List 11 | gui,color,,c0c0c0 12 | lvw:=300 13 | lvHdr3w:=60 14 | lvHdr2w:=100 15 | lvHdr1w:=lvw-lvHdr2w-lvHdr3w 16 | gui,add,listview,% "+hwndlvhwnd r20 w" . lvw . " -E0x200 glvCallback altsubmit",Script Name|State|DLL 17 | hideFocusBorder(ghwnd) 18 | gui,color,,default 19 | gosub,genList 20 | lv_modifyCol(1,lvHdr1w) 21 | lv_modifyCol(2,lvHdr2w) 22 | lv_modifyCol(3,lvHdr3w) 23 | 24 | ; options tab 25 | gui,tab,Options 26 | gui,color,c0c0c0 27 | gui,add,checkbox,% "-wrap gdeleteWarning vdeleteWarningc checked" . hideDeleteWarning,Disable file remove warning 28 | gui,add,checkbox,% "-wrap glogonRun vlogonRunc checked" . (loginRun?1:0),Start on User Login 29 | gui,add,picture,gsetDll vStd,% imgs . "\b1.png" 30 | gui,add,picture,gsetDll vMini,% imgs . "\b2.png" 31 | gui,add,picture,glibShort,% imgs . "\b3.png" 32 | 33 | 34 | ; about tab 35 | gui,tab,About 36 | gui,font,s12,arial 37 | gui,add,text,section,Written by 38 | gui,font,cBlue underline 39 | gui,margin,5,9 40 | gui,add,text,ys gaboutLink,Masonjar13 41 | gui,font,norm s12 42 | gui,margin,1 43 | gui,add,text,ys,% ". " 44 | gui,margin,15,9 45 | gui,font,s9 cBlack 46 | 47 | ; gui: addScript 48 | gui,% "addScript:+owner" . ghwnd . " +hwndghwnd2" 49 | gui,addScript:font,s10,arial 50 | gui,addScript:add,edit,w240 r2 vpathText section 51 | gui,addScript:add,ddl,w50 vdllType ys,Std||Mini 52 | gui,addScript:add,button,gaddScriptFinal xm,Add 53 | 54 | ; gui: execCode 55 | gui,% "execCode:+owner" . ghwnd . " +hwndghwnd4" 56 | gui,execCode:font,,courier new 57 | gui,execCode:add,edit,vexecScriptCode w500 r10 58 | gui,execCode:font,s12,arial 59 | gui,execCode:add,button,gexecScriptFinal w500,Execute Code 60 | 61 | ; menu: tray 62 | menu,tray,nostandard 63 | menu,tray,add,Open GUI,showMain 64 | menu,tray,default,Open GUI 65 | menu,tray,add,Exit,cleanup 66 | 67 | 68 | ; menu: LV context 69 | menu,cmain,add,Reload,reloadScript 70 | menu,cmain,add,Pause,pauseScript 71 | menu,cmain,add,Suspend,suspendScript 72 | menu,cmain,add,Open ListLines,listlinesScript 73 | menu,cmain,add,Edit,editScript 74 | menu,cmain,add,Remove,removeScript 75 | menu,cmain,add,Execute Code,execScript 76 | -------------------------------------------------------------------------------- /data/guiSubs.ahk: -------------------------------------------------------------------------------- 1 | guiDropFiles: 2 | loop,parse,a_guiEvent,`n 3 | { 4 | if(getFileext(newScript:=a_loopField)!="ahk"){ 5 | msgbox,,Error: Incorrect FileType,Only AutoHotkey files are allowed. 6 | continue 7 | } 8 | gui,+disabled 9 | guiControl,addScript:,pathText,% newScript 10 | gui,addScript:show,,Add Script 11 | winWaitClose,% "ahk_id " . ghwnd2 12 | } 13 | gui,-disabled 14 | return 15 | 16 | addScriptFinal: 17 | gui,addScript:submit 18 | iniWrite,% newScript . "?" . dllType,% sini,scripts,% getFilename(newScript) 19 | gosub,genList 20 | worker.ahkFunction("do","genList","","") 21 | worker.ahkPostFunction("do","run",getFilename(newScript),"") 22 | return 23 | 24 | genList: 25 | gui,% ghwnd . ":default" 26 | lv_delete() 27 | iniRead,allScripts,% sini,scripts 28 | loop,parse,allScripts,`n 29 | { 30 | regExMatch(a_loopField,"O)([^=]+)=([^?]+)\?([a-zA-Z0-9]+)",t) 31 | lv_add(,t.1,,t.3) 32 | } 33 | lv_modifyCol(1,"sort") 34 | return 35 | 36 | setDll: 37 | gui,+ownDialogs 38 | fileSelectFile,nDllPath,3,% fileLastDir,% "Set " . a_guiControl . " DLL",(*.dll) 39 | if(errorlevel||!nDllPath) 40 | return 41 | if(getFileext(nDllPath)!="dll"){ 42 | msgbox,,Error: Incorrect FileType,Only a AutoHotkey_H.dll should be selected. 43 | return 44 | } 45 | 46 | ; save last file dir for fileSelectFile 47 | splitPath,nDllPath,,fileLastDir 48 | 49 | ; std or mini 50 | nDllType:=inStr(a_guiControl,"Std")?"Std":"Mini" 51 | gosub setDllFinal 52 | return 53 | 54 | setDllFinal: 55 | worker.ahkPostFunction("do","setDll",nDllType,nDllPath) 56 | return 57 | 58 | libShort: 59 | fileDelete,% a_scriptDir . "\Lib.lnk" 60 | if(!ahkDir) 61 | splitPath,a_ahkPath,,ahkDir 62 | fileCreateShortcut,% ahkDir . "\Lib",% a_scriptDir . "\Lib.lnk" 63 | return 64 | 65 | editPath: 66 | inputBox,editPathNew,Edit Path,% "Set the path of the editor to use for the ""Edit"" item on the context menu. Leave empty to use registry entry.`nCurrent path: " . (editPath?editPath:"Use Registry") . "." 67 | if(!errorLevel) 68 | iniWrite,% editPath:=editPathNew,% sini,settings,editPath 69 | return 70 | 71 | regEditPath: 72 | regWrite,REG_SZ,HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit,LastKey,Computer\HKEY_CLASSES_ROOT\AutoHotkeyScript\shell\Edit\command 73 | run,regedit.exe 74 | return 75 | 76 | lvCallback: 77 | if(a_guiEvent="Normal") 78 | selectedRow:=a_eventInfo 79 | else if(a_guiEvent="RightClick"){ 80 | if(selectedRow:=a_eventInfo) 81 | menu,cmain,show 82 | } 83 | return 84 | 85 | showMain: 86 | gui,show,,ScriptUp 87 | return 88 | 89 | guiClose: 90 | gui,cancel 91 | return 92 | 93 | aboutLink: 94 | run,https://github.com/Masonjar13 95 | return 96 | -------------------------------------------------------------------------------- /data/imgs/ICONMX.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/ICONMX.ico -------------------------------------------------------------------------------- /data/imgs/MXIII.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/MXIII.png -------------------------------------------------------------------------------- /data/imgs/b1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/b1.png -------------------------------------------------------------------------------- /data/imgs/b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/b2.png -------------------------------------------------------------------------------- /data/imgs/b3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/b3.png -------------------------------------------------------------------------------- /data/imgs/b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/b4.png -------------------------------------------------------------------------------- /data/imgs/b5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Masonjar13/ScriptUp/ced51b5b0e150aa7a56c8993f629a81bef3e3b19/data/imgs/b5.png -------------------------------------------------------------------------------- /data/menuSubs.ahk: -------------------------------------------------------------------------------- 1 | reloadScript: 2 | lv_getText(scr,selectedRow) 3 | worker.ahkPostFunction("do","reload",scr,"") 4 | return 5 | 6 | pauseScript: 7 | lv_getText(scr,selectedRow) 8 | worker.ahkPostFunction("do","pause",scr,"") 9 | return 10 | 11 | suspendScript: 12 | lv_getText(scr,selectedRow) 13 | worker.ahkPostFunction("do","suspend",scr,"") 14 | return 15 | 16 | listlinesScript: 17 | lv_getText(scr,selectedRow) 18 | worker.ahkPostFunction("do","listlines",scr,"") 19 | return 20 | 21 | editScript: 22 | lv_getText(scr,selectedRow) 23 | worker.ahkPostFunction("do","edit",scr,editPath) 24 | return 25 | 26 | removeScript: 27 | if(!selectedRow){ 28 | if(!hideDeleteWarning) 29 | msgbox,,Make a selection,No file was selected. 30 | return 31 | } 32 | lv_getText(scr,selectedRow) 33 | if(!hideDeleteWarning){ 34 | msgbox,4,Confirm,Are you sure you want to remove this script? This will not delete the actual script. 35 | ifMsgbox,yes 36 | gosub removeScriptFinal 37 | }else 38 | gosub removeScriptFinal 39 | return 40 | 41 | removeScriptFinal: 42 | iniDelete,% sini,scripts,% scr 43 | worker.ahkFunction("do","remove",scr,"") 44 | worker.ahkPostFunction("do","genList","","") 45 | gosub genList 46 | return 47 | 48 | execScript: 49 | lv_getText(scrx,selectedRow) 50 | guiControl,execCode:,execScriptCode, 51 | gui,execCode:show,,% "Execute code on thread: " . scrx 52 | return 53 | 54 | execScriptFinal: 55 | gui,execCode:submit,nohide 56 | worker.ahkPostFunction("do","exec",scrx,execScriptCode) 57 | return 58 | -------------------------------------------------------------------------------- /data/optionSubs.ahk: -------------------------------------------------------------------------------- 1 | deleteWarning: 2 | gui,submit,nohide 3 | if(deleteWarningc) 4 | iniWrite,% hideDeleteWarning:=1,% sini,settings,hideDeleteWarning 5 | else 6 | iniWrite,% hideDeleteWarning:=0,% sini,settings,hideDeleteWarning 7 | return 8 | 9 | logonRun: 10 | gui,submit,nohide 11 | if(logonRunc) 12 | regWrite,REG_SZ,% regStartupPath,ScriptUp,% a_scriptFullPath 13 | else 14 | regDelete,% regStartupPath,ScriptUp 15 | return 16 | -------------------------------------------------------------------------------- /data/workerH.ahk: -------------------------------------------------------------------------------- 1 | #singleInstance force 2 | #persistent 3 | #noEnv 4 | #noTrayIcon 5 | setWorkingDir,% a_scriptDir 6 | sini:=a_scriptDir . "\config.ini" 7 | onExit,clean 8 | 9 | threadList:=new fileList(sini) 10 | threadList.genList() 11 | threadList.runAll() 12 | setTimer,updateStatus,100 13 | return 14 | 15 | do(funct,p1,p2){ ; execAFunc does not support varadic functions or optional params 16 | global threadList 17 | params:=[] 18 | loop 2 19 | if(p%a_index%) 20 | params.push(p%a_index%) 21 | threadList[funct](params*) 22 | } 23 | 24 | updateStatus: 25 | stateList:=threadList.returnStates() 26 | return 27 | 28 | clean: 29 | threadList:= 30 | exitApp 31 | 32 | class fileList { 33 | __new(sini){ 34 | this.quitTimeout:=3000 35 | this.scripts:=[] 36 | this.sini:=sini 37 | this.loadDlls() 38 | } 39 | __delete(){ 40 | for i,a in this.scripts { 41 | this.close(a.name) 42 | } 43 | } 44 | genList(){ 45 | iniRead,allScripts,% this.sini,scripts 46 | loop,parse,allScripts,`n 47 | { 48 | ctn:=0 49 | regExMatch(a_loopField,"O)([^=]+)=([^?]+)\?([a-zA-Z0-9]+)",t) 50 | for i,a in this.scripts { 51 | if(a.name=t.1){ 52 | ctn:=1 53 | break 54 | } 55 | } 56 | if(!ctn){ 57 | tn:={name: t.1,path: t.2,dll: t.3} 58 | this.scripts[t[1]]:=tn 59 | } 60 | } 61 | } 62 | runAll(reload:=0){ 63 | for i,a in this.scripts { 64 | if(reload) 65 | err:=this.reload(a.name) 66 | else 67 | err:=this.run(a.name) 68 | if(err){ 69 | if(err=-1){ 70 | if(err1){ 71 | if(!inStr(err1,a.dll)) 72 | err1.=", " . a.dll 73 | }else 74 | err1:=a.dll 75 | } 76 | else if(err=-2){ 77 | if(err2){ 78 | if(!inStr(err2,a.dll)) 79 | err2.=", " . a.dll . " (" . this.getDll(a.dll) . ")" 80 | }else 81 | err2:=a.dll . " (" . this.getDll(a.dll) . ")" 82 | }else if(err=-3) 83 | err3:=(err3?err3 . ", ":"") . a.name . " (" . a.path . ")" 84 | } 85 | } 86 | if(err1||err2||err3) 87 | msgbox,,Error,% "There were errors while trying to run scripts:`n`n " 88 | . (err1?"DLL path not specified: " . err1 . "`n`n ":"") 89 | . (err2?"DLL not found at path: " . err2 . "`n`n ":"") 90 | . (err3?"File path invalid: " . err3 . "`n`n ":"") 91 | } 92 | reloadAll(){ 93 | this.runAll(1) 94 | } 95 | closeAll(){ 96 | global debug 97 | for i,a in this.scripts { 98 | if(debug) 99 | tooltip,% "Closing " . a.name 100 | this.close(a.name) 101 | } 102 | toolTip 103 | } 104 | edit(scriptName,editor:=""){ 105 | if(editor){ 106 | try 107 | run,% """" . editor . """ """ . this.scripts[scriptName].path . """" 108 | }else{ 109 | try 110 | run,% "edit """ . this.scripts[scriptName].path . """" 111 | } 112 | } 113 | exec(scriptName,code){ 114 | if(this.pauseState(scriptName)) 115 | msgbox,,Limitation Error,Code can not be executed while thread is paused. 116 | else 117 | return this.scripts[scriptName].thread.ahkExec(code) 118 | } 119 | reload(scriptName){ 120 | this.close(scriptName) 121 | return this.run(scriptName) 122 | } 123 | listlines(scriptName){ 124 | if(this.scripts[scriptName].dll="Mini") 125 | msgbox,,Limitation Error,Mini DLL doesn't support ListLines. 126 | else 127 | this.exec(scriptName,"ListLines") 128 | } 129 | pause(scriptName,pauseState:="tog"){ 130 | if(pauseState="tog"){ 131 | pauseState:=!this.pauseState(scriptName) 132 | } 133 | pauseState:=this.scripts[scriptName].thread.ahkPause(pauseState) 134 | return pauseState 135 | } 136 | pauseState(scriptName){ 137 | return this.scripts[scriptName].thread.ahkPause() 138 | } 139 | suspend(scriptName){ ; Helgef - https://autohotkey.com/boards/viewtopic.php?p=207480#p207480 140 | static WM_COMMAND := 0x111 141 | static ID_FILE_SUSPEND := 65404 142 | local dhwLast 143 | 144 | if(this.scripts[scriptName].dll="Mini") 145 | msgbox,,Limitation Error,Mini DLL doesn't support hotkeys. 146 | else{ 147 | if(a_detectHiddenWindows="Off"){ 148 | dhwLast:=a_detectHiddenWindows 149 | detectHiddenWindows,on 150 | } 151 | postMessage,WM_COMMAND,ID_FILE_SUSPEND,,,% "ahk_id " this.scripts[scriptName].thread.ahkGetVar("a_scripthwnd") 152 | if(dhwLast) 153 | detectHiddenWindows,% dhwLast 154 | } 155 | } 156 | getState(scriptName){ 157 | if(this.scripts[scriptName].thread.ahkReady()){ 158 | pauseState:=this.pauseState(scriptName) 159 | suspendState:=this.scripts[scriptName].thread.ahkGetVar("a_isSuspended") 160 | return pauseState?(suspendState?"P/S":"Paused"):(suspendState?"Suspended":"Running") 161 | } 162 | return "Stopped" 163 | } 164 | returnStates(){ 165 | local str,i,a 166 | for i,a in this.scripts 167 | str.=!str?this.getState(a.name):"," . this.getState(a.name) 168 | return str 169 | } 170 | run(scriptName){ 171 | setWorkingDir,% a_scriptDir 172 | dllPath:=this.getDll(this.scripts[scriptName].dll) 173 | 174 | ; error checking 175 | if(!dllPath) 176 | return -1 177 | else if(!fileExist(dllPath)) 178 | return -2 179 | else if(!fileExist(this.scripts[scriptName].path)) 180 | return -3 181 | this.scripts[scriptName].thread:=ahkThread(this.scripts[scriptName].path,,1,dllPath) 182 | } 183 | close(scriptName){ 184 | try{ 185 | try{ 186 | this.scripts[scriptName].thread.ahkTerminate() 187 | MemoryFreeLibrary(this.scripts[scriptName].thread[""]) 188 | } 189 | this.scripts[scriptName].thread:="" 190 | } 191 | } 192 | remove(scriptName){ 193 | this.close(scriptName) 194 | this.scripts.delete(scriptName) 195 | } 196 | loadDlls(){ 197 | iniRead,dlltypes,% this.sini,dllTypes 198 | loop,parse,dlltypes,`n 199 | { 200 | regExMatch(a_loopField,"O)([^=]+)=([^$]+)",t) 201 | this.dllTypes[t[1]]:=t.2 202 | } 203 | } 204 | setDll(dllType,path){ 205 | this.dllTypes[dllType]:=path 206 | iniWrite,% path,% this.sini,dlltypes,% dllType 207 | } 208 | getDll(dllType){ 209 | return this.dllTypes[dllType] 210 | } 211 | } 212 | 213 | ahkthread_free(obj:=""){ 214 | static objects 215 | if !objects 216 | objects:=[] 217 | if (obj="") 218 | objects:=[] 219 | else if !IsObject(obj) 220 | return objects 221 | else If objects.HasKey(obj) 222 | objects.Remove(obj) 223 | } 224 | ahkthread(s:="",p:="",IsFile:=0,dll:=""){ 225 | static ahkdll,ahkmini,base,functions 226 | if !base 227 | base:={__Delete:"ahkthread_release"},UnZipRawMemory(LockResource(LoadResource(0,hRes:=DllCall("FindResource","PTR",0,"Str","F903E44B8A904483A1732BA84EA6191F","PTR",10,"PTR"))),SizeofResource(0,hRes),ahkdll) 228 | ,UnZipRawMemory(LockResource(LoadResource(0,hRes:=DllCall("FindResource","PTR",0,"Str","FC2328B39C194A4788051A3B01B1E7D5","PTR",10,"PTR"))),SizeofResource(0,hRes),ahkmini) 229 | ,functions:={_ahkFunction:"s==stttttttttt",_ahkPostFunction:"i==stttttttttt",ahkFunction:"s==sssssssssss",ahkPostFunction:"i==sssssssssss",ahkdll:"ut==sss",ahktextdll:"ut==sss",ahkReady:"",ahkReload:"i==i",ahkTerminate:"i==i",addFile:"ut==sucuc",addScript:"ut==si",ahkExec:"ui==s",ahkassign:"ui==ss",ahkExecuteLine:"ut==utuiui",ahkFindFunc:"ut==s",ahkFindLabel:"ut==s",ahkgetvar:"s==sui",ahkLabel:"ui==sui",ahkPause:"i==s",ahkIsUnicode:""} 230 | obj:={(""):lib:=MemoryLoadLibrary(dll=""?&ahkdll:dll="FC2328B39C194A4788051A3B01B1E7D5"?&ahkmini:dll),base:base} 231 | for k,v in functions 232 | obj[k]:=DynaCall(MemoryGetProcAddress(lib,A_Index>2?k:SubStr(k,2)),v) 233 | If !(s+0!="" || s=0) 234 | obj.hThread:=obj[IsFile?"ahkdll":"ahktextdll"](s,"",p) 235 | ahkthread_free(true)[obj]:=1 ; keep dll loaded even if returned object is freed 236 | return obj 237 | } --------------------------------------------------------------------------------