1

Тема: AHK: работа с консольными утилитами и командами

Необходима универсальная функция для всех версий ahk (a32, u32, u64), которая бы позволяла последовательно выполнять одну или несколько консольных команд или утилит и получать их StdOut (или если он пуст, то - StdErr) в переменную, причём так, чтобы окно консоли не появлялось ни на долю секунды.

В файле справки на странице о команде run есть такой код:

RunWaitMany(commands) {
    shell := ComObjCreate("WScript.Shell")
    ; Open cmd.exe with echoing of commands disabled
    exec := shell.Exec(ComSpec " /Q /K echo off")
    ; Send the commands to execute, separated by newline
    exec.StdIn.WriteLine(commands "`nexit")  ; Always exit at the end!
    ; Read and return the output of all commands
    return exec.StdOut.ReadAll()
}

Но с ним появляется окно консоли.

Товарищ с irc-канала дал такой код:

RunWaitOne(command) {
	WinGet,pid,pid,ahk_id%A_ScriptHwnd%
	DetectHiddenWindows, on
	Run,%comspec% /k,,Hide UseErrorLevel, cPid
	WinWait, ahk_pid %cPid%,,10
	DllCall("AttachConsole","uint",cPid),hCon:=DllCall("CreateFile","str","CONOUT$","uint",0xC0000000,"uint",7,"uint",0,"uint",3,"uint",0,"uint",0),shell:=ComObjCreate("WScript.Shell"),exec:=shell.Exec(command),DllCall("CloseHandle","uint",hCon),DllCall("FreeConsole")
	if(info:=exec.Stderr.ReadAll()){
		return info
	}else{
		return exec.stdout.ReadAll()
	}
}

Но он у меня (на u64) выдаёт ошибку (это даже если код не менять, ведь он заточен под выполнение только одной команды, а не нескольких).

Пробовал искать по ключевому запросу "autohotkey DllCall AttachConsole" - и нашёлся код с этого форума где используется

DllCall("AttachConsole", "Ptr"

вместо

DllCall("AttachConsole","UInt"

, в другом месте нашёлся вариант и такой вариант использования:

DllCall("AttachConsole", "UInt", cPID, "Cdecl int")

, а где-то и такой:

    
DllCall("AttachConsole", int, -1, int)

, а ещё есть вариант от самого lexikos'а, но там код старый и уж больно много его.

Другими словами - я окончательно запутался и хочу один рабочий код.
Умеющие транслировать WinAPI в DllCallы - подсобите, пожалуйста.

2

Re: AHK: работа с консольными утилитами и командами

Посмотрите это.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

3

Re: AHK: работа с консольными утилитами и командами

teadrinker, посмотрел, оно выдаёт пустоту в ответ на аргумент "echo abc".

4

Re: AHK: работа с консольными утилитами и командами

 MsgBox, % CMDret("cmd /c echo abc")

Как-то так, без компа сейчас.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

5 (изменено: Drugoy, 2016-05-13 23:55:52)

Re: AHK: работа с консольными утилитами и командами

teadrinker, спасибо, да, так работает.
Не очень понял когда требуется "cmd /c" а когда оно не обязательно.

И ещё: умеет ли эта функция выполнять несколько команд подряд? Если да - то чем их разделять (попробовал `n - не помогло)?

6

Re: AHK: работа с консольными утилитами и командами

teadrinker
и ещё: команда "type aa.txt>bb.txt" не отрабатывает (должно происходить копирование текстового содержимого файла в другой).

7

Re: AHK: работа с консольными утилитами и командами

чем их разделять

Обычно &&. Остальное только в вск смогу посмотреть.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

8

Re: AHK: работа с консольными утилитами и командами

Вот ещё вариант: AHK: Запуск консольного приложения с перехватом его ввода и вывода.

9 (изменено: Drugoy, 2016-05-15 01:19:42)

Re: AHK: работа с консольными утилитами и командами

YMP, благодарю, вроде подходит, но есть пара вопросов:

1. у вас там в коде есть переменная "BytesWritten", которая указана всего однажды - она точно нужна?
2. можно ли как-то просто избавиться от текста, не относящегося к output? Т.е. вырезать cmd'шное приветствие ("Microsoft Windows … (c) Корпорация Майкрософт … Все права защищены."), prompt ("C:\path\to\script.ahk\>") и input (т.е. отправляемые команды)? Хочется чистого output'а, не хочется вручную парсить текущую выдачу.

10 (изменено: YMP, 2016-05-15 06:33:22)

Re: AHK: работа с консольными утилитами и командами

1. В описаниях говорится, что этот параметр может быть нулём только в случае асинхронного чтения или записи, а здесь синхронное. Так что хотя и не используется, но приходится указывать.

2. Простого способа, видимо, нет. Команды из вывода cmd.exe можно исключить параметром /q, но всё остальное остаётся. Содержимое вывода зависит от запускаемой программы, поэтому встроить в саму функцию какой-то один для всех парсер нет возможности. Придётся фильтровать уже на выходе функции.

11

Re: AHK: работа с консольными утилитами и командами

Drugoy пишет:

2. можно ли как-то просто избавиться от текста, не относящегося к output? Т.е. вырезать cmd'шное приветствие ("Microsoft Windows … (c) Корпорация Майкрософт … Все права защищены."), prompt ("C:\path\to\script.ahk\>") и input (т.е. отправляемые команды)?

cmd /q /k echo off
Забыл пароль и потерял e-mail.