How can I know if started by WER, the OS is running in a GUI environment?

Rohan Pande 420 Reputation points
2024-07-04T07:48:35.1333333+00:00

Hi,

I am building a Win32 application using WinUI2 as GUI.

Before displaying a window to the user, we are checking our Desktop capabilities from the Operating System has shown below.

bool
CheckDesktop () noexcept
{
    HDESK   thread_desktop;
    uint32_t    rc;
	thread_desktop = ::GetThreadDesktop (::GetCurrentThreadId ());
	
	if (!thread_desktop)
    	return false;
	
	// Expected size of buffer (rc here) is 4 bytes. So,
	// use uint32_t buffer type instead of Bool.
	
	if (::GetUserObjectInformationA (thread_desktop, UOI_IO, &rc, sizeof (rc), nullptr) == 0)
    	return false;

	if (rc != 1)
    	return false;
	
	return true;
}

We have chosen our application in such a way that if this above function returns false, we don't start our application and exit it from there.

If the above function returns false, we say that application is running in non-GUI environment.

But along with this, we have registered for WER framework as shown below:

int WINAPI
wWinMain ([[maybe_unused]] HINSTANCE pInstance, [[maybe_unused]] HINSTANCE pPrevInstance, [[maybe_unused]] PWSTR pCmdLine, [[maybe_unused]] int pShowCmd)
{
   	 if (!CheckDesktop ())
		return 1; 

	// ... Some other calls

 	// Registering for WER
	
	HRESULT hresult;
	hresult = ::RegisterApplicationRestart (nullptr, RESTART_NO_PATCH | RESTART_NO_CRASH | RESTART_NO_HANG);

}

Stating a scenario,

User launches the application CheckDesktop func will return true and WER registration succeeds. As WER is registered so the application will come back upon restart but that is not working as expected because when the application starts by WER the 'CheckDesktop ()' returns false due to which my application exits.

As stated in Desktops "The Winlogon desktop is active while a user logs on. The system switches to the default desktop when the shell indicates that it is ready to display something, or after thirty seconds, whichever comes first."

I understand that OS might take some time for this switch, but can somebody help me in what should be done for my CheckDesktop function to return true in the case where application was started by WER?

Thanks

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,519 questions
0 comments No comments
{count} votes

Accepted answer
  1. RLWA32 43,146 Reputation points
    2024-07-04T08:38:39.22+00:00

    Since you have not clearly defined what you mean by "GUI Environment" i suggest that you consider any process running in an interactive session (i.e., not in session 0) as a "GUI Environment".

    Checking for the input desktop is not particularly meaningful since, as I previously advised you, the thread is probably already connected to WinSta0\Default which is not the input desktop at the time the code calls GetUserObjectInformation upon restart.

    You could use a timer to delay the call to GetUserObjectInformation if you want to continue defining a "GUI Environment" as connection to the input desktop.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. RLWA32 43,146 Reputation points
    2024-07-04T10:37:55.44+00:00

    Another possibility is to register for the EVENT_SYSTEM_DESKTOPSWITCH event to receive a callback in which you can test for the input desktop.

    Keep in mind that there may be other occasions besides restarting when WinSta0\Default is not the input desktop. For example, UAC prompts, use of Ctrl+Alt+Del, etc.

    1 person found this answer helpful.
    0 comments No comments