正如@NicholasWilson 所说,SetThreadDesktop()
这是在默认桌面和winlogon 桌面之间切换进程的正确方法。
发生错误 170,“请求的资源正在使用中”,因为我在调用MessageBox()
之前SetThreadDesktop()
调用过。调用CreateWindow()
也可能导致错误。
我认为在调用之前调用的与 GUI 创建相关的任何函数SetThreadDesktop()
都可能导致错误。所以要想调用SetThreadDesktop()
成功,一定要确保在调用之前不要调用任何GUI创建函数SetThreadDesktop()
。
代码
这里的代码是如何将进程切换到指定的桌面。
用法: SetWinSta0Desktop(TEXT("winlogon"))
,SetWinSta0Desktop(TEXT("default"))
SetWinSta0Desktop()
功能:
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()
功能:
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);
}
}