При желании можно сделать вывод программы в контрол Edit. См. пример ниже. Запустите скрипт и введите что-нибудь в нижнее поле, например, ping localhost или т.п.
Gui, Add, Edit, w480 h300 HWNDhwndOutput
Gui, Add, Edit, w480 r1 vCmdLine
Gui, Add, Button, Default w80 h20 gExec, Выполнить
GuiControl, Focus, CmdLine
Gui, Show
Return
Exec:
GuiControlGet, CmdLine
RunConAppToEdit(CmdLine, "", hwndOutput)
Return
GuiClose:
ExitApp
RunConAppToEdit(CmdLine, Input, hwndEdit)
{
static BufSizeChar := 1024, hParent := 0
static Show := 0, Flags := 0x101 ; STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW
static Buf, BufSizeByte, ProcessInfo, StartupInfo, PipeAttribs
static piSize, siSize, paSize, flOffset, shOffset, ihOffset
static inOffset, outOffset, errOffset, thrOffset
If (!hParent) {
BufSizeByte := A_IsUnicode ? BufSizeChar * 2 : BufSizeChar
If (A_PtrSize = 8) {
piSize := 24, siSize := 104, paSize = 24
flOffset := 60, shOffset := 64, ihOffset := 16
inOffset := 80, outOffset := 88, errOffset := 96
thrOffset := 8
}
Else {
piSize := 16, siSize := 68, paSize = 12
flOffset := 44, shOffset := 48, ihOffset := 8
inOffset := 56, outOffset := 60, errOffset := 64
thrOffset := 4
}
VarSetCapacity(Buf, BufSizeByte, 0), VarSetCapacity(ProcessInfo, piSize, 0)
VarSetCapacity(StartupInfo, siSize, 0), VarSetCapacity(PipeAttribs, paSize, 0)
NumPut(siSize, StartupInfo, 0, "uint"), NumPut(Flags, StartupInfo, flOffset, "uint")
NumPut(Show, StartupInfo, shOffset, "ushort")
NumPut(paSize, PipeAttribs, 0, "uint"), NumPut(1, PipeAttribs, ihOffset, "int")
hParent := DllCall("GetCurrentProcess", "ptr")
}
DllCall("CreatePipe", "ptr *", hRead1_tmp, "ptr *", hWrite2
, "ptr", &PipeAttribs, "uint", 0)
DllCall("CreatePipe", "ptr *", hRead2, "ptr *", hWrite1_tmp
, "ptr", &PipeAttribs, "uint", 0)
NumPut(hRead2, StartupInfo, inOffset, "ptr")
NumPut(hWrite2, StartupInfo, outOffset, "ptr")
NumPut(hWrite2, StartupInfo, errOffset, "ptr")
DllCall("DuplicateHandle", "ptr", hParent, "ptr", hRead1_tmp
, "ptr", hParent, "ptr *", hRead1
, "uint", 0, "uint", 0
, "uint", 2) ; DUPLICATE_SAME_ACCESS
DllCall("CloseHandle", "ptr", hRead1_tmp)
DllCall("DuplicateHandle", "ptr", hParent, "ptr", hWrite1_tmp
, "ptr", hParent, "ptr *", hWrite1
, "uint", 0, "uint", 0
, "uint", 2)
DllCall("CloseHandle", "ptr", hWrite1_tmp)
DllCall("ExpandEnvironmentStrings", "str", CmdLine, "str", Buf, "uint", BufSizeChar)
CmdLine := Buf
Ret := DllCall("CreateProcess", "ptr", 0, "str", CmdLine, "ptr", 0, "ptr", 0
, "uint", 1, "uint", 0, "ptr", 0, "ptr", 0
, "ptr", &StartupInfo, "ptr", &ProcessInfo)
If (!Ret) {
MsgBox,, %A_ThisFunc%, Не удалось создать процесс.
Output := ""
Return 1
}
hChild := NumGet(ProcessInfo, 0, "ptr")
DllCall("CloseHandle", "ptr", NumGet(ProcessInfo, thrOffset, "ptr"))
DllCall("CloseHandle", "ptr", hRead2)
DllCall("CloseHandle", "ptr", hWrite2)
If (Input) {
InLen := StrLen(Input) + 2
VarSetCapacity(InBuf, InLen, 0)
StrPut(Input . "`r`n", &InBuf, "cp866")
DllCall("WriteFile", "ptr", hWrite1, "ptr", &InBuf, "uint", InLen
, "uint *", BytesWritten, "uint", 0)
}
DllCall("CloseHandle", "ptr", hWrite1)
Output := ""
Loop {
If not DllCall("ReadFile", "ptr", hRead1, "ptr", &Buf, "uint", BufSizeByte
, "uint *", BytesRead, "uint", 0)
Break
NumPut(0, Buf, BytesRead, "Char")
Output := StrGet(&Buf, "cp866") . "`n"
SendMessage, 0xC2, False, &Output,, ahk_id %hwndEdit%
}
DllCall("CloseHandle", "ptr", hRead1)
DllCall("GetExitCodeProcess", "ptr", hChild, "int *", ExitCode)
DllCall("CloseHandle", "ptr", hChild)
Return ExitCode
}