; ======= Функция RunCon ==================================
RunCon(CmdLine, Input, ByRef Output)
{
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")
}
DllCall("CloseHandle", "ptr", hRead1)
DllCall("GetExitCodeProcess", "ptr", hChild, "int *", ExitCode)
DllCall("CloseHandle", "ptr", hChild)
Return ExitCode
}