How to switch a process between default desktop and Winlogon desktop?

烂漫一生 提交于 2019-11-28 13:27:25

You did the right thing: SetThreadDesktop is correct. The error is telling you that you have some resources open on the current desktop though, such as a window, and that prevents you from switching. If you had tried to produce a minimal test-case (as you are meant to do when asking questions here!) you would have found that out.

Cut out parts of your program until you find the chunk that's preventing you switching desktop. Some Windows APIs are nasty and prevent you switching desktop, so need to be called in a dedicated thread.

As @NicholasWilson said, SetThreadDesktop() is the correct way to switch a process between default desktop and winlogon desktop.

The error 170, "The requested resource is in use", occurred because I called MessageBox() before SetThreadDesktop() called. Also calling CreateWindow() can cause the error.

I think any function associated with GUI creation called before SetThreadDesktop() called can cause the error. So if you want to invoke SetThreadDesktop() successfully, you must be sure not to call any GUI creation function before you invoke SetThreadDesktop().

Code

Code here is how to switch the process to the specified desktop.

Usage: SetWinSta0Desktop(TEXT("winlogon")), SetWinSta0Desktop(TEXT("default"))

SetWinSta0Desktop() function:

BOOL SetWinSta0Desktop(TCHAR *szDesktopName)
{
    BOOL bSuccess = FALSE;

    HWINSTA hWinSta0 = OpenWindowStation(TEXT("WinSta0"), FALSE, MAXIMUM_ALLOWED);
    if (NULL == hWinSta0) { ShowLastErrorMessage(GetLastError(), TEXT("OpenWindowStation")); }

    bSuccess = SetProcessWindowStation(hWinSta0);
    if (!bSuccess) { ShowLastErrorMessage(GetLastError(), TEXT("SetProcessWindowStation")); }

    HDESK hDesk = OpenDesktop(szDesktopName, 0, FALSE, MAXIMUM_ALLOWED);
    if (NULL == hDesk) { ShowLastErrorMessage(GetLastError(), TEXT("OpenDesktop")); }

    bSuccess = SetThreadDesktop(hDesk);
    if (!bSuccess) { ShowLastErrorMessage(GetLastError(), TEXT("SetThreadDesktop")); }

    if (hDesk != NULL) { CloseDesktop(hDesk); }
    if (hWinSta0 != NULL) { CloseWindowStation(hWinSta0); }

    return bSuccess;
}

ShowLastErrorMessage() function:

void ShowLastErrorMessage(DWORD errCode, LPTSTR errTitle)
{
    LPTSTR errorText = NULL;

    FormatMessage(
       FORMAT_MESSAGE_FROM_SYSTEM |
       FORMAT_MESSAGE_ALLOCATE_BUFFER |
       FORMAT_MESSAGE_IGNORE_INSERTS,  
       NULL,
       errCode,
       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
       (LPTSTR)&errorText,
       0,
       NULL);

    if ( NULL != errorText )
    {
        WCHAR msg[512] = {0};
        wsprintf(msg, TEXT("%s:\nError Code: %u\n%s\n"), errTitle, errCode, errorText);

        LocalFree(errorText);
        errorText = NULL;

        OutputDebugString(msg);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!