Shutting down Windows

Heiko 1,291 Reputation points
2023-04-26T14:49:30.99+00:00

I have a specific image set in Windows 10 for the login screen (image B). Whenever I shut down Windows and restart or reboot, I get image B as the login screen. Rarely it happens that something in Windows did not work or an update has problems during the installation. Then the next time I boot the PC I get a default image as login screen (image A). Therefore, the display of image A is always an indication that something did not work properly during the last shutdown. If I then reboot Windows again, I get image B as the login screen again. I have a WPF app with a MainWindow. I want the user to be able to shutdown Windows from my app. What is the cleanest way to do this? In a custom C++ DLL I use the following method:

bool NativeHelpers::ShellHelper::ShutdownNow()
{
	HANDLE hToken;
	TOKEN_PRIVILEGES tkp;

	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
		return false;

	if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid))
		return false;

	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
	{
		::CloseHandle(hToken);
		return false;
	}

	bool ret = true;

	if (!ExitWindowsEx(EWX_LOGOFF | EWX_POWEROFF | EWX_SHUTDOWN, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE))
		ret = false;

	::CloseHandle(hToken);
	return ret;
}

Since ExitWindowsEx() immediately starts the Windows shutdown and blocks the current thread, after a few seconds I get a message from Windows that my app is blocking the shutdown. Of course, this message is not wanted. Therefore I start ShutdownNow() in a separate thread and close the MainWindow and the app afterwards:

private void ShutdownSelected()
{
	Task<bool> shutdown = Task.Run(() => ShellHelper.ShutdownNow());
	bool ret = true;

	if (Task.WaitAny(shutdown, Task.Delay(1000)) == 0)
		if (shutdown.IsCanceled || shutdown.IsFaulted)
			ret = false;
		else
			ret = shutdown.Result;

	if (ret)
	{
		Close();
		App.Current.Shutdown();
	}
}

This now works visually without any problems. My app does not block the shutdown. But whenever I use this method of my app, after the next boot of the PC I get the default login screen with image A. So something did not work as it should. What do I have to do to shut down the PC cleanly so that I get image B as login screen after booting?

Developer technologies | Windows Presentation Foundation
Windows development | Windows API - Win32
Developer technologies | C#
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 12,731 Reputation points Microsoft External Staff
    2023-05-02T07:24:40.5033333+00:00

    @Heiko Confirmed. It's about 'Windows spotlight' feature. You can Send feedback to Microsoft with the Feedback Hub app about the concern.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Heiko 1,291 Reputation points
    2023-05-02T13:31:33.68+00:00

    Is there no way to programmatically shut down Windows, as Windows itself does, when the user clicks on the stutdown entry in Windows start menu? It is obviously different from the example I described.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.