AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi [gelöst] Henne Ei Problem - eigene EXE löschen

[gelöst] Henne Ei Problem - eigene EXE löschen

Ein Thema von moelski · begonnen am 2. Jun 2009 · letzter Beitrag vom 4. Jun 2009
Antwort Antwort
Seite 3 von 4     123 4   
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#21

Re: Henne Ei Problem - eigene EXE löschen

  Alt 2. Jun 2009, 18:24
Moin !

hat das mit dem MoveFileEx() denn irgendwelche Nachteile Ja, funktioniert nicht unter 98.
Aber 98 brauchen wir (leider) noch.

Zitat:
das Grauen...
Os schon richtig, aber das Thema ist auch leider nicht so trivial

Zitat:
auf keinen Fall den Programm-Ordner einfach so löschen
Nuja ... Wenn User im Programmordner Dateien ablegen, dann sollte man nur noch das Beileid aussprechen
Aber ich gebe dir Recht. So eine Überprüfung könnte noch Sinn machen. Aber nicht bevor ich dieses Problem im Griff habe ..
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#22

Re: Henne Ei Problem - eigene EXE löschen

  Alt 2. Jun 2009, 18:31
Zitat von moelski:
Wenn User im Programmordner Dateien ablegen, dann sollte man nur noch das Beileid aussprechen
Du verwendest Delphi7 und siehst ja daran, was früher gängige Praxis war. Aber sehe auch, das aktuelle Uninstaller nichts löschen, was deren Installationsprogramm nicht selber reinkopiert hat.

Man bekommt dann immer die nette Meldung "Es konnte nicht alles gelöscht werden", womit der Ordner gemeint war, der nicht leer geworden ist.
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

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

Re: Henne Ei Problem - eigene EXE löschen

  Alt 2. Jun 2009, 19:37
Alles klar, das mit Win98 ist ein Argument. Bin ich froh, damit nichts mehr am Hut haben zu müssen.


Und weil Win98 eh lumpig ist, kann man dann auch den Uninstaller einfach im Temp-Ordner rumliegen lassen..
http://streamwriter.org

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

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#24

Re: Henne Ei Problem - eigene EXE löschen

  Alt 2. Jun 2009, 20:04
Hallo,

der Link unten zeigt c++-Quellcode zum Löschen der eigenen Exe.
Inwiefern das auch unter Win98 schon geht, weiss ich nicht.

DeleteMe.cpp

Heiko
Heiko
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#25

Re: Henne Ei Problem - eigene EXE löschen

  Alt 3. Jun 2009, 02:22
Zitat von hoika:
der Link unten zeigt c++-Quellcode zum Löschen der eigenen Exe.
Inwiefern das auch unter Win98 schon geht, weiss ich nicht.
Das geht nicht mal unter allen Windows NT Varianten .

Zitat von moelski:
hat das mit dem MoveFileEx() denn irgendwelche Nachteile Ja, funktioniert nicht unter 98.
Aber 98 brauchen wir (leider) noch.
Das ist nicht dein Ernst, oder? Stimmt zwar, daß MoveFileEx unter Windows 9x nicht den MOVEFILE_DELAY_UNTIL_REBOOT Parameter implementiert, aber es ist ja nicht so als würde es unter Windows 9x keinen Mechanismus dafür geben: Nämlich wininit.ini.

In einigen Zeilen Code hat man dann in Windeseile einen Wrapper geschrieben:
Delphi-Quellcode:
function GetWindowsFolder: string;
const
  MAX_PATH_NTFS = 32767;
var
  CharArray : array[0..MAX_PATH_NTFS] of char;
begin
  FillChar(CharArray, SizeOf(CharArray), 0);
  if GetWindowsDirectory(CharArray, MAX_PATH_NTFS) > 0
    then Result := IncludeTrailingPathDelimiter(CharArray)
    else Result := '';
end;

function IsWindowsNT : boolean; inline;
begin
  Result := GetVersion and $80000000 = 0;
end;

function GetShortFilename(Filename: string) : string;
var
  ShortFilename : array[0..MAX_PATH] of char ;
begin
  if GetShortPathName(PChar(Filename), @ShortFilename, MAX_PATH) > 0
    then Result := ShortFilename
    else Result := Filename;
end;

function DeleteFileOnReboot(Filename : string) : boolean;
begin
  if IsWindowsNT
    then Result := MoveFileEx(PChar(ParamStr(0)), nil, MOVEFILE_DELAY_UNTIL_REBOOT)
    {
    FIXME:
    Prinzipiell können mehrere NUL Werte existieren. WritePrivateProfileString würde dann den jeweils ersten immer wieder überschreiben.
    Entsprechend wäre der 100% saubere Weg einen eigenen kleinen Parser für die wininit.ini zu bauen, der die rename Section sucht
    und die eigenen Einträge hinten dran hängt.
    }

    else Result := WritePrivateProfileString('rename', 'nul', PChar(GetShortFilename(Filename)), PChar(GetWindowsFolder + 'wininit.ini'));
