本文转自wonsoft的专栏:http://blog.csdn.net/wonsoft/article/details/6598407。
在XP/2003下调试得好好的程序,到了windows7下,却抛出“不允许所请求的注册表访问权”的异常,该异常就在读写注册表时引发,例:
public class Program { public static void SetAutoRun(string keyName, string filePath) { using (RegistryKey runKey = Registry.LocalMachine.OpenSubKey(@"software\microsoft\windows\currentversion\run", true)) { runKey.SetValue(keyName, filePath); runKey.Close(); } } static void Main() { string keyName = "TestAutoRun"; string fliePath = @"D:\CSharpProject\CSharp_Learn\MyDelegate.exe"; SetAutoRun(keyName, fliePath); } } }
【方法一】
注册表
代码访问安全性策略必须向使用 Microsoft.Win32.Registry 类访问注册表的代码授予 RegistryPermission。这个权限类型可以用于限制对特定注册表项和子注册表项的注册表访问,还可以控制代码读取、写入或创建注册表项和已命名的值的能力。
约束注册表访问
要约束代码对特定注册表项的访问,可以使用带 SecurityAction.PermitOnly 的 RegistryPermissionAttribute。下面的属性确保代码仅可以读 HKEY_LOCAL_MACHINE\SOFTWARE 下面的 YourApp 注册表项(及子项)。
[RegistryPermissionAttribute(SecurityAction.PermitOnly, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\YourApp")] public static string GetConfigurationData( string key, string namedValue ) { return (string)Registry. LocalMachine. OpenSubKey(key). GetValue(namedValue); }
请求 RegistryPermission
要记录代码的权限要求,并确保在代码访问安全性策略没有授予它充分的注册表访问权限时程序集无法加载,应当添加带 SecurityAction.RequestMinimum 的程序集级 RegistryPermissionAttribute,如下面的示例所示。
[assembly:RegistryPermissionAttribute(SecurityAction.RequestMinimum, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\YourApp")]
【方法二】
添加 应用程序清单文件,在其中加入
<security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC 清单选项 如果希望更改 Windows 用户帐户控制级别,请用以下节点之一替换 requestedExecutionLevel 节点。 <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> 如果您希望利用文件和注册表虚拟化提供 向后兼容性,请删除 requestedExecutionLevel 节点。 --> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> </requestedPrivileges> </security>
修改代码,如下:
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal( identity ); if(principal.IsInRole( System.Security.Principal.WindowsBuiltInRole.Administrator )) { // 修改注册表 } else { System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.FileName = System.Windows.Forms.Application.ExecutablePath; // 获取当前可执行文件的路径及文件名 //以下 Args 为启动本程序的对应的参数 startInfo.Arguments = String.Join( " ", Args ); startInfo.Verb = "runas"; System.Diagnostics.Process.Start( startInfo ); }