Autor Beitrag
thommy f
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

Windows 2K pro
Delphi 5 Enterprise
BeitragVerfasst: Di 11.08.09 15:35 
Hallo Leute, ich bin auch mal wieder da und hätte ein kleines Problemchen,

also kurz zu dem was ich machen möchte:

ich habe ein kleines Delphi-Porgramm geschrieben, dass sich aus einer Datenbank nach der Reihe verschiedene Verzeichnisse holt, und den Inhalt der Verzeichnise auf einen Stick kopiert (ein kleines Backup-Tool eben.)

Das klappt wie am Schnürchen.

Jetzt wollte ich das Programm so in Windows (Es soll auf W2K und WinXP laufen) einbinden, dass es bei jedem Herunterfahren des Systems ausgeführt wird.

Das gestaltet sich jedoch komplexer als ich dachte, denn selbst wenn man das Betriebssystem dazu überreden kann, das Programm auszuführen, wird dieses zwar gestartet aber Windows wartet leider nicht, bis es wieder beendet wurde, sondern erzwingt einen Programmabbruch mit Fehlermeldung.

Also, habe ich mir gedacht, programmieren wir das Teil halt so, dass es nach dem erfolgreichen Backup die Windows-Eigene "Shutdown-Routine" aufruft. Und genau das ist unter Delphi 5 Enterprise leichter gesagt als getan.

Habe im Netz folgende Funktion gefunden, die auch "fast" das macht, was sie soll:

ausblenden 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:
function ExitWin(flag:word): Boolean;
var vi      : TOSVersionInfo;
    hToken  : THandle;
    tp      : TTokenPrivileges;
    h       : DWord;

begin
  vi.dwOSVersionInfoSize:=SizeOf(vi);
  GetVersionEx(vi);
  if vi.dwPlatformId = VER_PLATFORM_WIN32_NT then // Windows NT 
  begin
    OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,hToken);
    LookupPrivilegeValue(nil,'SeShutdownPrivilege',tp.Privileges[0].Luid);
    tp.PrivilegeCount := 1;
    tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    h := 0;
    AdjustTokenPrivileges(hToken,False,tp,0,PTokenPrivileges(nil)^,h); 
    CloseHandle(hToken);
    result := ExitWindowsEx(flag,0); 
  end
  else // Windows 95 
  begin
    result := ExitWindowsEx(flag,0); 
  end;
end;


leider produziert mir diese Funktion ab und zu einen Rundll32-Fehler und fährt meinen PC zwar herunter, aber schaltet diesen nicht ab ("Sie können den Computer jetzt ausschalten")

Das ist nicht ganz das, was ich gerne erreicht hätte.

Bitte HILFE, bzw. Anregungen. Ich tappe z.Zt. wiedermal betriebsblind im Kreis!

DANKE!

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt

_________________
Der Mensch wächst mit seinen Aufgaben *** Wer kämpft kann verlieren, wer nicht kämpft hat schon verloren
Timosch
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1314

Debian Squeeze, Win 7 Prof.
D7 Pers
BeitragVerfasst: Di 11.08.09 18:35 
Was übergibst du denn als Flag? EWX_POWEROFF oder EWX_SHUTDOWN? Die Function stimmt so prinzipiell schon, ich benutze sie auch.

Wehe, hier bringt irgendjemand den shutdown.exe-Kram an! Man muss Leuten ja nicht sofort Fehler beibringen.

_________________
If liberty means anything at all, it means the right to tell people what they do not want to hear. - George Orwell
thommy f Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

Windows 2K pro
Delphi 5 Enterprise
BeitragVerfasst: Di 11.08.09 19:22 
Ich habe jetzt in einem anderen Forum eine Funktion gefunden, die im Grunde genau das macht, was ich möchte. Allerdings zeigt mein Rechner beim Abmelde-Vorgang irgendeinen Fehler (leider so kurz, dass ich ihn nicht wieder geben kann).

Wenn ich meinen Rechner dann wieder einschalte, geht meine LAN-Verbindung nicht mehr. Erst wenn ich Ihn dann über START-Beenden herunterfahre und anschließend ein paar Minuten aus lasse, ist die Verbindung beim Hochfahren (meistens) wieder aktiv.

Sie wird zwar konsequent mit gestartet und auch als "verbunden" angezeigt, aber leider findet kein Datentransfer statt.

Woran könnte denn das nun wieder liegen?

die Funktion, die ich jetzt nutze sieht folgendermaßen aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function  MyWindowsShutdown(AForce: Boolean): Boolean;
  var
    hToken: THandle;
    tp:     TTokenPrivileges;
    h,
    Flag:   DWord;
  begin
    flag:=EWX_SHUTDOWN;
    if (Win32Platform = VER_PLATFORM_WIN32_NT) then
    begin
      flag:=EWX_POWEROFF;
      OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
      LookupPrivilegeValue(nil'SeShutdownPrivilege', tp.Privileges[0].Luid);
      tp.PrivilegeCount:=1;
      tp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
      h:=0;
      AdjustTokenPrivileges(hToken, False, tp, 0, PTokenPrivileges(nil)^, h);
      CloseHandle(hToken);
    end;
    if AForce then flag:=flag or EWX_FORCE;
    Result:=ExitWindowsEx(flag, 0);
end;


und ich rufe sie mit folgender Zeile auf:

ausblenden Delphi-Quelltext
1:
MyWindowsShutdown(true);					



dazu gleich noch die Frage: Bringt man in dieser Funktion vielleicht noch irgendwo ein

ausblenden Delphi-Quelltext
1:
Application.Terminate					


mit unter, damit mein eigenes Programm nicht vom Betriebssystem geschlossen werden muss, sondern nachdem Es den "Shutdown" für Windows ausgelöst hat selbst noch ordnungsgemäß beendet wird?

ich weiß, dass sind ziehmlich "DUMME" Fragen, aber ich hab mit FLAGS und WINDOWS und API usw. zum ersten Mal zu tun, und das Programm muss schnellstmöglich fertig werden. Also ist leider nicht viel Zeit für lange Lektüre.

Danke euch!

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt

_________________
Der Mensch wächst mit seinen Aufgaben *** Wer kämpft kann verlieren, wer nicht kämpft hat schon verloren
Timosch
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1314

Debian Squeeze, Win 7 Prof.
D7 Pers
BeitragVerfasst: Di 11.08.09 20:43 
Die beiden Funktionen machen exakt das gleiche. Zumindest habe ich keine Unterschiede für den NT-relevanten Teil gefunden.

Wieso setzt du den Parameter auf true? Das ist ein bisschen ruppig und könnte evtl. das Problem mit der LAN-Verbindung auslösen. (Damit wird das Flag EWX_FORCE übergeben.)

Wie rufst du die erste Funktion (ExitWin) auf? Mit EWX_SHUTDOWN oder EWX_POWEROFF? Probier mal ExitWin(EWX_POWEROFF);. Das sollte ggf. das Problem beheben, dass der PC nicht abschaltet. Wenn das nicht geht bzw. die Fehlermeldung mit rundll32 bleibt, nimm ExitWin(EWX_POWEROFF or EWX_FORCEIFHUNG);

Wie genau lautet denn diese Fehlermeldung eigentlich? (Ich meine die rundll32-Meldung, nicht die aus deinem zweiten Post, die nur ganz kurz kommt.)

Application.Terminate müsste eigentlich überflüssig sein, wenn dein Programm nicht gerade in irgendeiner Entlosschleife hängt o.ä. Windows beendet Programme völlig ordnungsgemäß, wenn sie sich nicht weigern. Wenn sie das tun, werden sie ggf. zwangsbeendet, und das dürfte die Fehlermeldung sein, die du ganz kurz siehst. Ich glaube aber nicht, dass dein Programm hängt. Das dürfte eher ein anderes sein.

PS: Verwende statt Code-Tags Delphi-Tags, dann ist die Darstellung besser und Narses muss das nicht für dich machen. :-)

_________________
If liberty means anything at all, it means the right to tell people what they do not want to hear. - George Orwell
thommy f Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

Windows 2K pro
Delphi 5 Enterprise
BeitragVerfasst: Mi 12.08.09 09:20 
OK, danke, jetzt läuft das Prog so wie´s soll. (Glaube ich wenigstens (Tests folgen)). habe das jetzt so gelöst, wie Timosch empfohlen hat.

Gruß:

Thommy F

_________________
Der Mensch wächst mit seinen Aufgaben *** Wer kämpft kann verlieren, wer nicht kämpft hat schon verloren