Jump to content
  • Advertisement
Sign in to follow this  
xycsoscyx

Detecting when Windows shuts down

This topic is 4858 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Pretty simple (as the name implies), but how do I detect when Windows is shutting down (or a session is ending, perhaps?), without creating a window and responding to the event? I have an application that is going to be running in the background (a downloader, it just runs silently to download an update), but I want to make sure it stops and exits properly when Windows is shutting down (or users are logging off, or powering down, or whatever, basically, whenever I should be closing, I want to close).

Share this post


Link to post
Share on other sites
Advertisement
a signal handler?

#include <csignal>

have a look online

does windows just send terminate signals to all processes on shutdown?

Share this post


Link to post
Share on other sites
In your message loop you can process the WM_CLOSE message.
When you recieve that, your program has either been closed(alt-f4, the X in the corner)
or it has been told by window's shutdown to close.


OR, if you don't have a message loop(which it sounds like you don't...)

#include <windows.h>
static BOOL WINAPI Handler (DWORD CntrlEvent);

int _tmain (int argc, LPTSTR argv [])
{
//May want to look up the options on this command:
SetConsoleCtrlHandler (Handler, TRUE);
return 0;
}

//This handles the close events:
BOOL WINAPI Handler (DWORD CntrlEvent)
{
switch (CntrlEvent) {
case CTRL_C_EVENT:
return TRUE;
case CTRL_CLOSE_EVENT:
//Code to handle you close messages
return TRUE;
case CTRL_LOGOFF_EVENT:
//Code handles a LOG OFF message
return TRUE;
case CTRL_SHUTDOWN_EVENT:
//Code handles a System Shutdown
return TRUE;
default:
return FALSE; //TRUE == Message was handled by your handler, false means the system should take care of this for you
}
}




Share this post


Link to post
Share on other sites
Aha, that is exactly what I was looking for. It is a Windows application, but I wanted something completely seperate that simply tells me when I should be closing (due to forced close or shutdown or etc). I didn't want to have to create a new hidden window or anything just to detect that.

Thanks

Share this post


Link to post
Share on other sites
Hmmm, or not, looking over it (and trying it out), does this only work for console applications? My application isn't a console app, but I don't want to use a hidden window to detect this.

Share this post


Link to post
Share on other sites
Looking over what?

If your app has a message loop, try using the control event handler to send a WM_QUIT message to exit the loop - or to send a message telling your program to execute it's shuts down procedures. You don't need a hidden window to detect it, but you probably will need a message loop of some kind. Here's an example. YMMV.



#include <windows.h>
#include <tchar.h>

// global thread id
static DWORD g_tid = 0;

// ---------------------------------------------------------------------------

void _stdcall PrintError(LPTSTR szMsg, DWORD ErrorCode)
{
WCHAR *errMsg;

FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR) &errMsg, 0, NULL );

#ifdef UNICODE
LPWSTR szFmt = L"%s - %08X - %s"; // \n
#else
LPSTR szFmt = "%s - %08X - %S"; // \n
#endif

printf(szFmt, szMsg, ErrorCode, errMsg );

LocalFree( errMsg );

}

// ---------------------------------------------------------------------------

BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{

switch (fdwCtrlType)
{
// Handle the CTRL+C signal.
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT: // uncomment this to capture sysmenu close

if ( g_tid != 0 ) {
while ( !PostThreadMessage(g_tid,WM_QUIT,0,0) ) { Sleep(10); }
}

return TRUE; // indicate handled

default:
return FALSE;
}

}


BOOL _stdcall InstallSignalHandler(PHANDLER_ROUTINE pfnCtrlHandler)
{
BOOL fSuccess = SetConsoleCtrlHandler(pfnCtrlHandler, TRUE);
if ( !fSuccess ) {
PrintError(_T("Error InstallSignalHandler\n"), GetLastError());
}
return fSuccess;
}

BOOL _stdcall UnInstallSignalHandler(PHANDLER_ROUTINE pfnCtrlHandler)
{
BOOL fSuccess = SetConsoleCtrlHandler(pfnCtrlHandler, FALSE);
if ( !fSuccess ) {
PrintError(_T("Error UnInstallSignalHandler\n"), GetLastError());
}
return fSuccess;
}

// ---------------------------------------------------------------------------

void _stdcall SuperMsgLoop(void)
{
MSG msg;

// Start the message loop
while ( msg.message != WM_QUIT )
{
// Check if a message is waiting for processing
if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) // PM_REMOVE | PM_QS_POSTMESSAGE)
{

// Change the format of certain messages
// TranslateMessage( &msg );
// Pass the message to WndProc() for processing
// messages not associated with a window can not be dispatched
// DispatchMessage( &msg );

}
else {
// do stuff

}
}
}

DWORD WINAPI ThreadFunction(LPVOID lpParameter)
{
// without this we can not exit msgloop
g_tid = GetCurrentThreadId();

SuperMsgLoop();

return 0;

}

// ---------------------------------------------------------------------------

int main(void)
{
DWORD dwThread, exThread;

InstallSignalHandler(CtrlHandler);

// create the thread that launches the message loop
// CreateThreadEx
HANDLE hThread = CreateThread(NULL, (DWORD)NULL,
(LPTHREAD_START_ROUTINE)ThreadFunction,
(LPVOID) NULL, (DWORD)NULL, &dwThread);

// suspend main thread until new thread completes
WaitForSingleObject(hThread,INFINITE);

// examine create thread response
if ( !GetExitCodeThread(hThread, &exThread) ) {
PrintError(_T("GetExitCodeThread\n"),GetLastError());
}

// close thread handle
CloseHandle(hThread);
UnInstallSignalHandler(CtrlHandler);

return 0;

}



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!