Захват вывода CMD с помощью AutoHotkey

Я пытаюсь прочитать стандартный вывод Windows CMD с помощью AutoHotkey. Например, я хотел бы, чтобы вывод команды setconsole внутри AHK сохранялся в переменной. Я уже добился этого некоторое время назад, и поэтому я еще больше недоумеваю, почему он не работает сейчас.
На форумах AHK есть довольно старый поток о CMDret, функции на основе библиотеки DLL, чтобы делать именно то, что Я хочу. Первой проблемой было найти для него рабочую загрузку, так как все ссылки в посте были мертвы. Google предоставил мне другой сайт с хостингом v3.1.2. . Хотя кажется, что есть более новый (v3.2.1 соответственно 4d Beta), я проверил его и протестировал простой пример:

msgbox % CMDret(COMSPEC " /C set")
CMDret(CMD) 
{ 
  VarSetCapacity(StrOut, 10000) 
  RetVal := DllCall("cmdret.dll\RunReturn", "str", CMD, "str", StrOut)
  Return, %StrOut%
}

К сожалению, MsgBox ничего не содержал. Затем я проверил RetVal со значением 0; а в прилагаемом файле readme говорится:

Если функция не работает, возвращаемое значение равно нулю.

Ниже написано:

Примечание. только 32-битные консольные приложения в настоящее время будут работать с этой версией DLL CMDret (v3.1.2 или ниже). Вызовы, для которых требуется command.com, скорее всего, не выдадут никаких результатов и могут привести к сбою. Чтобы избежать этого, я включил в загрузку файл с именем «cmdstub.exe» (в папке Win9x). Этот файл следует использовать при вызове 16-битных консольных приложений, чтобы разрешить возврат вывода.

В заключение, я не уверен, в чем проблема. Моя машина работает на 64-битной версии. Но должен ли соответствующий пункт в файле readme исключать исключительно 16-битные системы или он включает только 32-битные?
Если вычислительная архитектура, вероятно, не является проблемой, то что может быть?

Я ищу одно из следующих:

  1. Могу ли я решить проблему и продолжать использовать v3.1.2?
  2. Есть ли у кого-нибудь рабочий источник (или даже локальная копия) более новой версии, которую я мог бы проверить?
  3. Есть ли другой подход [библиотека, код .ahk и т. Д.], Который я мог бы использовать для своих целей? (желательно аналогично, потому что CMDret кажется очень простым)

person MCL    schedule 04.04.2013    source источник
comment
Привет! ;) вам все еще нужен ответ? Я просто просматривал и нашел этот вопрос, это можно сделать полностью в ahk, я отправлю ответ, когда смогу ... Сейчас я путешествую ...   -  person Joe DF    schedule 23.08.2014


Ответы (5)


