Propongo otra versión, DosCommand:
function DosCommand(CommandLine: String): String; var Buffer: array [0..4096] of char; pipeRead, pipeWrite: THandle; sa: SECURITY_ATTRIBUTES; si: STARTUPINFO; pi: PROCESS_INFORMATION; dwRead: DWORD; begin Result:= ''; GetEnvironmentVariable('COMSPEC', Buffer, sizeof(Buffer)); CommandLine:= String(Buffer) + ' /C ' + CommandLine; ZeroMemory(@sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength:= sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle:= TRUE; if CreatePipe(pipeRead, pipeWrite, @sa, 25*1024) then begin si.cb:= sizeof(STARTUPINFO); ZeroMemory(@pi, sizeof(PROCESS_INFORMATION)); si.hStdOutput:= pipeWrite; si.hStdError := pipeWrite; si.hStdInput := pipeWrite; si.dwFlags:= STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; si.wShowWindow:= SW_HIDE; if CreateProcess(nil, PCHAR(CommandLine), nil, nil, TRUE, 0, nil, nil, si, pi) then begin CloseHandle(pi.hThread); if WaitForSingleObject(pi.hProcess, 9000) = WAIT_OBJECT_0 then begin dwRead:= 0; Buffer[0]:= ' '; WriteFile(pipeWrite, Buffer, 1, dwRead, 0); repeat ZeroMemory(@buffer, sizeof(buffer)); ReadFile(pipeRead, buffer, sizeof(buffer), dwRead, 0); OemToCharBuffA(buffer, buffer, dwRead); Result:= Result + #13 + #10 + String(buffer); until dwRead < sizeof(buffer); end; CloseHandle(pi.hProcess); end; CloseHandle(pipeRead); CloseHandle(pipeWrite); end; end;
Un ejemplo de uso:
Memo1.Text:= DosCommand(Edit1.Text);
Saludos.
PD.
Modifico el código:
// cambio WriteFile(pipeWrite, '', 1, dwRead, 0); // por Buffer[0]:= ' '; //un espacio. WriteFile(pipeWrite, Buffer, 1, dwRead, 0);
Para evitar problemas con programas que no devuelvan nada a la consola.