Jak odróżnić zamykanie i restart systemu

0

Witam.
Mam pytanie - jak rozróżnić zamykanie systemu Windows XP od próby ponownego uruchomienia komputera?

Mam program, który co n- zamknięć systemu powinien wstrzymać proces zamykania (restartu), uruchomić defragmentację, po jej zakończeniu ponowić ten proces. Zamykanie wykrywam dzięki komunikatowi WM_ENDSESSION (niestety, z WM_QUERYENDSESSION jest problem - pomija go, więc mogę obsłużyć jedynie WM_ENDSESSION, jednak mniejsza z tym).

W obsłudze procedury wykrywającej WM_ENDSESSION (która jest wywoływana zarówno podczas zamykania, jak i restartu) mam wywołanie do funkcji, która sprawdza czy system zamknięto odpowiednią ilość razy, jeżeli tak, to uruchamia defragmentację, jeżeli nie - to uruchamia systemowy program shutdown.exe z odpowiednimi parametrami.

Z tego co wyczytałem w SDK powinno się chyba zwrócić 0 aby dokonać zamknięcia systemu, jednak stosując analogicznie do przykładów z WM_QUERYENDSESSION takie coś:

Message.Result := 0;

nic się nie dzieje. Dlatego uruchamiam shutdown.exe. Wydaje mi się, że wina leży po mojej stronie - chyba nie potrafię poprawnie zwrócić tego parametru... Obsługa procedury WM_ENDSESSION wygląda mniej więcej tak:

procedure WMEndSession(var Message: TMessage); message WM_ENDSESSION;

(...)

procedure TForm1.WMEndSession(var Message: TMessage);
begin
  if Zamykanie then      // sprawdza, czy któryś z dysków ma zostać zdefragmentowany podczas zamykania
    gZamykanie := True   // po zakończeniu defragmentacji sprawdzany jest stan tej zmiennej, jeśli True, to należy zamknąć system
  else
    WinExec('shutdown.exe -s -f -t 0', SW_HIDE); //tutaj próbowałem stosować zamiast tego Message.Result := 0;
end;

Funkcja Zamykanie zajmuje się już ewentualnym uruchomieniem defragmentacji, tak więc w tej procedurze jest jedynie ustawienie stanu zmiennej gZamykanie (mogło by to co prawda być zawarte w funkcji, ale nie musi być) lub zamykanie systemu.
Zresztą, nawet gdyby udało się pominąć wywoływanie programu shutdown.exe i zamykać poprzez zwrócenie jakiegoś parametru, to i tak rozwiązuje to jedynie przypadek, gdy podczas zamykania systemu nie należy przeprowadzić defragmentacji. Co innego, gdy takie coś wystąpi - wtedy wyłączanie jest wstrzymywane, po czym przeprowadzana jest defragmentacja, po jej zakończeniu chciałbym właśnie w zależności od tego, jak użytkownik zamykał system, albo zamknąć, albo uruchomić ponownie komputer. Czy ktoś się orientuje, jak to rozróżnić? Delphi 2005 dla Win32.

0

WM_ENDSESSION

The WM_ENDSESSION message is sent to an application after the system processes the results of the WM_QUERYENDSESSION message. The WM_ENDSESSION message informs the application whether the session is ending.

A window receives this message through its WindowProc function.

LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // end-session option
LPARAM lParam );// logoff option
Parameters
hwnd
A handle to the window.
uMsg
The WM_ENDSESSION identifier.
wParam
If the session is being ended, this parameter is TRUE; the session can end any time after all applications have returned from processing this message. Otherwise, it is FALSE.
lParam
This parameter can be one or more of the following values. If this parameter is 0, the system is shutting down or restarting (it is not possible to determine which event is occurring).

0

Rzeczywiście, umknęło to mojej uwadze... Ale temat nie dotyczy jedynie komunikatu WM_ENDSESSION. Jeżeli istnieją inne metody typowo związane z Delphi i SDK, to bardzo chętnie je poznam. Podejrzewam też, że w Windowsie jest jakiś plik, w którym zapisywane są informacje o uruchomieniu, sposobie zamknięcia itp. tyle że pewnie wpis pojawia się w takim pliku na samym końcu procesu zamykania / restartu, gdy jest już za późno na jakiekolwiek działanie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1