Если вам не нужен прямой вывод, вы можете использовать само поле cmd для сохранения самого текстового файла, а затем вы можете настроить autohotkey, чтобы определить, когда PID консоли завершился (используя возвращенный результат runwait и прочитать полученный файл в памяти .

Таким образом, вы можете сделать это в своей команде запуска (просто обычный параметр cmd):

ipconfig > myoutput.txt
exit

Теперь у вас есть текстовый файл с выводом ipconfig.

ИЛИ вы можете сделать то же самое, но вместо вывода в текстовый файл вы можете вывести его в буфер обмена, например:

ipconfig | clip

Затем, поскольку результат находится в буфере обмена, вы можете легко захватить его в autohotkey.

person bgmCoder    schedule 24.06.2013
comment
Я тоже вижу здесь проблему с безопасностью. Поскольку я обрабатываю конфиденциальные данные, я не хочу, чтобы мои пароли отображались в файле или в буфере обмена. Также мне нужна возможность захватывать поток в реальном времени. Я думаю, что использовать эти методы было бы довольно сложно. - person MCL; 28.06.2013
comment
Ну, конечно, вам придется разобраться с этим в сценарии. Если он чувствительный, вы не можете использовать буфер обмена, потому что его может отслеживать что-то еще. Однако, если вы выводите в текстовый файл и загружаете файл в память, вы можете стереть текстовый файл и удалить его. Я делаю это в некоторых своих приложениях, и это прекрасно работает. Для этого потребуется всего три или четыре строки кода автотракторной клавиши. - person bgmCoder; 28.06.2013
comment
К файлам также может получить доступ любой другой процесс. Конечно, файл существует не очень долго, и, возможно, я немного параноик, но все же есть шанс, которым я не хочу рисковать. Тем более, что AHK удаляет только файлы, что не делает данные нечитаемыми. - person MCL; 29.06.2013
comment
Хммм ... если стереть содержимое перед его удалением (с помощью fileopen). - person bgmCoder; 29.06.2013
comment
Это великолепно! Я использую эту команду, чтобы сохранить свой IP-адрес WAN в переменной: nslookup myip.opendns.com resolver1.opendns.com | find /i "address" | find /v "208.67.222.222" | clip - person Shayan; 14.06.2019

Новые рекомендуемые 2 способа сделать с ноября 2019 г. - https://www.autohotkey.com/docs/FAQ.htm#output:

Как можно получить вывод операции из командной строки?

Тестирование показывает, что из-за кеширования файла временный файл может быть очень быстрым для относительно небольших выходных данных. Фактически, если файл удаляется сразу после использования, он часто не записывается на диск. Например:

RunWait %ComSpec% /c dir > C:\My Temp File.txt
FileRead, VarToContainContents, C:\My Temp File.txt
FileDelete, C:\My Temp File.txt

Чтобы избежать использования временного файла (особенно если вывод большой), рассмотрите возможность использования метода Shell.Exec (), как показано в примерах для команды «Выполнить».

Пример команды «Выполнить» - https://www.autohotkey.com/docs/commands/Run.htm#StdOut:

MsgBox % RunWaitOne("dir " A_ScriptDir)


RunWaitOne(command) {
    shell := ComObjCreate("WScript.Shell")
    exec := shell.Exec(ComSpec " /C " command)
    return exec.StdOut.ReadAll()
}

Примечание: последний метод (shell.Exec) приведет к быстрому отображению окна cmd. Вы можете сократить продолжительность его появления, поместив эти строки в верхнюю часть вашего скрипта, что также вызовет мерцание только один раз при первом вызове команды cmd. Из https://autohotkey.com/board/topic/92032-how-to-hide-a-wscript-comspec-window/:

;Following 2 lines : the cmd window will flash only once and quickly
DllCall("AllocConsole")
WinHide % "ahk_id " DllCall("GetConsoleWindow", "ptr")
person amynbe    schedule 14.11.2019

Как насчет этого скрипта, StdoutToVar?
Он поддерживает 64-битные консоли. http://www.autohotkey.com/board/topic/15455-stdouttovar/page-7

person bgmCoder    schedule 29.06.2013
comment
Я тоже нашел это, но не тестировал github.com/camerb/ AHKs / blob / master / thirdParty / StdoutToVar.ahk - person Shayan; 14.06.2019

Это меня уже некоторое время беспокоит - и, наконец, это сработало!

Единственным предварительным условием для этого является MS sqlcmd.exe, база данных с именем AHK_Dev и, конечно же, AHK_DBA для чтения значения, когда вы хотите его использовать.

PS. убедитесь, что вы заменили {yourDir} и {yourServer} собственными значениями!

USE AHK_DEV
CREATE TABLE [dbo].[AHK_DOS]([dos_out] [varchar](max) NULL) ON [PRIMARY];
insert into ahk_dos select 'empty'

Создайте следующий скрипт ... назовите его dos_out.bat

@echo off
if "%1" == "" ( 
    set v_cmd=""
) else (
    set v_cmd=%1
)
set v_cmd=%v_cmd:~1,-1%
SETLOCAL ENABLEDELAYEDEXPANSION
if "!v_cmd!" == "" (
    set v_cmd="echo ... %COMPUTERNAME% %USERNAME% %DATE% %TIME%"
    set v_cmd=!v_cmd:~1,-1!
)
set v_data=""
FOR /F "usebackq delims=¬" %%i in (`!v_cmd!`) do (
    set v_data="!v_data:~1,-1!%%i~"
)
set q_cmd="set nocount on;update ahk_dos set dos_out=N'!v_data:~1,-1!'"
"{yourDir}\Microsoft SQL Server\90\Tools\Binn\sqlcmd.exe" -S {yourServer} -E -d ahk_dev -Q !q_cmd! -W 
set q_cmd="set nocount on;select len(dos_out) as out_len, dos_out from ahk_dos"
"{yourDir}\Microsoft SQL Server\90\Tools\Binn\sqlcmd.exe" -S {yourServer} -E -d ahk_dev -Q !q_cmd! -W -w 8000
pause

вы можете запустить его из AHK, используя ...

dosCmd2db(c) {
runwait, {yourDir\}dos_out.bat "%c%", , , dospid
msgbox %dospid% closed
}
dosCmd2db("")
dosCmd2db("echo This is a test")
dosCmd2db("dir")

Поскольку одно и то же поле обновляется каждый раз, вам явно нужно будет что-то делать между каждым, чтобы сделать этот пример полезным!

Попробуйте и дайте мне знать, как у вас дела.

С уважением, Джефф

person geoff    schedule 21.02.2014
comment
Фу! Насколько я понимаю, это будет создавать и писать / читать из локальной базы данных? Звучит ужасно обширно. Кроме того, одно из моих требований заключается в том, чтобы никакие данные не были доступны другим процессам, поскольку я хочу передавать пароли в качестве параметров. Я не хочу, чтобы они отображались в базе данных. - person MCL; 21.02.2014

Я нашел решение только для скрипта, которое работает для AutoHotKey L 64bit по адресу: http://www.autohotkey.com/board/topic/67687-ahkahk-lusing-wsh-to-interact-with-command-line-progs/

Немного поиграв с ним, я смог записать весь вывод текстового файла размером 40 КБ, который я перечислил, используя команду DOS Type. Существует демонстрация, которая показывает, как вы можете взаимодействовать с командой time, что удобно, если вам нужно ограниченное двустороннее взаимодействие с командой dos или пакетным скриптом.

person Community    schedule 21.06.2013
comment
Я тем временем нашел и эту. К сожалению, он всегда создает окно, и я хочу избежать этого, тем более что я вызываю утилиты с конфиденциальными данными, такими как пароли. - person MCL; 21.06.2013