2015-11-18 29 views
1

我遇到了當前正在處理的Windows服務的問題。基本上我在HKCU註冊表中存儲了一些值(從一個以管理員身份運行的GUI工具),並從該GUI中啓動一項服務。該服務使用SYSTEM帳戶運行,我相信這是我的問題 - 我無法訪問存儲在我的GUI工具內的註冊表項,因爲它指向不同的HKCU!C#訪問另一個用戶的註冊表

如何「重定向」該服務以使用存儲的用戶的HKCU? (其實我可以傳遞用戶名到服務或SID,如果有人會指出我如何在我的GUI中檢索它,但我不知道我應該用什麼來「改變」用戶指向正確的)

@EDIT

我使用靜態類訪問註冊表,它用於通過GUI和服務和功能來檢索基本密鑰是(rootKey是字符串變量保持子項名稱):

private static RegistryKey GetBaseKey(bool writable = false) 
     { 
      try 
      { 
       RegistryKey reg = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64); 
       RegistryKey rk = reg?.OpenSubKey("SOFTWARE", writable)?.OpenSubKey(rootKey, writable); 

       return rk; 
      } 
      catch (Exception ex) 
      { 
       // handle exceptions later 
      } 

      return null; 
     } 

我發現WindowsIdentity類可以爲當前用戶提供句柄(AccessToken),我應該將它作爲參數傳遞給我的服務並使用此句柄在服務內冒充?

@ EDIT2

我已經做了一些東西,但它不起作用。我的嘗試:

CurrentUserToken = WindowsIdentity.GetCurrent().Token; // to get current identity token 

然後ServiceController.Start我說CurrentUserToken.ToString() 作爲參數。在我的服務,我初始化RegistryUserToken (IntPtr)與傳遞的價值,我被困在:

WindowsIdentity RegUser = new WindowsIdentity(RegistryUserToken) 

拋出異常

無效令牌模擬 - 它不能重複

我試過與WindowsIdentity的當前實例的AccessToken相同 - 拋出相同的異常

我可以一直這樣嗎?或者我應該嘗試一些不同的?

+0

顯示您的代碼。你如何使用註冊表? –

+0

添加了「主要」註冊表方法,所有其他方法都使用它來獲取要使用的子項。 – user1970395

+0

您可以簡單地在您的用戶帳戶下運行Windows服務。 –

回答

1

好吧,我設法解決它有點不同。我已將SID變量添加到我的註冊表類中,如果它不爲空,則我打開Users Registry Hive而不是HKCU。首先,我檢索使用當前的用戶SID(我的GUI應用程序內):

WindowsIdentity.GetCurrent().User.ToString(); 

,我作爲參數傳遞給我的服務,並設定它的註冊表類。

5

我可以給你兩個選擇:如果你有他們的憑證,或者使用HKCU是HKEY_USERS下的鍵之一的符號鏈接的想法,模擬該用戶。 因爲冒充你可以看到this link。 如果你知道該用戶的SID,那麼你可以在那裏找到它。你可以這樣得到SID:

var account = new NTAccount("usernameThatYouNeed"); 
var identifier = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier)); 
var sid = identifier.Value; 

我更喜歡模仿。如果您不知道該用戶的憑證,則第二種選擇是用於案例。 我不喜歡第二種選擇,因爲它需要管理權限才能寫入其他人的帳戶。

+0

實際上,我相信我可以使用模擬,因爲我首先啓動GUI(作爲管理員),使用GUI工具存儲這些值(在HKCU註冊表中),並從該GUI中啓動服務,因此我可以(我可以嗎?)在GUI代碼中檢索當前用戶身份並傳遞給服務,是不是正確? – user1970395

+0

更新我的問題與我所做的和我卡住的地方,希望你能幫助我。 – user1970395

1

我需要從服務讀取另一個用戶的註冊表。這是我如何工作,但在這種情況下,我知道確切的用戶名。這裏的其他答案幫了很多。用戶名和路徑是你需要的。

 NTAccount f = new NTAccount("yourUserName"); 
     SecurityIdentifier s = (SecurityIdentifier)f.Translate(typeof(SecurityIdentifier)); 
     String sidString = s.ToString(); 

     Microsoft.Win32.RegistryKey OurKey = Microsoft.Win32.Registry.Users; 
     OurKey = OurKey.OpenSubKey(sidString + "\\SOFTWARE\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppContainer\\Mappings", true); 

     if (OurKey != null) { 
      foreach (string Keyname in OurKey.GetSubKeyNames()) 
      {