Dynamic scripting has various uses. Examples include:
[*:2mvn5eww]ACConsole is like a command prompt window where you can type or paste in commands to execute.
[*:2mvn5eww]expression and variable? - In this thread are examples of executing dynamic code/expressions by running a temporary script file. Throughout the thread are various methods of returning the result from the temporary script, back to the "master" script.
[*:2mvn5eww]Execute AHK code dynamically! dynamically executes any given command.If, for whatever reason, you want to avoid writing a temporary script file to disk, a named pipe can be used as a "file."
There were a couple of obstacles making it difficult to pipe a script to AutoHotkey; the comments in the script explain what they are and the solutions.
Type a line of code in the InputBox, and the script will "execute" it. (The InputBox is the only reason it is limited to one line.)
#NoEnv ptr := A_PtrSize ? "Ptr" : "UInt" char_size := A_IsUnicode ? 2 : 1 InputBox, Script, Script, Enter a line of script to execute.,,, 120,,,,, MsgBox :D ; To prevent "collision", pipe_name could be something mostly "unique", like: ; pipe_name := A_TickCount pipe_name := "testpipe" ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes ; the pipe to close, so we must create a second pipe for the actual file contents. ; Open them both before starting AutoHotkey, or the second attempt to open the ; "file" will be very likely to fail. The first created instance of the pipe ; seems to reliably be "opened" first. Otherwise, WriteFile would fail. pipe_ga := CreateNamedPipe(pipe_name, 2) pipe := CreateNamedPipe(pipe_name, 2) if (pipe=-1 or pipe_ga=-1) { MsgBox CreateNamedPipe failed. ExitApp } Run, %A_AhkPath% "\\.\pipe\%pipe_name%" ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes(). DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0) ; This pipe is not needed, so close it now. (The pipe instance will not be fully ; destroyed until AutoHotkey also closes its handle.) DllCall("CloseHandle", ptr, pipe_ga) ; Wait for AutoHotkey to connect to open the "file". DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0) ; Standard AHK needs a UTF-8 BOM to work via pipe. If we're running on ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead: Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script char_size := (A_IsUnicode ? 2:1) if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0) MsgBox WriteFile failed: %ErrorLevel%/%A_LastError% DllCall("CloseHandle", ptr, pipe) CreateNamedPipe(Name, OpenMode=3, PipeMode=0, MaxInstances=255) { global ptr return DllCall("CreateNamedPipe","str","\\.\pipe" Name,"uint",OpenMode ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr) }Covered by Lexikos' default copyright license.
The above script demonstrates an effective solution to one planned feature:
The ability to run AutoHotkey.exe and pass a single command (or perhaps group of commands) to execute.
Piping in General
While a pipe can act like a file, there are some major limitations: pipes do not support seeking or GetFileSize(). FileRead uses GetFileSize() internally, so cannot be used with pipes. Many other applications will attempt to read the "file" (pipe), but will fail. (Notepad and Wordpad included.)
You may have more luck with other applications. I have seen a few scripts that use temporary .vbs files, but I have yet to try running one through a pipe.
Interestingly, Loop, Read and FileReadLine do work with pipes.
Update 2010-07-23: Added support for Unicode and 64-bit builds of AutoHotkey.
Update 2010-08-01: Fixed some weird typo. char_size := (...) had become Script_size := *(...).