![]() |
Ruhezustand blockieren-> Versuch erkennen -> selbst au
Hi, wie geht das?
ich habe ein Programm das "vertrauliche Daten" anzeigen kann, und wenn der User jetzt den Ruhezustand auslöst, will ich das blockieren, alle Daten speichern + beenden und dann selbst den Ruhezustand auslösen, so dass nicht beim nächsten Start die Daten wieder angezeigt werden. nen Code für Ruhezustand auslösen hab ich irgendwo hier schon mal gefunden, das ist kein Problem. aber wie kann ich ihn blockieren und sogar einen Versuch erkennen? [ich hoffe mal ich hab in die richtige Sparte gepostet] |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
![]() Damit brauchst du den Ruhezustand nicht blockieren, sondern einfach nur auf die Message reagieren und deine Daten "verstecken" sobald diese Nachricht kommt. |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Hi ichbins,
im Interface:
Delphi-Quellcode:
In der Implementation:
procedure WMPowerBroadcast(var Msg : TWMPower) ; message WM_POWERBROADCAST;
Delphi-Quellcode:
//------------------------------------------------------------------------
procedure TfrmMain.WMPowerBroadcast(var Msg: TWMPower); //------------------------------------------------------------------------ // Suspend ablehnen //------------------------------------------------------------------------ begin Msg.Result := BROADCAST_QUERY_DENY; end; |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Wie ich schon geschrieben habe:
Wenn er soweit ist, dann braucht er den Versuch doch nicht blockieren um ihn dann selber zu starten. Problem dabei ist nämlich: Er blockiert den Versuch in den Ruhezustand zu gehen, "versteckt" seine Daten und initiiert den Ruhezustand dann selber. Folge: Er landet WIEDER in seiner Behandlungsroutine wo er den Ruhezustand blockiert und wieder aufruft => Endlosscheife. Aber wenn er schon soweit ist den Versuch in den Ruhezustand zu gehen zu überprüfen, dann kann er doch dort gleich seine Daten "verstecken" und den Ruhezustand zulassen. |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Das geht nicht, da das Suspend sehr zeitkritisch ist. Wenn man die Broadcast Nachricht nicht sofort beantwortet, wird das Suspend ausgelöst, ohne dass man darüber die Kontrolle hat. Besser wäre es, die Nachricht dann zu blockieren, die "Daten zu verstecken" und ein entsprechendes Flag zu setzen. Dann die Nachricht an sich selber schicken. Da das Flag jetzt gesetzt sein sollte, wird auf die Nachricht nicht mehr reagiert.
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
<edit> OK, hast recht. Aber er hat immerhin ZWANZIG Sekunden Zeit auf die Nachricht zu reagieren. Das osllte wohl ausreichen. </edit> |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Das ist praktische Erfahrung. Und Windows wartet auch nicht auf jedes Programm. Sonst würde ja das Runterfahren verhindert durch Programme, die diese Message gar nicht verarbeiten.
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Siehe mein Edit.
Das Programm hat 20 Sekunden Zeit auf PBT_APMQUERYSUSPEND zu reagieren und ebenfalls 20 Sekunden bei PBT_APMSUSPEND. Das sollte wirklich reichen. Denn ich denke mal es geht auch deutlich schneller, wenn er das Programm beendet. |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Wo hast Du denn die 20 Sekunden her? Das ist vielleicht der Fall bei einem Shutdown, aber was ist bei Hibernation? Dort bleiben zwar die Daten erhalten (theroetisch), aber wenn man dem nicht traut oder man gerne noch eine offene SQL-Server-Verbindung schliessen möchte... Und gerade auf Laptops macht das dann whuusch und weg.
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
![]() ![]() Jeweils der erste Link |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Da steht aber:
Zitat:
Zitat:
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
Und anscheinend ist für Microsoft "As quickly as possible" = "The system allows approximately 20 seconds" Und das "verstecken" der Daten sollte allerdings sicher nicht mehr als eine, max. zwei Sekunden dauern. Ich kann aus meiner Erfahrung jedenfalls sagen, dass die Zeit ausreicht noch Daten an einen Server zu schicken und auf Antwort zu warten. Aber das sollte ichbins selber entscheiden wie er es machen will. |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
Zitat:
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
Was machen denn die ganzen "Internet-Cafe Programme", die alle möglichen Sachen vor dem User über die Registry verstecken. Wenn es die Sicherheit erfordert, sollte man schon auch zu solchen Mitteln greifen dürfen. Gruss |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Zitat:
Zitat:
Zitat:
Zitat:
Also ich fände die erste Idee fals machbar schon recht fein (bis jetzt ^^). |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
ich mach halt einfach eine boolean-Variable etwa so:
Delphi-Quellcode:
procedure getmessage;
begin if bool then exit; post(abbruchmessage); bool:=true; save; post(shutdownmessage); |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Inzwischen bin ich so weit gekommen:
Delphi-Quellcode:
Aber leider funktioniert das ganze nicht. Wenn ich den Ruhezustand auslöse, erhält er zwar die wmpowerbroadcast, aber erkennt nicht, dass es sich um eine pbt_apmquerysuspend handelt.
procedure TForm1.WMPowerBroadcast(var Msg: TWMPower);
begin showmessage('got message: wmpowerbroadcast'); if ((msg.msg=PBT_APMQUERYSUSPEND) and (not readyforsuspend)) then begin showmessage('message is pbt_apmquerysuspend'); Msg.Result := BROADCAST_QUERY_DENY; if messagedlg('denied. suspend?',mtinformation,[mbyes,mbno],0)=mryes then suspend(self); end else showmessage('message is not pbt_apmquerysuspend'); end; procedure suspend(var form:tform1); begin form.readyforsuspend:=true; form.closeallowed:=true; form.close; setsystempowerstate(true,false); end; |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Schreibe einen PnP-Treiber der den Ruhezustand nicht unterstützt und installiere ihn. Das funzt immer - den Ruhezustand gibt's dann nimmer.
Aber mal ernsthaft, kannst du das mit dem Verstecken der Daten nochmal genauer ausführen?! BTW: Zitat:
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
@treiber: vielleicht eine Stufe zu brutal ;)
ich will den Ruhezustand ja nur verhindern, um dann meine Sachen zu speichern, was unter Umständen länger als 20 Sekunden dauern kann, und dann den Ruhezustand selbst auslösen, so dass es dem User nur "verzögert" scheint. |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
wo ist das problem?
verarbeite die message, sage nein zum supend, hibernate oder was auch immer. speichere deine daten und entferne sie aus deiner anzeige, danach setzt du eine boolean-variable auf true. dann rufst du die funktion für den suspend/hibernate modus auf und erlaubst bei erneuter messageverarbeitung anhand deiner vorher gesetzten variablen den suspend/hibernate. das sollte die einfachste methode darstellen. |
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Das ist mir schon klar. Ich hab nur Probleme damit, zu Überprüfen, ob das WM_Powerbroadcast auch wegen dem Ruhezustand ausgelöst wurde und nicht wegen z.B. einem Reboot.
Diese Impementierung
Delphi-Quellcode:
scheint jedenfalls nicht zu funktionieren.
if msg.msg=PBT_APMQUERYSUSPEND then
|
Re: Ruhezustand blockieren-> Versuch erkennen -> selbs
Ich habe jetzt eine Lösung für mein Problem gefunden und poste sie hier:
Oben in der Definition der Form müssen folgende 2 Einträge hinzugefügt werden:
Delphi-Quellcode:
Und im Code-Abschnitt die folgenden 3 Prozeduren:
procedure WMPowerBroadcast(var Msg: TWMPower); message WM_POWERBROADCAST
readyforsuspend:boolean;
Delphi-Quellcode:
function EnableShutDownPrivilege: Boolean;
var vi: TOSVersionInfo; hToken: THandle; tp: TTokenPrivileges; h: DWord; begin result := False; 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; result := AdjustTokenPrivileges(hToken, False, tp, 0, PTokenPrivileges(nil)^, h); CloseHandle(hToken); end; end; procedure TForm1.WMPowerBroadcast(var Msg: TWMPower); begin if ((msg.powerevt=PBT_APMQUERYSUSPEND) and (not readyforsuspend)) then begin Msg.Result := BROADCAST_QUERY_DENY; readyforsuspend:=true; suspend(self); end; end; procedure suspend(var form:tform1) {die Variable form1 wird hier übertragen, damit auch von der Klassenunabhängigen Prozedur SUSPEND auf die form zugegriffen werden kann.}); begin {hier Speichervorgänge, wie das Schliesen des Forms etc. vornehmen. Sie dürfen beliebig lange dauern.} if enableshutdownprivilege then setsystempowerstate(true,false); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz