Thema: Delphi Readfile bleibt hängen

Einzelnen Beitrag anzeigen

Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#4

AW: Readfile bleibt hängen

  Alt 11. Mai 2011, 18:12
Ist jetzt kein Post im Sinne von 'hey, hier ist dein Fehler!', aber vielleicht hilft meine Funktion (keine Gewähr auf 100% Premium-Code!) etwas weiter? Ich könnte mir vorstellen, dass ReadFile() erst zurückkehrt, wenn auch deine 255 Bytes gelesen wurden, was vielleicht nicht immer der Fall ist. Das müsste aber im MSDN stehen.

Delphi-Quellcode:
function RunProcess(Filename, WorkingDir: string; Timeout: Integer; var Output: AnsiString): Integer; overload;
var
  OK: Boolean;
  Handle: Cardinal;
  SI: TStartupInfo;
  PI: TProcessInformation;
  SA: TSecurityAttributes;
  SD: TSecurityDescriptor;

  ReadPipeOut, WritePipeOut: THandle;
  ReadPipeIn, WritePipeIn: THandle;
  ReadCount: DWORD;
  Avail: DWORD;
  Tmp: AnsiString;
  Started: Cardinal;
begin
  Result := 1;
  Output := '';
  if Filename = 'then
    Exit;

  if not InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION) then
    Exit;
  if not SetSecurityDescriptorDacl(@SD, True, nil, False) then
    Exit;
  SA.lpSecurityDescriptor := @SD;

  SA.nLength := SizeOf(TSecurityAttributes);
  SA.bInheritHandle := True;

  if not CreatePipe(ReadPipeOut, WritePipeOut, @SA, 0) then
    Exit;

  if not CreatePipe(ReadPipeIn, WritePipeIn, @SA, 0) then
  begin
    CloseHandle(ReadPipeOut);
    CloseHandle(WritePipeOut);
    Exit;
  end;

  FillChar(SI, SizeOf(TStartupInfo), #0);
  FillChar(PI, SizeOf(TProcessInformation), #0);
  SI.cb := SizeOf(TStartupInfo);
  SI.dwFlags := STARTF_FORCEOFFFEEDBACK or STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
  SI.wShowWindow := SW_HIDE;
  SI.hStdOutput := WritePipeOut;
  SI.hStdError := WritePipeOut;
  SI.hStdInput := ReadPipeIn;
  OK := CreateProcess(nil, @Filename[1], nil, nil, True,
    CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS or CREATE_NO_WINDOW,
    nil, @WorkingDir[1], SI, PI);
  try
    if OK then
    begin
      Handle := PI.hProcess;

      Result := 0;

      Started := GetTickCount;
      while WaitForSingleObject(Handle, 100) = WAIT_TIMEOUT do
      begin
        PeekNamedPipe(ReadPipeOut, nil, 0, nil, @Avail, nil);
        if Avail > 0 then
        begin
          SetLength(Tmp, Avail);
          ReadFile(ReadPipeOut, Tmp[1], Avail, ReadCount, nil);
          Output := Output + Tmp;

          Started := GetTickCount;
        end;

        if Started + Timeout < GetTickCount then
        begin
          Result := 2; // Timeout!
          Exit;
        end;
      end;

      // Prozess ist zuende, noch den Rest holen. kA ob das muss..
      PeekNamedPipe(ReadPipeOut, nil, 0, nil, @Avail, nil);
      if Avail > 0 then
      begin
        SetLength(Tmp, Avail);
        ReadFile(ReadPipeOut, Tmp[1], Avail, ReadCount, nil);
        Output := Output + Tmp;
      end;
    end;
  finally
    CloseHandle(PI.hThread);
    CloseHandle(PI.hProcess);
    CloseHandle(ReadPipeOut);
    CloseHandle(WritePipeOut);
    CloseHandle(ReadPipeIn);
    CloseHandle(WritePipeIn);
  end;
end;
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat