Новый участник
Сообщения: 28
Благодарности: 9
|
Профиль
|
Отправить PM
| Цитировать
Пытаюсь прикрутить к Inno чтение с консоли, причем нужна реализация через пайпы и чтобы текст построчно отображался в Memo.
Пытаюсь адаптировать следующий пример, 3-ий на странице (RunDosInMemo):
http://decoding.dax.ru/faq/vcl/console/console001.html
Вроде почти перевел, но осталась заморочка именно с чтением через ReadFile и вывод, соответственно в Memo, да, там должны передаваться символы и строки, у меня счас там цифры, содрал с одного примера, но подружить с текстом не удается.
Просьба продвинутых поправить пример, если это возможно.
Скрипт (для версии Unicode)
Код: 
[Setup]
AppName=MyApp
Appvername=MyApp
DefaultDirname={pf}\MyApp
[_Code]
const
ReadBuffer = 2400;
STARTF_USESTDHANDLES = $100;
STARTF_USESHOWWINDOW = 1;
NORMAL_PRIORITY_CLASS = $00000020;
HEAP_ZERO_MEMORY = $0008;
WAIT_TIMEOUT = $00000102;
type
TMyMsg = record hWnd: HWND; msg, wParam: Word; lParam: LongWord; Time: TFileTime; pt: TPoint; end;
type
TSecurityAttributes = record
nLength: DWord;
lpSecurityDescriptor: longint;
bInheritHandle: Boolean;
end;
TProcessInformation = record
hProcess:DWORD;
hThread:DWORD;
dwProcessId:DWORD;
dwThreadId:DWORD;
end;
TStartupInfo = record
cb:DWORD;
lpReserved:DWORD; // not PChar; - need NULL pointer
lpDesktop:DWORD; // not PChar; - need NULL pointer
lpTitle:DWORD; // not PChar; - need NULL pointer
dwX:DWORD;
dwY:DWORD;
dwXSize:DWORD;
dwYSize:DWORD;
dwXCountChars:DWORD;
dwYCountChars:DWORD;
dwFillAttribute:DWORD;
dwFlags:DWORD;
wShowWindow:WORD;
cbReserved2:WORD;
lpReserved2:DWORD;
hStdInput:DWORD;
hStdOutput:DWORD;
hStdError:DWORD;
end;
// ----------------------------------------------------------- //
function PeekMessage(var lpMsg: TMyMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL;
external 'PeekMessageW@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMyMsg): BOOL;
external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMyMsg): Longint;
external 'DispatchMessageW@user32.dll stdcall';
// ----------------------------------------------------------- //
function CloseHandle(hObject: THandle): BOOLEAN;
external 'CloseHandle@kernel32.dll stdcall';
function CreateProcess(lpApplicationName: String; lpCommandLine: string; lpProcAttrib,lpThreadAttrib: TSecurityAttributes; bInheritHandles: Boolean; dwCreationFlags: DWORD; lpEnvironment:DWORD; lpCurrentDirectory: String; var lpStartupInfo:TStartupInfo; var lpProcessInfo:TProcessInformation): Boolean;
external 'CreateProcessW@kernel32.dll stdcall';
function CreatePipe(out hReadPipe,hWritePipe: THandle; lpPipeAttributes: TSecurityAttributes; nSize: dword): BOOLEAN;
external 'CreatePipe@kernel32.dll stdcall';
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD;
external 'WaitForSingleObject@kernel32.dll stdcall';
function ReadFile(hFile: THandle; lpBuffer: Longint; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: Longint): BOOL;
external 'ReadFile@kernel32.dll stdcall';
function GetProcessHeap: THandle;
external 'GetProcessHeap@kernel32.dll stdcall';
function HeapAlloc(hHeap: THandle; dwFlags, dwBytes: DWORD): Longint;
external 'HeapAlloc@kernel32.dll stdcall';
function HeapSize(hHeap: THandle; dwFlags: DWORD; lpMem: Longint): DWORD;
external 'HeapSize@kernel32.dll stdcall';
function HeapFree(hHeap: THandle; dwFlags: DWORD; lpMem: Longint): BOOL;
external 'HeapFree@kernel32.dll stdcall';
Function OemToChar(lpszSrc, lpszDst: AnsiString): longint;
external 'OemToCharA@user32.dll stdcall';
procedure AppProcessMessage;
var
Msg: TMyMsg;
begin
while PeekMessage(Msg, 0, 0, 0, 1) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
function OemToAnsiStr(strSource: AnsiString): AnsiString;
var
nRet: longint;
begin
SetLength(Result, Length(strSource));
nRet:= OemToChar(strSource, Result);
end;
procedure InitializeWizard;
var
MyMemo: TMemo;
Security: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
Start: TStartUpInfo;
ProcessInfo: TProcessInformation;
Buffer: PAnsiChar;
BytesRead: DWord;
Apprunning: DWord;
appName, commandLine,workingDirectory: string;
hFile, hHeap: THandle;
lpBuffer: Longint;
dwBufferSize, dwRead: DWORD;
begin
WizardForm.InnerNoteBook.Hide;
WizardForm.OuterNotebook.Hide;
MyMemo:=TMemo.Create(WizardForm);
MyMemo.SetBounds(30, 30, 440, 260);
MyMemo.Parent:=WizardForm;
MyMemo.Text:='Hello!';
{
with Security do
begin
nlength := SizeOf(Security);
binherithandle := true;
lpsecuritydescriptor := 0;
end;
}
Security.nlength := SizeOf( Security );
Security.binherithandle := true;
Security.lpSecurityDescriptor := 0;
if Createpipe( ReadPipe, WritePipe, Security, 0 ) then
begin
hHeap := GetProcessHeap;
lpBuffer := HeapAlloc(hHeap, HEAP_ZERO_MEMORY, ReadBuffer);
dwBufferSize := HeapSize(hHeap, 0, lpBuffer);
//Buffer := AllocMem( ReadBuffer+1 );
//FillChar( Start, Sizeof( Start ), #0 );
Start.cb := SizeOf( Start );
Start.hStdOutput := WritePipe;
Start.hStdInput := ReadPipe;
Start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
Start.wShowWindow := SW_HIDE;
if CreateProcess('c:\windows\System32\PING.EXE', ' ' + 'ya.ru', Security, Security, True, NORMAL_PRIORITY_CLASS, 0, 'c:\windows\System32', Start, ProcessInfo) then
begin
repeat
Apprunning := WaitForSingleObject( ProcessInfo.hProcess, 100 );
ReadFile(ReadPipe, lpBuffer, dwBufferSize, dwRead, 0);
//ReadFile( ReadPipe, lpBuffer[0], ReadBuffer, BytesRead, nil );
//lpBuffer[BytesRead] := #0;
MyMemo.Text := MyMemo.text + OemToAnsiStr(lpBuffer);
AppProcessMessage;
until ( Apprunning <> WAIT_TIMEOUT );
// until ( BytesRead < ReadBuffer );
end;
HeapFree(hHeap, 0, lpBuffer);
CloseHandle( ProcessInfo.hProcess );
CloseHandle( ProcessInfo.hThread );
CloseHandle( ReadPipe );
CloseHandle( WritePipe );
end;
end;
|