Autor Beitrag
jackie05
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 357



BeitragVerfasst: So 22.02.09 17:26 
Hallo,
ich habe in meinem Projekt eine Update funktion geschrieben, wenn ich jetzt Updates Herunterladen klicke, klappt alles wunderbar und wenn das Update heruntergeladen ist, wird mein Delphi Projekt geschlossen und update.bat aufgerufen indem folgendes drin steht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
@echo off
echo Update...
mkdir "C:\Program Files (x86)\Firmenname\Projekt\"
@if exist "C:\Program Files (x86)\Firmenname\Projekt\Projekt.exe" del "C:\Program Files (x86)\Firmenname\Projekt\Projekt.exe" /F
@copy "C:\Temp\Projekt.exe" "C:\Program Files (x86)\Firmenname\Projekt\Projekt.exe"
@if exist C:\Temp\"Projekt.exe" del C:\Temp\"Projekt.exe" /F
cd C:\Program Files (x86)\Firmenname\Projekt\
start Projekt.exe


wenn das abgeschlossen ist, wird aber meine .exe datei nicht überschrieben, die alte Projekt.exe Datei ist immer noch vorhanden.

Wisst ihr vieleicht was ich da falsch gemacht habe?

MfG
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 22.02.09 17:31 
Du musst die Batchdatei auch mit Administratorrechten starten, sonst kannst du unter c:\program files ja nix schreiben.
jackie05 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 357



BeitragVerfasst: So 22.02.09 17:38 
Danke Dir.
Aber wie soll ich die Btachdatei mit Administratorrechte starten?

MfG
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 22.02.09 17:56 
Du kannst sagen, dass ein Prozess diese Rechte braucht, wenn du ihn startest. Das Stichwort hier ist Process Elevation, dafür gibts z.B. von Luckie etwas, auch die entsprechenden Teile der JWSCL sind dafür interessant.

Aber ich glaube das einfachste wäre ein zusätzliches kleines Updaterprogramm inkl. Manifest, das Administratorrechte anfordert. Das kann ja ohne Formular und damit sehr klein sein.
jackie05 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 357



BeitragVerfasst: So 22.02.09 19:23 
Danke.

Ich habe mir das anders überlegt, indem ich in Delphi ein Update Projekt zuammen baue und mit dem Projekt die Dateien dann kopiere.
Ich habe über google.de diese Seite gefunden:
www.planet-source.de/tipps/7/107.php

Jetzt habe ich das mal versucht bei mir einzubauen:
ausblenden volle Höhe Delphi-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:
60:
61:
62:
63:
64:
65:
66:
function CopyFile(ASourceFilePath, ADestFilePath : string; AAllowOverride : boolean = True; ACallBack : TNotifyEvent = nil) : boolean;
var
  ABuffer : array [0..4095] of Byte;
  ABytesRead : int64;
  ADestFileStream : TFileStream;
  ASourceFileSize : int64;
  ASourceFileStream : TFileStream;
begin
  Result := False;
  if (ASourceFilePath = '') or (ADestFilePath = '') then
    Exit;

  if FileExists(ASourceFilePath) and (ExtractFileName(ADestFilePath) <> '') then
  begin
    //Falls DestFile existiert löschen
    if AAllowOverride and FileExists(ADestFilePath) then
    begin
      //eigene Dateilöschroutine oder
      //SysUtils.DeleteFile(ADestFilePath);
    end;
 
    ForceDirectories(ExtractFilePath(ADestFilePath));
 
    ASourceFileStream := TFileStream.Create(ASourceFilePath, fmOpenRead);
    ADestFileStream := TFileStream.Create(ADestFilePath, fmCreate);
    try
      ASourceFileSize := ASourceFileStream.Size;
      ABytesRead := 0;
      repeat
        ABytesRead := ASourceFileStream.Read(ABuffer, SizeOf(ABuffer));
        if ABytesRead <> 0 then
        begin
          ADestFileStream.Write(ABuffer, SizeOf(ABuffer));

          //CallBack
          if Assigned(ACallBack) then
          begin
            //Dem Callback gebt ihr ein Object mit
            //das ihr Selber erstellt habt worin
            //z.B. die Aktuellgeschriebene Bytezahl drin gespeichert ist
            ACallBack(AFileProgress);
          end; //End assigned
        end
      until ABytesRead = 0;

      Result := (ASourceFileStream.Size = ADestFileStream.Size);
    finally
      FreeAndNil(ASourceFileStream);
      FreeAndNil(ADestFileStream);
    end;
  end;
end;

procedure MyCallBack(Sender : TObject);
begin
  if Sender is MyProgressObject then
  begin
    Form1.ProgressBar1.Max := MyProgressObject.FileSize; //maximum der Bar setzten
    //usw.
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CopyFile('C:\Quell.txt','D:\Ziel.txt',true,MyCallBack);
end;


Ich weiss jetzt nicht wie ich ein Object erzeugen muss:
"Nun wird die Datei kopiert. Und immer wenn 4095 Byte kopiert wurden wird die Routine MyCallback aufgerufen, die das von Ihnen erstelle Objekt als Sender bekommt. Und dann können Sie dort die Progressbar aktualisieren oder sonstiges."

Kann mir da vieleicht jemand weiterhelfen?

MfG
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 22.02.09 19:37 
Dass es auch eine eingebaute Funktion dafür gibt, weißt du aber? Da fehlt nur der Fortschrittsbalken.
www.swissdelphicente.../showcode.php?id=101
Für kleine Projekte wird der aber auch nicht nötig sein. ;-)
jackie05 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 357



BeitragVerfasst: So 22.02.09 19:43 
Vielen Dank für die schnelle antwort.

Ich brauch eine Kopierfunktion mit Fortschrittanzeige und ich habe auf meiner Form eine ProgressBar erzeugt.
Irgendwiewill das nicht so ganz funktionieren.

MfG
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 22.02.09 20:15 
user profile iconjackie05 hat folgendes geschrieben Zum zitierten Posting springen:
Ich brauch eine Kopierfunktion mit Fortschrittanzeige
Was hast du denn für große Dateien, dass sich das lohnt? Aber das musst du ja wissen. ;-)

Möglich wäre das auch mit SHFileOperation, dann käme die Fortschrittsanzeige wie beim Windows Explorer:
www.delphipraxis.net/topic1451.html
www.delphipraxis.net/topic50381.html

user profile iconjackie05 hat folgendes geschrieben Zum zitierten Posting springen:
Irgendwiewill das nicht so ganz funktionieren.
Äußerst präzise Angabe. ;-)

In dem Quelltext oben sind jedenfalls Fehler drin, da entsteht Datenmüll am Ende und kompilierbar ists so auch nicht...
So sollte es funktionieren, TMyProgressObject kannst du natürlich anpassen wie du willst.
ausblenden volle Höhe Delphi-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:
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:
type
  TMyProgressObject = class
  public
    FileSize, CurrentPosition: Int64;
    function GetCurrentProgress: Byte;
  end;

  TForm1 = class(TForm)
  private
    procedure MyCallBack(Sender: TObject);

...

function TMyProgressObject.GetCurrentProgress: Byte;
begin
  Result := CurrentPosition * 100 div FileSize;
end;

function CopyFile(ASourceFilePath, ADestFilePath : string; AAllowOverride : boolean = True; ACallBack : TNotifyEvent = nil) : boolean;
var
  ABuffer : array [0..4095] of Byte;
  ABytesRead : int64;
  ADestFileStream : TFileStream;
  ASourceFileSize : int64;
  ASourceFileStream : TFileStream;
  AFileProgress: TMyProgressObject;
begin
  Result := False;
  if (ASourceFilePath = '') or (ADestFilePath = '') then
    Exit;

  if FileExists(ASourceFilePath) and (ExtractFileName(ADestFilePath) <> '') then
  begin
    //Falls DestFile existiert löschen
    if AAllowOverride and FileExists(ADestFilePath) then
    begin
      //eigene Dateilöschroutine oder
      //SysUtils.DeleteFile(ADestFilePath);
    end;
 
    ForceDirectories(ExtractFilePath(ADestFilePath));

    AFileProgress := TMyProgressObject.Create;
    ASourceFileStream := TFileStream.Create(ASourceFilePath, fmOpenRead);
    ADestFileStream := TFileStream.Create(ADestFilePath, fmCreate);
    try
      ASourceFileSize := ASourceFileStream.Size;
      AFileProgress.FileSize := ASourceFileSize;
      repeat
        ABytesRead := ASourceFileStream.Read(ABuffer, SizeOf(ABuffer));
        if ABytesRead <> 0 then
        begin
          ADestFileStream.Write(ABuffer, ABytesRead);

          //CallBack
          if Assigned(ACallBack) then
          begin
            //Dem Callback gebt ihr ein Object mit
            //das ihr Selber erstellt habt worin
            //z.B. die Aktuellgeschriebene Bytezahl drin gespeichert ist
            AFileProgress.CurrentPosition := ADestFileStream.Position;
            ACallBack(AFileProgress);
          end; //End assigned
        end
      until ABytesRead = 0;

      Result := (ASourceFileStream.Size = ADestFileStream.Size);
    finally
      FreeAndNil(ASourceFileStream);
      FreeAndNil(ADestFileStream);
    end;
  end;
end;

procedure TForm1.MyCallBack(Sender : TObject);
begin
  if Sender is TMyProgressObject then
    Form1.ProgressBar1.Position := TMyProgressObject(Sender).GetCurrentProgress;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CopyFile('C:\Quell.txt','D:\Ziel.txt',true,MyCallBack);
end;
jackie05 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 357



BeitragVerfasst: So 22.02.09 22:59 
Du hast recht, ist wirklich sinnlos.
Ich habe jetzt eine Update Projekt fertig und wenn ich diese ausführe und in dem gleichen Pfad eine andere .exe Datei herunterladen möchte vom Server, dann bekomme ich folgende Fehlermeldung:
Datei "C:\Program Files (x86)\Projekt\Projekt.exe" kann nicht erstellt werden. Zugriff verweigert.

Gibt es eine möglichkeit dies zu umgehen in Delphi?

MfG
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 22.02.09 23:12 
Das braucht Administratorrechte für diesen Ordner, d.h. du solltest dem Updater am besten ein Manifest verpassen, der dem System sagt, dass der Adminrechte braucht.
www.vb-magazin.de/fo...2006/10/28/6330.aspx
jackie05 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 357



BeitragVerfasst: Mo 23.02.09 00:06 
Vielen Dank, Du hast mir sehr weitergeholfen.

MfG