end;
Wenn man dann noch das Verzeichnis entfernen will, bietet sich der bereits oft zitierte Trick mit der temporären Datei an. Sowas könnte dann z.B. so aussehen:
Delphi-Quellcode:
program DeleteMe;

{$APPTYPE CONSOLE}

uses
  SysUtils, windows;

function GetWindowsFolder: string;
const
  MAX_PATH_NTFS = 32767;
var
  CharArray : array[0..MAX_PATH_NTFS] of char;
begin
  FillChar(CharArray, SizeOf(CharArray), 0);
  if GetWindowsDirectory(CharArray, MAX_PATH_NTFS) > 0
    then Result := IncludeTrailingPathDelimiter(CharArray)
    else Result := '';
end;

function GetTempFolder : string;
const
  MAX_PATH_NTFS = 32767;
var
  CharArray : array[0..MAX_PATH_NTFS] of char;
begin
  FillChar(CharArray, SizeOf(CharArray), 0);
  if GetTempPath(MAX_PATH_NTFS, @CharArray) > 0
    then Result := IncludeTrailingPathDelimiter(CharArray)
    else Result := '';
end;

function GetTemporaryFilename : string;
var
  CharArray : array[0..MAX_PATH] of char;
begin
  FillChar(CharArray, SizeOf(CharArray), 0);
  if GetTempFileName(PChar(GetTempFolder), 'Del', 0, @CharArray) <> 0
    then Result := CharArray
    else Result := '';
end;

function GetShortFilename(Filename: string) : string;
var
  ShortFilename : array[0..MAX_PATH] of char ;
begin
  if GetShortPathName(PChar(Filename), @ShortFilename, MAX_PATH) > 0
    then Result := ShortFilename
    else Result := Filename;
end;

function IsWindowsNT : boolean; inline;
begin
  Result := GetVersion and $80000000 = 0;
end;

function DeleteFileOnReboot(Filename : string) : boolean;
begin
  if IsWindowsNT
    then Result := MoveFileEx(PChar(ParamStr(0)), nil, MOVEFILE_DELAY_UNTIL_REBOOT)
    {
    FIXME:
    Prinzipiell können mehrere NUL Werte existieren. WritePrivateProfileString würde dann den jeweils ersten immer wieder überschreiben.
    Entsprechend wäre der 100% saubere Weg einen eigenen kleinen Parser für die wininit.ini zu bauen, der die rename Section sucht
    und die eigenen Einträge hinten dran hängt.
    }

    else Result := WritePrivateProfileString('rename', 'nul', PChar(GetShortFilename(Filename)), PChar(GetWindowsFolder + 'wininit.ini'));
end;

procedure ExecuteFile(Filename, Parameters : string);
var
  StartupInformation : TStartupInfo;
  ProcessInformation : TProcessInformation;
begin
  writeln('Temporaere Datei erstellt: ', Filename);
  FillChar(StartupInformation, SizeOf(TStartupInfo), 0);
  FillChar(ProcessInformation, SizeOf(TProcessInformation), 0);
  StartupInformation.cb := SizeOf(TStartupInfo);

  CreateProcess(nil, PChar('"' + Filename + '" ' + Parameters), nil, nil, false,
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInformation,
    ProcessInformation);
end;

procedure CreateAndRunCopyOfMyself();
var
  RandomFilename : string;
begin
  RandomFileName := GetTemporaryFilename;
  if RandomFilename <> ''
    then
      if CopyFile(PChar(ParamStr(0)), PChar(RandomFilename), false)
        then ExecuteFile(RandomFilename, '"' + ParamStr(0) + '"')
        else DeleteFile(PChar(RandomFilename));
end;

procedure DeleteMyOldSelfAndMe();
begin
  if FileExists(ParamStr(1))
    then
      repeat
        writeln('Versuche alte Datei zu entfernen ...');
        Sleep(1000);
      until DeleteFile(PChar(ParamStr(1)));
  // Prinzipiell könnte man jetzt auch das Verzeichnis entfernen nur so nebenbei ...
  if DeleteFileOnReboot(ParamStr(0))
    then writeln('Alte Datei entfernt und mich selbst fuer Entfernung bei Reboot eingetragen.')
    else writeln('Alte Datei entfernt, aber ich selbst bin noch da: ', ParamStr(0));
end;

begin
  if ExtractFileExt(ParamStr(0)) = '.tmp'
    then DeleteMyOldSelfAndMe()
    else CreateAndRunCopyOfMyself;
  Writeln('Enter um die Anwendung zu beenden');
  Readln;
