2013-01-08 58 views
6

我們正在開發一個C#.NET窗口服務。模擬用戶

我們的服務正在系統帳戶下運行,我們正試圖模擬登錄的用戶USER。 模擬工作正常,即在模擬後調用System.Security.Principal.WindowsIdentity.GetCurrent()時,我們得到正確的用戶'USER'。

問題是,當我們嘗試訪問用戶配置文件時,我們沒有得到預期的結果。 一個例子是訪問註冊表CURRENT_USER。我們得到一個訪問被拒絕的錯誤。 使用我們假設部分使用註冊表的第三方功能時,我們會獲取「真實」(模擬前)用戶的詳細信息。 此外,在撥打Environment.ExpandEnvironmentVariables("%TEMP%")時,我們將獲取系統配置文件,而不是登錄的用戶配置文件。

有沒有辦法完全模仿不同的用戶? 我知道我們可以使用LoadUserProfile來獲取特定的用戶配置文件,但這對我們並不好,因爲我們正在運行使用當前用戶配置文件的第三方dll。

我們的模擬代碼在this

+1

首先,你應該使用System.IO.Path.GetTempPath();如果仍然不起作用,這可能是你的問題:http://stackoverflow.com/questions/944483/how-to-get-temporary-folder-for-current-user看到接受的答案,以及它是如何工作的。 – lahsrah

+0

讓我更具體。我們正在使用對我們無法更改的第三方dll的調用。所以如果他們預計特定的用戶配置文件,我們必須使該進程與該用戶配置文件一起運行。 – user844541

+0

@ user844541請再次閱讀我的鏈接。 – lahsrah

回答

2

我注意到代碼不調用LoadUserProfile基地,使用戶配置文件沒有加載。

注意在該函數的註釋中,HKEY_CURRENT_USER仍然沒有被替換。

認爲您可以通過調用RegOverridePredefKey來解決此問題(在調用第三方DLL之前)。

請注意,很多伏都教可能涉及到這一切的工作權利 - 我會盡力確保覆蓋發生在第三方呼叫之前儘可能晚,並儘快恢復後(希望這是對圖書館的一次調用)。

作爲一種替代方案,我會認真嘗試尋找不同的第三方產品,不需要所有這些都會跳出來。

+0

在這種情況下調用'RegOverridePredefKey'將無濟於事,因爲每個進程都是進程模擬,而每個線程都是模擬。 – Ben

2

正如您發現的那樣,模擬不會設置HKEY_CURRENT_USER或環境。

這是因爲模擬令牌是每個線程,並且HKCU和環境是每個進程。

如果您需要訪問用戶的常用環境,則需要使用HKEY_USERS\SID和模擬用戶的SID,例如例如HKEY_USERS\S-1-5-21-12345678-12345678-12345678-1234。致電LoadUserProfile確保密鑰已加載。 (如果它應該是當前登錄的用戶,它應該已經加載,所以你可能不應該那樣做,但檢查它是否存在並且如果不存在則返回一個錯誤)。

你也可以計算出他們平常的環境,因爲這是在HKCU內的關鍵「環境」之下。你只需要將它與系統環境結合起來。

如果第三方DLL實際需要HKCU並且環境設置正確,則需要在用戶的登錄會話中創建一個進程來承載DLL,並以某種方式發送任何操作的結果。如果只需要環境,則可以創建子進程並手動設置環境。

但是你還沒有說過你爲什麼要這樣做。這聽起來像你已經解決了這個問題,作爲解決更大問題的一部分。如果可能的話,我建議你看看是否有辦法做到你所需要的,而不需要獲取用戶的環境或HKCU。

爲什麼不能直接在用戶自己的會話中運行該DLL?爲什麼需要一項服務?您是否可以重新構建解決方案,以便在登錄會話中運行用戶模式部分並承載第三方DLL,並與服務進行通信,以便該服務僅執行絕對必需的部分?

+0

+1有關在用戶會話中運行某些內容的建議。幾乎每次我遇到類似的服務和用戶帳戶問題時,都是這樣。 – Basic