Comment est-ce que je donne par programme la propriété d’une clé de registre aux administrateurs?

J’ai rencontré un problème étrange lorsque j’ai mis à niveau certaines machines vers Windows 10 où des permissions incorrectes sur RuntimeBroker causaient des problèmes. J’ai trouvé une solution en ligne qui recommandait de modifier les permissions (d’abord dans le registre, puis dans la configuration DCOM) et j’essaie d’écrire une petite application .NET pour automatiser le processus.

Actuellement, le propriétaire des clés de registre pertinentes est NT SERVICE\TrustedInstaller et j’essaie de le remplacer par COMPUTER\Administrators . J’ai une application WPF simple avec le requiredExecutionLevel défini sur «requireAdministrator», mais je rencontre toujours des problèmes. Voici un extrait de code illustrant le problème:

 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); } } } } 

Le problème, c’est que l’appel à OpenSubKey() n’a même pas été dépassé avant de bash une OpenSubKey() SecurityException indiquant que “l’access au registre demandé n’est pas autorisé”. Je pense que c’est parce que les administrateurs n’ont pas encore access (rappelez-vous qu’il appartient à TrustedInstaller), mais cela devient un peu un problème de poule et d’oeuf. La chose étrange est que lorsque j’utilise regedit à la main, je suis autorisé à changer le propriétaire en administrateurs, et je suis à peu près sûr que mon instance de regedit s’exécute en tant qu’administrateurs.

Comment puis-je obtenir ce travail dans .NET?

Je l’ai compris, et heureusement, il est possible d’y parvenir avec les classes .NET. Voici comment appeler OpenSubKey:

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

Ensuite, vous devez AddAccessRule() l’appel à AddAccessRule() … vous ne pouvez pas modifier cela tant que vous n’êtes pas propriétaire. et vous devez faire ces deux opérations en série. Prenez donc d’abord la propriété, puis rouvrez la clé avec différents droits d’access pour append la règle d’access.

EDIT: J’ai découvert aujourd’hui que vous devez d’ abord manipuler le jeton avec lequel votre application s’exécute en vous connectant à des appels P / Invoke. J’ai trouvé une classe appelée TokenManipulator référencée dans une autre question de débordement de stack . Incluez cette classe dans votre projet, puis accordez des privilèges de sauvegarde, de restauration et de prise en charge à votre jeton avant d’appeler OpenSubKey . Donc, votre méthode finira par ressembler à ceci:

 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"); }