end.
Die Anwendung kopiert sich selbst in den Temp Ordner, ruft dann seine Kopie auf mit dem Originalnamen als Parameter. Danach versucht die Kopie das Original zu löschen. Sobald das geschehen ist, fügt es sich selbst zum Löschen bei Reboot hinzu. Prinzipiell kann man dann sobald die Original Datei gelöscht ist, auch das Verzeichnis entfernen indem man den Code in DeleteMyOldSelfAndMe an der Kommentarstelle erweitert.

Prinzipiell könnte man auch Code in eine fremde Anwendung injezieren um die eigene Anwendung zu löschen. Das käme komplett ohne Temporäre Dateien oder ähnliches aus. Allerdings ist es je nach System relativ schwer zu implementieren. Davon abgesehen kreischen die ganzen HIPS und Behaviour Blocker immer gleich rum, wenn man Code Injection durchführt. Weiß nicht ob das entsprechend für Dich eine Option wäre.

Achja: Ich behaupte übrigens, daß es keine Installationsaufgabe gibt, die man nicht mit einem der gängigen Installer Tools lösen kann. Entsprechend find ich es sinnbefreit einen womöglich dritt- oder viertklassigen Installer selbst zu bauen, wenns teilweise extrem leistungsfähige Open Source Projekte gibt (InnoSetup, NSIS um nur zwei zu nennen, von komerziellen Lösungen mag ich gar nicht erst anfangen).

Zu guter letzt weise ich darauf hin, daß ich der Übersicht halber nur rudimentäres Fehlerhandling implementiert hab. Bevor man den Code benutzt, sollte man ihn um entsprechendes Fehlerhandling erweitern.
Fridolin Walther
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#26

Re: Henne Ei Problem - eigene EXE löschen

  Alt 3. Jun 2009, 07:14
Moin !

Danke für den Code. Werde ich doch gleich mal testen.

Zitat:
Ich behaupte übrigens, daß es keine Installationsaufgabe gibt, die man nicht mit einem der gängigen Installer Tools lösen kann
Habe ja nie etwas Gegenteiliges behauptet
Wir hatten zu Beginn Innosetup und danach AKInstallerMSI. Und du hast vollkommen Recht das wir damit alles lösen können.

OT ein
Wir wollten aber einen Installer der genau auf unsere Bedürfnisse zugeschnitten ist. Nämlich:
- Installation / Update über Web
- Installation / Update über Resourcen ZIP
- Installation direkt auf USB Stick (bedarf ein paar extra Schritte)
- sehr einfaches Handling

Ich denke das unser Installer genau das erfüllt Und wir haben einen Installer wo wir die Quellcodes von Anfang an kennen und nach unseren Vorstellungen anpassen können. Mag sein das diese Aufgaben mit anderen Installern ebenfalls lösbar sind, aber nun ist er eh bald fertig und wie gesagt er macht genau das was wir brauchen. Nicht mehr und nicht weniger.
OT aus
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#27

Re: Henne Ei Problem - eigene EXE löschen

  Alt 3. Jun 2009, 08:48
Moin !

So code mal getestet und funzt soweit ganz gut. Aber das Löschen des Verzeichnisses bereitet noch ein Problem.

Wenn ich die Anwendung absolut starte (aus dem Verzeichnis heraus oder per Link), dann wird das Verzeichnis nicht gelöscht.
Starte ich die Anwendung relativ also z.B. "Neuer Ordner\Project1.exe" dann klappt auch das Löschen des Verzeichnisses.

Finde ich etwas merkwürdig, denn erst wird das Verzeichnis geleert und dann versucht ja die zweite Instanz das Verzeichnis zu entfernen. Mir ist nicht ganz klar warum das in die Hose geht.
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
Satty67

Registriert seit: 24. Feb 2007
Ort: Baden
1.566 Beiträge
 
Delphi 2007 Professional
 
#28

Re: Henne Ei Problem - eigene EXE löschen

  Alt 3. Jun 2009, 08:57
Vielleicht vorm Ordner löschen auch noch etwas warten (auch wenn das im Vergleich zur funktionierenden Methode unlogisch wäre) und den Fehler beim Ornder löschen genauer auswerten (beschreiben)... wenn es denn einen gibt.
  Mit Zitat antworten Zitat
moelski

Registriert seit: 31. Jul 2004
1.110 Beiträge
 
Delphi 2010 Professional
 
#29

Re: Henne Ei Problem - eigene EXE löschen

  Alt 3. Jun 2009, 09:07
Moin !

"Warten" habe ich auch schon probiert. Bringt aber nichts.
Muss mal sehen ob ich das Problem näher eingrenzen kann.
Dominik Schmidt
Greetz Dominik

I love Delphi 2007/2010
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#30

Re: Henne Ei Problem - eigene EXE löschen

  Alt 3. Jun 2009, 09:24
Hallo,

vielleicht solltest du vor dem Löschen per

SetCurrentDirectory

mal aus deinem Exe-Verzeichnis rausgehen (z.B. ins Temp).


Heiko
Heiko
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz