不知道大家注意到沒有,Windows XP新增加了一個快速切換用戶的功能。它可以讓您在不注銷的情況下在用戶之間進行切換,而且每個用戶有自己獨立的配置文件和桌面。也就是說當您切換到另外一個用戶(即用另外一個賬號登陸)時,以前的那個用戶運行的所有程序都還是在運行的,並沒有退出來。這就給我們的開發帶來了新的問題。比如您的應用程序提供的功能在多個用戶同時運行時發生錯誤,您必須為應用程序添加代碼以檢測該情形並作出相應的反應。
1、檢測是否有用戶正在運行該應用程序
我們平時都使用互斥體的方法來實現只有一個實例運行,而且在使用CreateMutex()生成互斥體是使用默認的方式,即互斥體的作用范圍不是全局的,只能在一個Session裡起作用,而對於切換用戶下存在多個Session是不起作用的,因而也就檢測不到已經在運行的實例。解決的方法很簡單,在使用CreateMutex()時,在互斥體的名字前加上"Global"關鍵字即可。
m_hMutexAppRunning = CreateMutex(NULL, FALSE, "Global\\EsXPSwitchUserApp");
2、監測用戶現在是否在切換用戶有的時候,我們需要檢測用戶做切換用戶操作的這個行為,以便讓我們的程序能夠做出相應的處理。例如,我們需要在結束活動用戶會話運行狀態時釋放某些資源,而在其再次進入活動會話狀態時重新獲得該資源。還好Microsoft提供了讓我們的程序接收會話通知消息的方法。我們可以通過調用 WTSRegisterSessionNotification 函數進行注冊以接收WM_WTSSESSION_CHANGE 消息。
這些消息主要有:
WTS_CONSOLE_CONNECT
WTS_CONSOLE_DISCONNECT
WTS_REMOTE_CONNECT
WTS_REMOTE_DISCONNECT
WTS_SESSION_LOGON
WTS_SESSION_LOGOFF
WTS_SESSION_LOCK
WTS_SESSION_UNLOCK
在wParam中包含了這些消息類型,而lParam包含的是發生變化的Session的SessionID.
switch(message)
{
case WM_WTSSESSION_CHANGE:
{
switch(wParam)
{
case WTS_CONSOLE_CONNECT:
MessageBox("WTS_CONSOLE_CONNECT", "Esmile", MB_OK );
break;
case WTS_CONSOLE_DISCONNECT:
MessageBox("WTS_CONSOLE_DISCONNECT",
"Esmile", MB_OK );
break;
case WTS_SESSION_LOCK:
MessageBox("WTS_SESSION_LOCK",
"Esmile", MB_OK );
break;
case WTS_SESSION_UNLOCK:
MessageBox("WTS_SESSION_UNLOCK",
"Esmile", MB_OK );
break;
case WTS_SESSION_LOGOFF:
MessageBox("WTS_SESSION_LOGOFF",
"Esmile", MB_OK );
break;
case WTS_SESSION_LOGON:
MessageBox("WTS_SESSION_LOGON",
"Esmile", MB_OK );
break;
default:
break;
}
}
break;
default:
break;
}
這樣,我們就可以處理我們感興趣的消息了,從而達到我們的目的.
3、注意事項
每一個對 WTSRegisterSessionNotification 的調用應與一個對 WTSUnRegisterSessionNotification 的調用匹配,
即在程序退出時要釋放這個通知注冊信息。
WTSRegisterSessionNotification 和 WTSUnRegisterSessionNotification 需要頭文件Wtsapi32.h以及
Wtsapi32.lib。另外在包含 windows.h 的語句之前添加以下 #define 語句
#define _WIN32_WINNT 0x0501
文章附帶的源代碼在win2000pro下編譯通過,程序只能在Window XP下運行,因為非XP系統沒有WTSAPI32.dll。
任何問題希望能與大家共同探討!
本文配套源碼