【VS调试】C#读写Windows 7注册表时抛出“不允许所请求的注册表访问权”的解决办法

在XP/2003下调试得好好的程序,到了windows7下,却抛出“不允许所请求的注册表访问权”的异常,该异常就在读写注册表时引发,例:
  1. public class Program 
  2.     { 
  3.         public static void SetAutoRun(string keyName, string filePath) 
  4.         { 
  5.             using (RegistryKey runKey = Registry.LocalMachine.OpenSubKey(@"software\microsoft\windows\currentversion\run", true)) 
  6.             { 
  7.                 runKey.SetValue(keyName, filePath); 
  8.                 runKey.Close(); 
  9.             } 
  10.         } 
  11.  
  12.         static void Main() 
  13.         { 
  14.             string keyName = "TestAutoRun"
  15.             string fliePath = @"D:\CSharpProject\CSharp_Learn\MyDelegate.exe"
  16.             SetAutoRun(keyName, fliePath); 
  17.         } 
  18.     } 
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);
        }
    }
}

该程序如在windows 7下运行,需以管理员权限运行。

【方法一】

注册表

代码访问安全性策略必须向使用 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")]

【方法二】

添加 应用程序清单文件,在其中加入

  1. <security> 
  2.       <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> 
  3.         <!-- UAC 清单选项 
  4.             如果希望更改 Windows 用户帐户控制级别,请用以下节点之一替换  
  5.             requestedExecutionLevel 节点。 
  6.  
  7.         <requestedExecutionLevel  level="asInvoker" uiAccess="false" /> 
  8.         <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" /> 
  9.         <requestedExecutionLevel  level="highestAvailable" uiAccess="false" /> 
  10.  
  11.             如果您希望利用文件和注册表虚拟化提供 
  12.             向后兼容性,请删除 requestedExecutionLevel 节点。 
  13.         --> 
  14.         <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 
  15.       </requestedPrivileges> 
  16.     </security> 
<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>

修改代码,如下:

  1. System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); 
  2. System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal( identity ); 
  3. if(principal.IsInRole( System.Security.Principal.WindowsBuiltInRole.Administrator )) 
  4.     // 修改注册表 
  5. else 
  6.        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); 
  7.        startInfo.FileName = System.Windows.Forms.Application.ExecutablePath; // 获取当前可执行文件的路径及文件名  
  8.         //以下 Args 为启动本程序的对应的参数 
  9.         startInfo.Arguments = String.Join( " ", Args ); 
  10.        startInfo.Verb = "runas"
  11.        System.Diagnostics.Process.Start( startInfo ); 
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 );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值