2012-10-26 53 views
1

假設我在某個時間點從本地服務應用程序調用WTSEnumerateSessions並獲取當前用戶會話ID的列表。所以如果稍後我需要知道某個特定的用戶會話是否仍然處於相同的狀態,我可以依靠WTS_SESSION_INFO::SessionId是唯一的嗎?如果沒有,如何做到這一點?WTSEnumerateSessions API獲得的會話ID是否唯一?

+1

你會考慮改變狀態嗎?如果用戶登錄並且現在被鎖定,您是否會說會話處於相同狀態? – ixe013

回答

2

Windows爲每個登錄會話提供一個SID。 MSDN has sample code to look it up,並且對於給定的登錄會話保證唯一且恆定。如果用戶註銷並重新登錄,他將被歸入新的登錄SID。

如果同一用戶在本地登錄並在同一位置進行遠程登錄,則每個登錄會話都會有一個不同的登錄SID。下圖顯示了我的意思:

Alice has two logon session, with distinct Logon SID

(免責聲明 - 我偷了它從一個blog post of mine

你可以用這個命令得到登錄SID。在不編寫任何代碼的情況下播放假設情景可能是有用的。

c:\>whoami /logonid 
S-1-5-5-0-329693570 

在Windows Server 2008上測試。在其他版本上的YMMV。

+0

很好的解釋,圖表(雖然是自剽竊)和C++代碼。雖然我有一個關於代碼示例的問題。它使用令牌句柄來查找登錄SID,但我沒有令牌。或者,我應該說,我如何得到它? – c00000fd

+1

@ user843732您可以使用[WTSQueyUserToken](http://msdn.microsoft.com/en-us/library/windows/desktop/aa383840%28v=vs.85%29.aspx)獲取令牌。致電***的應用程序必須在本地系統帳戶的上下文中運行,並具有「SE_TCB_NAME」權限才能使該呼叫生效。 –

+0

好點。謝謝。 – c00000fd

0

會話ID與安全ID不同。會話可能會有人在某個狀態下登錄,或者可能沒有人登錄。您可以調用WTSEnumerateSessions並發現有人在會話1登錄,稍後該人員可以註銷,稍後其他人可以登錄並且Windows可能會給他們會話1,然後再次調用WTSEnumerateSessions。因此,在經歷兩次更改並由不同用戶使用之前,狀態可能與之前相同。你稱這是獨一無二的嗎?我不知道你獨特的意思。

+0

那麼有什麼方法可以在當時對所有登錄的用戶帳戶進行更具體的(即唯一的)引用? – c00000fd

2

會話ID被分配爲登錄時最低的未使用號碼。

因此,如果我有ID 1,然後註銷,並且您登錄,您將獲得ID 1,因爲1在登錄時可用。

如果我從未註銷過,由於ID 1正在使用中,您將獲得ID 2。如果我然後註銷,並且您留在下一個用戶將再次分配ID 1(不是3),因爲1是最低的未使用的數字。

+0

那麼這個API返回的會話ID是什麼?該ID一旦返回就會失效,因爲在此期間,用戶可能已註銷,並且新用戶可能已登錄,並且新用戶將具有相同的會話ID ... – c00000fd

+0

假設您要查詢ID,然後立即做出您需要的任何內容,例如向所有登錄用戶發送消息,您將調用WTSEnumerateSessions併爲每個結果立即調用[ WTSSendMessage](http://msdn.microsoft.com/en-us/library/windows/desktop/aa383842%28v=vs.85%29.aspx)。這兩種操作都需要一秒鐘的時間才能完成,而且很可能一個人不會登錄,而另一個人將在這兩個呼叫之間的秒數部分登錄。 –

+0

另一個常見和有用的例子是如果我想要一個實用程序來記錄某人。我會調用一次WTSEnumerateSessions來填充我的UI,當用戶選擇註銷時,我再次調用WTSEnumerateSessions,我檢查用戶名和SessionID是否仍然與我在UI中顯示的相同(以防萬一用戶已經在間隔時間內註銷)然後我調用[WTSLogoffSession](http://msdn.microsoft.com/en-us/library/windows/desktop/aa383836%28v=vs.85%29.aspx)通過傳入剛剛檢查過的會話ID來註銷用戶,我知道這是有效的。 –