2016-07-19 38 views
1

當我將某些計算機升級到Windows 10時,RuntimeBroker上的權限不正確導致問題,我遇到了一個奇怪的問題。我發現a solution online建議更改權限(首先在註冊表中,然後在DCOM配置中),並且我正在嘗試編寫一個小的.NET應用程序來自動化該過程。如何以編程方式將註冊表項的所有權授予管理員?

目前,相關注冊表項的所有者是NT SERVICE\TrustedInstaller,我試圖將其更改爲COMPUTER\Administrators。我有一個簡單的WPF應用程序,其中requestedExecutionLevel設置爲「requireAdministrator」,但我仍遇到問題。這裏有一小段代碼來說明問題:

using System.Security.AccessControl; 
using System.Security.Principal; 
using Microsoft.Win32; 

namespace PermissionFixer 
{ 
    public class Fixer 
    { 
     public void Fix() 
     { 
      var subKey = Registry.ClassesRoot.OpenSubKey(@"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", true); 
      if (subKey != null) 
      { 
       var admins = new NTAccount("Administrators"); 
       var ac = subKey.GetAccessControl(); 
       ac.SetOwner(admins); 
       ac.AddAccessRule(new RegistryAccessRule(admins, RegistryRights.FullControl, AccessControlType.Allow)); 
       subKey.SetAccessControl(ac); 
      } 
     } 
    } 
} 

麻煩的是,它甚至沒有讓過去的呼叫OpenSubKey()創下了SecurityException,說之前的「請求的註冊表訪問是不允許的。」我認爲這是因爲管理員還沒有訪問權限(請記住它屬於TrustedInstaller),但它變得有點雞雞蛋問題。奇怪的是,當我手動使用regedit時,我允許am將所有者更改爲管理員,並且我非常確定我的註冊表實例正在以管理員身份運行。

我怎樣才能得到這個工作在.NET中?

+0

在本機代碼,你會通過仔細選擇開關鍵時請求其訪問權限做到這一點。您還需要打開它兩次,一次設置所有者,然後再次更改權限。我不知道你是否可以使用.NET類來這樣做。作爲一種簡單的解決方法,請嘗試啓用備份和恢復特權。 –

+0

原諒我這裏的無知......當你說本地代碼時,我認爲這意味着C++,這讓我想知道是否有任何可以調用的P/invoke方法來實現這一點? – SoaperGEM

+0

當然,你可以用P/Invoke來完成。如果你可以使用.NET類,那麼它會容易得多,而且更容易使用備份/恢復特權。 (如果你想去P/Invoke路線,首先查找RegCreateKeyEx和SetSecurityInfo。) –

回答

2

我明白了,幸運的是可以用.NET類來實現。這裏是你怎麼也得叫OpenSubKey:

var subKey = Registry.ClassesRoot.OpenSubKey(@"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership); 

然後,你必須尼克斯調用AddAccessRule() ...你不能修改,直到你有所有權;你必須連續做這兩個操作。所以先取得所有權,然後重新打開具有不同訪問權限的密鑰以添加訪問規則。

編輯:今天我發現,你必須第一操作與運行應用程序的令牌,掛接到P/Invoke調用。我在another Stack Overflow question中找到了一個名爲TokenManipulator的類。在您的項目中包含該類,然後在致電OpenSubKey之前向您的令牌授予「備份」,「恢復」和「獲取所有者」權限。所以,你的方法最終會看起來像這樣:

try 
{ 
    TokenManipulator.AddPrivilege("SeRestorePrivilege"); 
    TokenManipulator.AddPrivilege("SeBackupPrivilege"); 
    TokenManipulator.AddPrivilege("SeTakeOwnershipPrivilege"); 

    var subKey = Registry.ClassesRoot.OpenSubKey(@"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership); 
    // code to change owner... 
} 
finally 
{ 
    TokenManipulator.RemovePrivilege("SeRestorePrivilege"); 
    TokenManipulator.RemovePrivilege("SeBackupPrivilege"); 
    TokenManipulator.RemovePrivilege("SeTakeOwnershipPrivilege"); 
} 
+0

我估計你只是真的需要「擁有所有權」特權。但另外要求其他兩人也沒有什麼不好。 –

相關問題