question

AKR-6718 avatar image
0 Votes"
AKR-6718 asked XiaopoYang-MSFT edited

Windows shutdown functions

Hello,

I am not clear on the windows shut down function. I want the system to shutdown by closing all the apps (controlled shutdown).
The function which is used in the code is

 ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN, 0); 

This does the shut down job but I am not sure if it is correct way to use the function. Could some one help me with this.?

Thank you!





windows-serverwindows-apic++
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Castorix31 avatar image
0 Votes"
Castorix31 answered

You can see MSDN doc at Shutting Down


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

XiaopoYang-MSFT avatar image
1 Vote"
XiaopoYang-MSFT answered

The Document Example implements how the system shut down and all the applications are forced to close.
You can check your code according that.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AKR-6718 avatar image
0 Votes"
AKR-6718 answered AKR-6718 commented

The Shut down function is working but I see that in my code when i use ShutDown = TRUE , none of the previous lines are working. When Status message is true, i want the warning message to come and then after 3 sec the windows to shutdown. instead it goes straight to shutdown. Can you please suggest if it is because of sesystem privilage?


 UINT Status;
 bool ShutDown = FALSE;
 INT_PTR CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wP, LPARAM lP){
    
 if (msg == Status){
 ........
 // Warning message
 Sleep (3000);
 ShutDown = TRUE;
 }
 ;:::::::::::::::::
 ::::::::::::::::::
 if (ShutDown) {
  if (dwThisTID != dwCurrTID) 
  {
  AttachThreadInput(dwThisTID, dwCurrTID, TRUE);
  SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &lockTimeOut, 0);
  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
  AllowSetForegroundWindow(ASFW_ANY);
  }
  SetActiveWindow(hDlg);
  SetForegroundWindow(hDlg);
  SetFocus(hDlg);
  EnableWindow(hDlg, true);
    
  if (dwThisTID != dwCurrTID) {
  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (PVOID)lockTimeOut, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
  AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
  }
    
    
  SetWindowPos(hDlg, NULL, 0, 0, LOWORD(lP), HIWORD(lP), SWP_SHOWWINDOW);
  if (!OpenProcessToken(GetCurrentProcess(),
  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  return(FALSE);
    
  // Get the LUID for the shutdown privilege. 
  LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
    
  tkp.PrivilegeCount = 1; // one privilege to set    
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
  // Get the shutdown privilege for this process. 
  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
    
  ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN, 0);  //Windows herunterfahren
  //ExitWindowsEx(EWX_REBOOT, 0);
  ShutDown = FALSE;
  }
 }

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

No, the warning I want to show is code specific. It uses another callback function with WM_PAINT.

0 Votes 0 ·
AKR-6718 avatar image
0 Votes"
AKR-6718 answered XiaopoYang-MSFT edited

I realized it is much better to use shutdown in a callback function and call it with a timer.

· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Have you resolved your problem ?

0 Votes 0 ·

Not yet. I am working on it. The callback function should definitely solve the problem but It is not working yet.

0 Votes 0 ·

The issue is solved by using Callback function for shutdown operation and calling it with settimer() when necessary.

0 Votes 0 ·

I am glad you have got your solution and thanks for your sharing, I would appreciate it if you mark them as answer and this will be beneficial to other community.




0 Votes 0 ·
Castorix31 avatar image
1 Vote"
Castorix31 answered Castorix31 commented

If you want to Shutdown with a custom warning message, you can do something like this = >

87289-shutdown.jpg

