Autor |
Beitrag |
Blamaster
      
Beiträge: 164
|
Verfasst: Di 04.09.07 15:50
Hi,
mein Programm hängt sich während es entpackt erstmal total auf, nach dem entpacken läuft es wieder ohne Probleme. Wie kann ich das umgehen ?
Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106:
| procedure TForm1.Button2Click(Sender: TObject);
function ExecConsole(var Output, Errors: String): Boolean; var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; SecurityAttr: TSecurityAttributes; PipeOutputRead, PipeOutputWrite, PipeErrorsRead, PipeErrorsWrite: THandle;
function ReadPipeToString(const hPipe: THandle): String; const MEM_CHUNK_SIZE = 8192; var NumberOfBytesRead, NumberOfBytesTotal: Cardinal; begin Result := ''; NumberOfBytesTotal := 0; repeat SetLength(Result,Length(Result) +MEM_CHUNK_SIZE); if ReadFile(hPipe,(@Result[1+NumberOfBytesTotal])^,MEM_CHUNK_SIZE, NumberOfBytesRead,NIL) then Inc(NumberOfBytesTotal,NumberOfBytesRead); SetLength(Result,NumberOfBytesTotal); until (NumberOfBytesRead = 0); end;
begin FillChar(ProcessInfo,SizeOf(TProcessInformation),0); FillChar(SecurityAttr,SizeOf(TSecurityAttributes),0); SecurityAttr.nLength := SizeOf(SecurityAttr); SecurityAttr.bInheritHandle := TRUE; SecurityAttr.lpSecurityDescriptor := NIL; CreatePipe(PipeOutputRead,PipeOutputWrite,@SecurityAttr,0); CreatePipe(PipeErrorsRead,PipeErrorsWrite,@SecurityAttr,0); FillChar(StartupInfo,SizeOf(TStartupInfo),0); StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.hStdInput := 0; StartupInfo.hStdOutput := PipeOutputWrite; StartupInfo.hStdError := PipeErrorsWrite; StartupInfo.wShowWindow := SW_HIDE; StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; Result := CreateProcess(NIL,PChar(winrar+'rar.exe e -p'+(Pwid)+ ' ' +(Archivid)+ ' ' +(Archiv2)),NIL,NIL,TRUE, CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, NIL,NIL,StartupInfo,ProcessInfo);
CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsWrite); if (Result) then begin Output := ReadPipeToString(PipeOutputRead); Errors := ReadPipeToString(PipeErrorsRead); WaitForSingleObject(ProcessInfo.hProcess,INFINITE); CloseHandle(ProcessInfo.hProcess); end; CloseHandle(PipeOutputRead); CloseHandle(PipeErrorsRead); end;
begin try ini:=TIniFile.create(ExtractFilePath(ParamStr(0))+'einstellungen.ini'); Pwcheck:= ini.ReadInteger('Optionen','Id',-1); finally ini.free; end; try if ExecConsole(Output,Errors) then begin if (Errors <> '') then begin Pwid:=(Listbox1.Items[Pwcheck + 1]); Archivid:=(Listbox2.Items[0]);
Filename:=ExtractFileName(Archivid); Filename2:=ExtractFileExt(Filename); Fund:=Pos(Filename2,Filename); if Fund <> -1 then begin FileNameNew:=Copy(Filename,0,Fund-1); end; if Archiv = False then Archiv2:='' else Archiv2:=(Archivpfad)+(Filenamenew) +'\'; try ini:=TIniFile.create(ExtractFilePath(ParamStr(0))+'einstellungen.ini'); ini.WriteInteger('Optionen','Id',Pwcheck + 1); finally ini.free; end; end; Button2.Click; end
else
finally
end; end; |
|
|
noidic
      
Beiträge: 851
Win 2000 Win XP Vista
D7 Ent, SharpDevelop 2.2
|
Verfasst: Di 04.09.07 15:54
Das WaitforSingleObject blockiert das Programm, pack das entpacken in nen eigenen Thread.
_________________ Bravery calls my name in the sound of the wind in the night...
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 04.09.07 16:10
Kannst Du den Zeilen 68ff bitte mal etwas Layout verpassen?
Ferner: Ein leerer Finally-Teil hat wenig Sinn.
Genauso ein leere Else-Zweig.
Ansonsten: Anstatt bei WaitForSignleObject als Timeout Infinite anzugeben, nimmste nen Wert von ~200ms und prüfst in ner While-Schleife, ob das Timeout erreicht wurde, oder er ne Rückmeldung bekommen hat. Als Schleifen-Köprper kommt dann ein Application.ProcessMessages;.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Blamaster 
      
Beiträge: 164
|
Verfasst: Di 04.09.07 16:54
Kannst du das nochmal genauer erklären versteh ich irgendwie nicht so ganz 
|
|
Blamaster 
      
Beiträge: 164
|
Verfasst: Di 04.09.07 20:29
Bzw diesen Teil kann ich mir nicht ganz vorstellen:
"Prüfe in ner While-Schleife, ob das Timeout erreicht wurde, oder er ne Rückmeldung bekommen hat. Als Schleifen-Köprper kommt dann ein Application.ProcessMessages;."
Wie genau prüfe ich ob das Timeout erreicht wurde ?
Und was passiert mit Application.ProcessMessages ?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 04.09.07 21:20
Für Zeile 60 siehe WAITFORSINGLEOBJECT und ändere diese Zeile entsprechend. Manchmal sind Rückgabewerte dazu da, um diese abzufragen Aber auch nur manchmal...
Und das ganze dann in eine While Condition_For_WaitForSingleObject Do Application.ProcessMessages; zu packen, solltest Du selber hinbekommen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Blamaster 
      
Beiträge: 164
|
Verfasst: Di 04.09.07 22:48
Habe das Problem jetzt dank BenBE gelöst:
While WaitForSingleObject(ProcessInfo.hProcess,50) = WAIT_TIMEOUT do Application.ProcessMessages;
mfg Bla
|
|
|