我正在尝试使用AutoHotkey阅读Windows CMD的标准输出。例如,我想让AHK中的set
控制台命令的输出存储在一个变量中。我已经在不久前实现了它,这使我更加困惑为什么它现在不起作用
在AHK论坛中,有一个相当old thread关于 CMDret ,这是一个基于DLL的功能,可以完全按照我的意愿行事。第一个问题是为它找到一个有效的下载,因为帖子中的所有链接都已经死了。 Google给了我another site,托管 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 ;附上的自述文件说:
如果函数失败,则返回值为零。
进一步向下,它说:
注意:仅32位控制台应用程序目前可以使用 这个DLL版本的CMDret(v3.1.2或更低版本)。需要的电话 command.com可能不会产生任何输出并可能崩溃。避免 这个我已经包含了一个名为“cmdstub.exe”的文件和下载(在 Win9x文件夹)。调用 16位时应使用此文件 控制台应用程序以启用返回输出。
总之,我不确定问题是什么。我的机器运行在64位。但自述文件中的相应条款是否应该单独排除16位系统,还是只包含32位? 如果计算架构可能不是问题,那么可能是什么?
我正在寻找的是以下任何一种:
答案 0 :(得分:1)
如果您不需要实时输出,可以使用cmd框本身保存自身的文本文件,然后您可以在控制台的PID完成时使用autohotkey检测(使用返回的runwait
结果并将输出的文件读入内存。
所以你可以在你的运行命令(只是常规cmd参数)中执行此操作:
ipconfig > myoutput.txt
exit
现在你有一个带有ipconfig输出的文本文件。
OR 你可以做同样的事情,但不是输出到文本文件,你可以输出到剪贴板,如下所示:
ipconfig | clip
然后,由于输出在剪贴板上,您可以轻松地将其抓取到autohotkey。
答案 1 :(得分:1)
这一直困扰着我一段时间 - 最后这种方法有效!
唯一的先决条件是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")
由于每次更新相同的字段,您显然需要在每个字段之间执行某些操作以使此示例有用!
尝试一下,让我知道你是怎么做到的
此致,杰夫
答案 2 :(得分:0)
我发现了一个仅适用于AutoHotKey L 64bit的脚本解决方案: http://www.autohotkey.com/board/topic/67687-ahkahk-lusing-wsh-to-interact-with-command-line-progs/
稍微玩了一下后,我能够使用DOS Type命令列出我列出的40k文本文件的整个输出。有一个演示,展示了如何与time命令进行交互,如果你需要与dos命令或批处理脚本进行有限的双向交互,那就很好。
答案 3 :(得分:0)
这个脚本StdoutToVar
怎么样?
它支持64位控制台。
http://www.autohotkey.com/board/topic/15455-stdouttovar/page-7
答案 4 :(得分:0)
从2019年11月开始,新的推荐的两种操作方式-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")