1

Тема: AHK: Выполнение команды из переменной

Собственно сабж.В переменной бы имеем некую команду,нужно ее выполнить.

2 (изменено: creature.ws, 2012-10-20 13:53:14)

Re: AHK: Выполнение команды из переменной

В переменной вы имеете текст. Текст состоит из той же последовательности символов, что и имя некой команды существующей в ahk.
Встроенных средств интерпретации текста в переменной как исполняемого кода в ahk нет.
Если в процессе написания скрипта у вас возникло желание выполнять текст как код — уместно пересмотреть используемый в написании подход. Если после вдумчивого поиска, альтернатив обсуждаемому решению не нашлось — существует AutoHotkey_H. Подробности по ссылке.

В частных случаях можно обойтись:


; ahk_l unicode
; способ подразумевает отсутствие взаимодействия запущенной команды и запускающего скрипта
var := "msgbox"
DynaRun(var)

DynaRun(tempScript, pipeName = "")
{
    static DefaultArgs := ["UInt", 2, "UInt", 0, "UInt", 255, "UInt", 0, "UInt", 0, "Ptr", 0, "Ptr", 0, "Ptr"]
    static BOM := Chr(0xFEFF)

    (pipeName = "" && pipeName := "AHK_" . A_TickCount)

    pipeGA := DllCall("CreateNamedPipe", "Str", "\\.\pipe\" pipeName, DefaultArgs*)
    pipe := DllCall("CreateNamedPipe", "Str", "\\.\pipe\" pipeName, DefaultArgs*)
    if (pipe = -1 || pipeGA = -1)
        return false

    Run, % A_AhkPath . " ""\\.\pipe\" . pipeName . """",, UseErrorLevel HIDE, processID
    if ErrorLevel
        MsgBox, 262144, ERROR, % "Could not open file:`n ""\\.\pipe\" . pipeName . """"

    DllCall("ConnectNamedPipe", "Ptr", pipeGA, "Ptr", 0), DllCall("CloseHandle", "Ptr", pipeGA)
    DllCall("ConnectNamedPipe", "Ptr", pipe, "Ptr", 0)
    , tempScript := BOM . tempScript
    , tempScriptSize := (StrLen(tempScript)+1)*2
    if !DllCall("WriteFile", "Ptr", pipe, "Str", tempScript, "UInt", tempScriptSize, "UInt*", 0, "Ptr", 0)
        return A_LastError
    DllCall("CloseHandle", "Ptr", pipe)

    return processID
}

3

Re: AHK: Выполнение команды из переменной

creature.ws, а почему пайп, а не файл?

4

Re: AHK: Выполнение команды из переменной

Без лишних записей на диск, видимо. Функция взята с оф. форума и слегка модифицирована.

5 (изменено: Александр_, 2012-10-20 13:50:01)

Re: AHK: Выполнение команды из переменной

creature.ws пишет:

Без лишних записей на диск, видимо. Функция взята с оф. форума и слегка модифицирована.

Можно пометить файл как временный, тогда мусора на винчестере не будет(а на NTFS можно ещё и в поток к своему скрипту записать). Пайпы нужны для взаимодействия потоков внутри рабочей группы/домена, по сути это всё равно, что использовать сокеты.

6

Re: AHK: Выполнение команды из переменной

Запись в ntfs-поток — хорошая альтернатива. К сожалению, не знаю способа удаления ntfs-потока без удаления «родительского» файла.

7

Re: AHK: Выполнение команды из переменной

Для создания/удаления/записи/чтения из потоков применяются те же WinAPI функции, что и для обычных файлов.

8 (изменено: creature.ws, 2012-10-20 16:58:41)

Re: AHK: Выполнение команды из переменной

Тогда так:

DynaRun(tempScript, streamName = "")
{
    (streamName = "" && streamName := "AHK_" . A_TickCount)
    streamName := "\\.\" . A_ScriptFullPath . ":" . streamName
    stream := FileOpen(streamName, "rw")
    stream.Write(tempScript)
    stream.Close()

    Run, % A_AhkPath . " """ . streamName . """",, UseErrorLevel HIDE, processID
    if ErrorLevel
        MsgBox, 262144, ERROR, % "Could not open file:`n """ . streamName . """"

    Sleep 50 ; иначе скрипт не успевает загрузится из потока
    DllCall("DeleteFile", "Str", streamName, "UInt")

    return processID
}

var := "msgbox % A_ScriptFullPath"
DynaRun(var)
msgbox % A_ScriptFullPath

Странно, что FileDelete, file:stream не работает как ожидается.