(I commented ExitWindowsEx to test with a Beep)

 #define _CRT_NON_CONFORMING_SWPRINTFS
 #define _CRT_SECURE_NO_WARNINGS
 #include <windows.h>
 #include <tchar.h>
    
 #pragma comment(linker,"\"/manifestdependency:type='win32' \
 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
 processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    
 HINSTANCE hInst;
 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 int nWidth = 600, nHeight = 200;
 #define IDC_BUTTON 10
    
 float nTimeEllapsed = 0;
 float nTotalTime = 5000;
 bool bShutDown = false;
    
 int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
 {
     hInst = hInstance;
     WNDCLASSEX wcex =
     {
         sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION),
         LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("WindowClass"), NULL,
     };
     if (!RegisterClassEx(&wcex))
         return MessageBox(NULL, TEXT("Cannot register class !"), TEXT("Error"), MB_ICONERROR | MB_OK);
     int nX = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2, nY = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;
     HWND hWnd = CreateWindowEx(0, wcex.lpszClassName, TEXT("Test"), WS_OVERLAPPEDWINDOW, nX, nY, nWidth, nHeight, NULL, NULL, hInst, NULL);
     if (!hWnd)
         return MessageBox(NULL, TEXT("Cannot create window !"), TEXT("Error"), MB_ICONERROR | MB_OK);
     ShowWindow(hWnd, SW_SHOWNORMAL);
     UpdateWindow(hWnd);
     MSG msg;
     while (GetMessage(&msg, NULL, 0, 0))
     {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
     }
     return (int)msg.wParam;
 }
    
 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
     static HWND hWndButton = NULL, hWndStatic = NULL;
     int wmId, wmEvent;
     switch (message)
     {
     case WM_CREATE:
     {
         hWndButton = CreateWindowEx(0, L"Button", L"Click", WS_CHILD | WS_VISIBLE | BS_PUSHLIKE, 250, 10, 60, 32, hWnd, (HMENU)IDC_BUTTON, hInst, NULL);
         return 0;
     }
     break;
     case WM_COMMAND:
     {
         wmId = LOWORD(wParam);
         wmEvent = HIWORD(wParam);
         switch (wmId)
         {
         case IDC_BUTTON:
         {
             if (wmEvent == BN_CLICKED)
             {
                 nTimeEllapsed = 0;
                 bShutDown = true;
                 BOOL bRet = TRUE;
                 HANDLE hToken;
                 TOKEN_PRIVILEGES tkp;
                 if (bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
                 {
                     LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
                     tkp.PrivilegeCount = 1;
                     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                     bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
                 }
                 if (bRet)
                 {                    
                     SetTimer(hWnd, 1, 100, NULL);
                 }
             }
         }
         break;
         default:
             return DefWindowProc(hWnd, message, wParam, lParam);
         }
     }
     break;
     case WM_TIMER:
     {
         if (nTimeEllapsed >= nTotalTime)
         {
             KillTimer(hWnd, 1);
             Beep(6000, 500);
             bShutDown = false;
             //ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN, 0);
             //ExitWindowsEx(EWX_FORCE | EWX_REBOOT, 0);
         }
         nTimeEllapsed += 100;
         InvalidateRect(hWnd, NULL, TRUE);
     }
     break;
     case WM_PAINT:
     {
         PAINTSTRUCT ps;
         HDC hDC = BeginPaint(hWnd, &ps);
         if (bShutDown)
         {
             RECT rc;
             GetClientRect(hWnd, &rc);
             WCHAR wsBuffer[255] = TEXT("");
             float nSeconds = (nTotalTime - nTimeEllapsed) / 1000.0f;
             swprintf(wsBuffer, L"Shutdown in : %.2f seconds\r\n", nSeconds);
             int nFontSize = -MulDiv(32, GetDeviceCaps(hDC, LOGPIXELSY), 72);
             HFONT hFont = CreateFont(nFontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS,
                 NONANTIALIASED_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"Arial");
             HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
             SetTextColor(hDC, RGB(255, 0, 0));
             DrawText(hDC, wsBuffer, lstrlen(wsBuffer), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
             SelectObject(hDC, hFontOld);
             DeleteObject(hFont);
         }
         EndPaint(hWnd, &ps);
     }
     break;
     case WM_DESTROY:
     {
         PostQuitMessage(0);
         return 0;
     }
     break;
     default:
         return DefWindowProc(hWnd, message, wParam, lParam);
     }
     return 0;
 }



shutdown.jpg (40.7 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you so much. This is great code but the one I am working have customized warning messages. The warning message message is not windows shutdown. It is more like power is low or similar.

What I want my code to do: when I receive a status packet from micro controller and there is change in it a warning message pops up. if it is critical(after some seconds) windows shut down should take place
What it is doing now: no warning message is shown , the system shuts down immediately after receiving the packet.

0 Votes 0 ·

What I want my code to do: when I receive a status packet from micro controller and there is change in it a warning message pops up. if it is critical(after some seconds) windows shut down should take place

You can use the same Timer method : you start the Timer when you receive your notification (I used a click to simulate the start of the Timer/countdown)
Then you Shutdown at the end of the Timer

1 Vote 1 ·