Autor |
Beitrag |
Maggi
      
Beiträge: 160
WIN XP, WIN 2003
D5 Enter D 2006
|
Verfasst: Di 01.10.02 15:27
Tach zusammen,
ich habe da so meine Probleme mit der Shellexecute....
Ich bin dabei ein Updateprogramm für ein bestehendes Projekt zu schreiben, soweit kein Problem. Nun bin ich aber an einer Stelle angekommen wo ich nicht mehr weiter weiß??
Also zur Lage, mein Projekt schaut nach ob auf dem Server eine neuere Version vorliegt, wenn dies so ist beendet es sich und startet mit Shellex. ein kleines Kopierprogramm. Dieses Kopierprogramm schaut nun nach ob der Handel des Projektes schon weg terminiert ist (damit man die Datei überschreiben kann), und kopiert die neue Version vom Netz in das Arbeitsverzeichnis.
Das heißt, es sollte es tun, ich bekomme aber an der Stelle eine Exception das man es noch nicht kopieren kann da es noch im gebrauch ist. Dabei habe ich es mit Application.Terminate eigentlich korrekt beendet.
Kann es sein das das Shellexecute da einfach zu schnell ist? Kann man da eine art waitfor einbauen, oder hat jemand eine komplett bessere Idee und mein Ansatz ist "dumm"???
Ich bin am verzweifeln und würde mich über Hilfe freuen
Maggi
|
|
OregonGhost
      
Beiträge: 215
|
Verfasst: Di 01.10.02 16:49
Du kannst mit WaitForSingleObject() auf ein Objekt warten. Das kann zum Beispiel ein Prozess sein, dann musst du den Prozesshandle angeben. Den kannst du zum Beispiel bekommen, indem du dein kleines Programm mit CreateProcess() startest, was soweit ich weiß ohnehin der von Microsoft vorgesehen Weg ist, ein Programm zu starten. Schau dir ein wenig Informationen über diese Funktion an. Das wichtige, was du wissen musst, ist, dass der letzte Parameter vom Typ LPPROCESS_INFORMATION ist (in Delphi vielleicht PProcessInformation?). Der hat ein Member namens hProcess, und das ist der besagte Prozess-Handle, auf den du mit WaitForSingleObject() warten kannst. Alles klar? ;c)
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Popov
Gast
Erhaltene Danke: 1
|
Verfasst: Di 01.10.02 17:16
Zuerst ein mal ein grundsätzlicher Tip: downloade nie ein Programm in ein bestimmtes Verzeichnis. Aus Erfahrung weiss ich, daß es besser ist die Datei in das Temp-Verzeichnis unter ein Temp-Namen zwischenzuspeichern. Erst wenn dieser Vorgang angeschlossen ist sollte man die Datei an den entgültigen Platz verschieben.
Das ist zwar nicht die Antwort auf deine Frage, aber es ist etwas leichet mit einer Kopier-Funktion umzugehen als mit einer Downloadroutine. Zumindest hast du eine Zeitverzögerung und kannst paar Sekunden warten.
|
|
Maggi 
      
Beiträge: 160
WIN XP, WIN 2003
D5 Enter D 2006
|
Verfasst: Mi 02.10.02 08:13
Danke OregonGhost,
alles klar war nach deiner Antwort noch nicht, sie hat mir aber über den Berg geholfen....
Funktionieren tut es jetzt wobei ich immer noch nicht von der Art überzuegt bin wie ich die Sache Handel. Es gibt bestimmt noch einen komplett eleganteren Weg!?!?
Trotzdem besten Dank nochmal
Tschöö
Maggi
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 02.10.02 11:35
Popov hat folgendes geschrieben: | Zuerst ein mal ein grundsätzlicher Tip: downloade nie ein Programm in ein bestimmtes Verzeichnis. Aus Erfahrung weiss ich, daß es besser ist die Datei in das Temp-Verzeichnis unter ein Temp-Namen zwischenzuspeichern. |
Man kann die Datei auch mit einem temporären Namen im Anwendungsordner speichern lassen. Mit GetTempFileName lassen sich einzigartige Dateinamen erzeugen, so dass man sich bei mehreren Aktualisierungen nicht in die Quere kommt.
Ist die gewünschte Datei noch in Benutzung, lässt sich das System (Stichwort: "wininit.ini") dazu benutzen, beim nächsten Neustart die Dateien automatisch umzubenennen.
|
|
OregonGhost
      
