天天看點

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

<a href="http://www.cppblog.com/tuuzed/archive/2008/02/29/43424.html">http://www.cppblog.com/tuuzed/archive/2008/02/29/43424.html</a>

原著:Guy Teverovsky 

翻譯:土仔Tuuzed

本文特别聲明:原文版權歸原作者Guy Teverovsky所有,本譯文可以任意轉載, 轉載時請務必以超連結形式标明原文出處、譯文出處、譯者及本聲明。

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

        1. 這是一個内部函數,它在Winsta.dll内部實作,不像其他已公開的WTS API函數是在wtsapi32.dll内部;

        2. 該函數的傳回值(一個結構):WINSTATIONQUERYINFORMATIONW,該結構的代碼在MSDN上沒有任何資料;

        3. MSDN上的資料說,查詢的句柄(handle)通常隻能是SERVERNAME_CURRENT。這就意味着你不能查詢遠端的終端伺服器(盡管如此,通過用depends.exe(譯注:Visual Studio自帶的工具)檢視終端服務管理器(Terminal Services Manager)的EXE檔案,該管理器也大量地在使用這個函數)。

       我決定試一試,看能否解決以上的問題:

       1. “這是一個内部函數”——嗯……沒辦法,已經沒有其他方法能夠得到我想要的資訊了,這是唯一的選擇。

       2. “WINSTATIONQUERYINFORMATIONW結構的代碼沒有公開”——這是最棘手的問題。看了它在Platform SDK的winternl.h檔案中的定義後,我相當失望:

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

            顯然,這是不夠的……我設法找到了這部分結構的C++代碼,轉用C#定義如下:

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

       3. “MSDN上的資料說,我們隻能在本地機器上使用這個函數”——但是這裡隐含了些線索……這個函數與WTS API記載在了一起,而且你可以通過一個函數獲得終端服務(TS)的句柄(handle):WTSOpenServer。是以,接下來我要做的就是利用WTSOpenServer()函數擷取遠端終端服務的句柄(handle),然後利用WinStationQueryInformationW()函數得到我想要的資訊。

      把上面的做一個總述:

      需要的結構(structures)/枚舉類型(enums):

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

        DLL檔案導入(DLLImports):

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

         我們将得到通俗易懂的資訊:

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

        将難處理的FILETIME類型轉為DateTime類型:

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

       有用的代碼:

[翻譯]利用C#擷取終端服務(Terminal Services)會話的閑置時間

        隻需簡單地調用WTSQuerySessionInfo("servername", &lt;Session ID&gt;)就行了。

       總結:

       就如大家看到的一樣,在所有步驟完成後,我們還是沒有得到我們想要的“會話閑置時間(Session Idle Time)”。其實,根據下面的簡單規則就能很容易地把它計算出來:

※ 如果會話是斷開(disconnected)狀态,閑置時間=目前時間-斷開時間(Idle Time = CurrentTime - DisconnectTime)

※ 如果會話是活動的(alive)狀态,閑置時間=目前時間-最後輸入時間(Idle Time = CurrentTime - LastInputTime)

繼續閱讀