Autor Beitrag
Maggi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 160

WIN XP, WIN 2003
D5 Enter D 2006
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 160

WIN XP, WIN 2003
D5 Enter D 2006
BeitragVerfasst: 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



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 146

win 2000
D6 Pers
BeitragVerfasst: 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:

ausblenden volle Höhe Quelltext
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üß, :wink2:

_________________
Cause even though I know things won't get any better, they can certainly never get much worse!