Compile() 0.41
Download Compile.ahk or read the Documentation [ Alternate download link ]
Tested in _Basic and _L
i was thinking about making an app or modifying others i've seen, but this stdlib compliant function solves my needs pretty nicely
Example calls:
Compile("Run") ;= compiles .ahk into .exe, runs the .exe and exits the .ahk ;= making the .ahk like a shortcut to a freshly compiled exe when in the auto-execute section Compile() ;= compiles .ahk into .exe, but continues running the .ahk, for compiling on demand but to continue running the uncompiled .ahk
Example script:
#SingleInstance Force SetWorkingDir, % A_ScriptDir IfNotExist, % Icon := "CompileDemo.ico" GoSub, CreateIcon Compile("Run") ; or try: ; Compile() ; Compile("NoWait") MsgBox, The file currently running:`n`n%A_ScriptName% Return CreateIcon: IconData = ( join 000001000100101000000100080068050000160000002800000010000000200000000100080000000000000000 000000000000000000000000000000000000000000044f5b0013545f0016565f000c556000045b69000e5e6a00 15576100036f7f00046e7f000c6e7d001e6c780032626a002c6a7300346c750045717900527277007275760077 777700036f800005708100457c8500517980000485990007889b002c869400059ab100099ab100349dad0030ac bf004a919d00798688007a888b00668c9300738c90007d8f9300679ca4006facb60005adc70005aec8001eadc4 0026b8cf0069b5c1006fb9c50010c1dd0006c2e00007c6e40011c5e10016c5e1001dcbe6003acbe10040c2d700 6fc5d20063cada006dcfde0053cee1004ed5e90073dcec00869b9f00939393009394940091999a009ca2a3008f b1b600a1a1a100a0a5a500a6a6a600afbdbf00b1b2b200b3b4b400bbbbbb0084bbc40095bac10096c3ca0096cc d5009acfd80095d4de0099d5df00b3c4c700bbced200b9d6db0096dce700a3dae300a3dde6008ee3ef00b2e8f0 00bbedf400c0c0c000c5c5c500c1c7c800cacaca00cacdcd00cecece00c7d4d600cad0d100c7dade00c9dadc00 d1d1d100d6d6d600d3d8d900d0dddf00d9d9d900d9dedf00dedede00c7dfe300c4e3e700cde0e400c7e4e800c6 e7ec00cee6e900d3e0e200dae1e200dee0e100d4e6e800dae6e800c6ebf100e1e1e100eaf5f600a9cf0000c2f0 0000d1ff1100d8ff3100deff5100e3ff7100e9ff9100efffb100f6ffd100ffffff00000000002f260000504100 00705b000090740000b08e0000cfa90000f0c30000ffd21100ffd83100ffdd5100ffe47100ffea9100fff0b100 fff6d100ffffff00000000002f1400005022000070300000903e0000b04d0000cf5b0000f0690000ff791100ff 8a3100ff9d5100ffaf7100ffc19100ffd2b100ffe5d100ffffff00000000002f03000050040000700600009009 0000b00a0000cf0c0000f00e0000ff201200ff3e3100ff5c5100ff7a7100ff979100ffb6b100ffd4d100ffffff 00000000002f000e00500017007000210090002b00b0003600cf004000f0004900ff115a00ff317000ff518600 ff719c00ff91b200ffb1c800ffd1df00ffffff00000000002f0020005000360070004c0090006200b0007800cf 008e00f000a400ff11b300ff31be00ff51c700ff71d100ff91dc00ffb1e500ffd1f000ffffff00000000002c00 2f004b0050006900700087009000a500b000c400cf00e100f000f011ff00f231ff00f451ff00f671ff00f791ff 00f9b1ff00fbd1ff00ffffff00000000001b002f002d0050003f007000520090006300b0007600cf008800f000 9911ff00a631ff00b451ff00c271ff00cf91ff00dcb1ff00ebd1ff00ffffff000000000008002f000e00500015 0070001b0090002100b0002600cf002c00f0003e11ff005831ff007151ff008c71ff00a691ff00bfb1ff00dad1 ff00ffffff00747474747474655a58627474747474747474747474675a423b466774747474747474747474625b 40124065747474747474747474745b5e3e113c5c74747474747474747474472a1e0f1f57747474747474747474 66281b170a16446774747474747474704b271a17130d3d62747474747474745033271a17130610456274747474 7464352c261a17130503205767747474744d302d261a181405010c416274747474372e2f291d1c190b04022361 7474747432313836342b25241507226174747474373854514c4a49483f0e3a6574747474523956736c6b685f4f 215974747474746e535575757575724e43677474747474746f6a696d71605d6367747474740000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000 ) WriteFile(Icon,IconData) Return WriteFile(file,data) { Handle := DllCall("CreateFile","str",file,"Uint",0x40000000 ,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0) Loop { if strlen(data) = 0 Break StringLeft, Hex, data, 2 StringTrimLeft, data, data, 2 Hex = 0x%Hex% DllCall("WriteFile","UInt", Handle,"UChar *", Hex ,"UInt",1,"UInt *",UnusedVariable,"UInt",0) } DllCall("CloseHandle", "Uint", Handle) Return }
Function code:
;; ; Compile() - 0.41 - by gwarble ; compile your script on demand, with local icons/AutoHotkey.bin ; ; Compile(Action,Name,Password) ; ; Action "" [Default] -waits for the compiler to finish before returning ; Run -to run the compiled script and close the running script ; NoWait -starts compiling and continues running your script ; Recompile -closes the running .exe and launches the .ahk (if compiled) ; (useful for a self-editing compiled script) ; ; Name "" [Default] -uses filename of script for exe/ico/bin filenames ; Other -specify a different name for the input ico/bin and output exe ; ; Password ** -compilation password ; ; Return 1 on success ; 0 on failure, compiler not found, already compiled, etc... ; ; Notes save custom icon as ScriptName.ico (in a subdir is ok) or ; save modified AutoHotkeySC.bin as ScriptName.AHK.bin ; Compile(Action="",Name="",Password="") { If A_IsCompiled If Action <> Recompile ; unless "ReCompile", function does nothing when running compiled Return 0 Else { SplitPath, A_ScriptFullPath,,,,ScriptName Run, %ScriptName%.ahk ; if is Recompile, will close the running exe and launch the ahk script Return 1 ; which should have its own auto-exeute Compile("Run") } SplitPath, A_ScriptFullPath,, ScriptDir,, ScriptName If Name <> ScriptName := Name ; Name parameter overrides icon/exe name from Scripts name Icon := ExeFile := ScriptDir "\" ScriptName ".exe" Loop, %ScriptName%.AHK.bin, 0, 1 ; find .AHK.bin file if it exists, including subdirs IfExist %A_LoopFileFullPath% { Icon := CompilerBin := A_LoopFileFullPath Break } If CompilerBin = ; otherwise, use a found ScriptName.ico for the compile process Loop, %ScriptName%.ico, 0, 1 ; including subdirs IfExist %A_LoopFileFullPath% { ScriptIcon = /icon "%A_LoopFileFullPath%" Icon = %A_LoopFileFullPath% ; and sets it for the run string to run the compiler later Break } SplitPath, A_AhkPath,, Compiler,,, ; find compiler... Compiler := Compiler "\Compiler\Ahk2Exe.exe" ; assumes compiler is in AHKPath default Compiler dir IfNotExist %Compiler% ; otherwise, checks registry for AHK install dir { ; poor method checks the context menu for the compile command RegRead, Compiler, HKCR, AutoHotkeyScript\Shell\Compile\Command ; for location of compiler StringReplace, Compiler, Compiler, ",,All StringReplace, Compiler, Compiler, % "/in %l" ; and clean up that context menu command to the exe path IfNotExist %Compiler% { Loop %A_StartMenuCommon%\*.*, 0, 1 ; otherwise check the start menu for compiler's default shortcut If A_LoopFileName contains convert .ahk to .exe { FileGetShortcut, % A_LoopFileFullPath, Compiler Break } IfNotExist %Compiler% ; otherwise assumes AHK (and compiler) is not installed Loop, %A_ScriptDir%\Ahk2Exe.exe, 0, 1 ; so checks the local dir for the compiler Compiler := %A_LoopFileFullPath% ; including subdirs } IfNotExist %Compiler% ; and after all that if no compiler is found, returns error (0) Return 0 ; compiler not found } Prev_DetectHiddenWindows := A_DetectHiddenWindows DetectHiddenWindows On ; loop to WinClose all running processes before compiling Loop IfWinExist, % ExeFile,,30 WinClose Else Break DetectHiddenWindows %Prev_DetectHiddenWindows% If (Password) ; sets compilation password Password := "/pass " Password ; untested feature Loop, %ScriptName%.AHK.bin, 0, 1 IfExist %A_LoopFileFullPath% ; if custom .bin is used, copy it in place { ; after backing up the original SplitPath, Compiler,, CompilerDir,,, CompilerBin := CompilerDir "\AutoHotkeySC.bin" FileCopy, % CompilerBin, % CompilerDir "\AutoHotkeySC.Last.bin", 1 ; backed up original every run FileCopy, % CompilerBin, % CompilerDir "\AutoHotkeySC.Orig.bin", 0 ; first backup made won't be overwritten FileCopy, % A_LoopFileFullPath , % CompilerBin, 1 Break } ; and finally, put all those options together RunLine = %Compiler% /in "%A_ScriptFullPath%" /out "%ExeFile%" %ScriptIcon% %Password% If Action = NoWait ; decide how to run it (first parameter) Run, % RunLine, % A_ScriptDir, Hide Else RunWait, % RunLine, % A_ScriptDir, Hide If (CompilerBin) ; restore the original SC.bin file if a custom one was used FileCopy, % CompilerDir "\AutoHotkeySC.Last.bin", % CompilerBin, 1 If Action = Run ; and run the compiled script if "Run" option is used (typical) { Run, % ScriptName ExitApp } Return 1 }
nothing ground-breaking here but handy nonetheless, hope you like it, feedback greatly appreciated
- gwarble
edit: bugfix version 4, recompile working properly 8/3/10
edit: new version .41, small fixes/improvements 1/2012