Beiträge: 215
|
Verfasst: Sa 05.10.02 17:54
Zitat: | Funktionieren tut es jetzt wobei ich immer noch nicht von der Art überzuegt bin wie ich die Sache Handel. Es gibt bestimmt noch einen komplett eleganteren Weg!?!? |
Ich glaube nicht, dass einen eleganteren Weg gibt, auf ein Programm zu warten als mit WaitForSingleObject. Das funktioniert nämlich z.B. auch, wenn das Zielprogramm abgestürzt ist. Oder gibt es dir unelegant vor, das Programm mit dem doch recht umfangreichen CreateProcess() starten zu müssen? Das ist aber sogar der empfohlene Weg.
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 05.10.02 21:36
Von den JEDIs gibt es schon seit geraumer Zeit eine passende Funktion, die den Aufruf von "CreateProcess" kapselt und solange wartet, bis das aufgerufene Programm beendet wurde.
Und in der Delphi-PRAXiS gibt es einen entsprechenden Beitrag von Luckie und jbg.
|
|
JeanvanHees
      
Beiträge: 146
win 2000
D6 Pers
|
Verfasst: Mo 07.10.02 09:32
Naja, hab hier auch noch ne shellexecute procedure mit wait.
Ich hab nur die link nicht mehr wo ich sie her hab. Also:
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:
| //////////////////////////////////////////////////////////////// // AppName: name (including path) of the application // AppArgs: command line arguments // Wait: 0 = don't wait on application // >0 = wait until application has finished (maximum in milliseconds) // <0 = wait until application has started (maximum in milliseconds) // Hide: True = application runs invisible in the background // ExitCode: exitcode of the application (only avaiable if Wait <> 0) // function STO_ShellExecute(const AppName, AppArgs: String; const Wait: Integer; const Hide: Boolean; var ExitCode: DWORD): Boolean; var myStartupInfo: TStartupInfo; myProcessInfo: TProcessInformation; sAppName: String; iWaitRes: Integer; begin // initialize the startupinfo FillChar(myStartupInfo, SizeOf(TStartupInfo), 0); myStartupInfo.cb := Sizeof(TStartupInfo); myStartupInfo.dwFlags := STARTF_USESHOWWINDOW; if Hide then // hide application myStartupInfo.wShowWindow := SW_HIDE else // show application myStartupInfo.wShowWindow := SW_SHOWNORMAL;
// prepare applicationname sAppName := AppName; if (Length(sAppName) > 0) and (sAppName[1] <> '"') then sAppName := '"' + sAppName + '"';
// start process ExitCode := 0; Result := CreateProcess(nil, PChar(sAppName + ' ' + AppArgs), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(AppName)), myStartupInfo, myProcessInfo);
// could process be started ? if Result then begin // wait on process ? if (Wait <> 0) then begin if (Wait > 0) then // wait until process terminates iWaitRes := WaitForSingleObject(myProcessInfo.hProcess, Wait) else // wait until process has been started iWaitRes := WaitForInputIdle(myProcessInfo.hProcess, Abs(Wait)); // timeout reached ? if iWaitRes = WAIT_TIMEOUT then begin Result := False; TerminateProcess(myProcessInfo.hProcess, 1); end; // getexitcode GetExitCodeProcess(myProcessInfo.hProcess, ExitCode); end; CloseHandle(myProcessInfo.hProcess); end; end; |
Vielleicht einen overkill? Naja...
Tschüß, 
_________________ Cause even though I know things won't get any better, they can certainly never get much worse!
|
|
|