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

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

项目 - 属性 - 安全性,“使用ClickOnce”,修改app.mainfest,再取消“使用ClickOnce”

【另有一篇参考文章:http://blog.csdn.net/wonsoft/article/details/6598407

    在XP/2003下调试得好好的程序,到了windows7下,却抛出“不允许所请求的注册表访问权”的异常,该异常就在读写注册表时引发,例:

view
plain

  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.     }  
  19. }  

该程序如在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")]

 

【方法二】

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

view
plain

  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>  

 

修改代码,如下:

view
plain

  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.     // 修改注册表  
  6. }  
  7. else  
  8. {  
  9.        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();  
  10.        startInfo.FileName = System.Windows.Forms.Application.ExecutablePath; // 获取当前可执行文件的路径及文件名   
  11.         //以下 Args 为启动本程序的对应的参数  
  12.         startInfo.Arguments = String.Join( " ", Args );  
  13.        startInfo.Verb = "runas";  
  14.        System.Diagnostics.Process.Start( startInfo );  
  15. }  

问题描述:

为了实现程序的自动启动,我们会再注册表中写入相关信息,实现代码如下:

RegistryKey HKLM = Registry.LocalMachine;
RegistryKey Run = HKLM.CreateSubKey(@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\");

 

 

但总提示如上图的错误,困扰了我很久。编译后的的exe以管理员身份运行没有问题,为什么呢?难道VS在调试的是没有管理员身份(实际也没有必要),百思不得其解。。。终于发现在win7用vs访问注册表键HKEY_LOCAL_MACHINE没有管理员身份是不行,但访问HKEY_CURRENT_USER可以,所以上面的代码修改为:

RegistryKey HKLM = Registry.CurrentUser;
RegistryKey Run = HKLM.CreateSubKey(@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\");

现在OK了。

 

 

参考:《Windows 7软件开发示例:UAC、系统版本、权限》

 

看到Win7的酷炫功能流口水,已经忍不住想拥抱呢?别急,Win7的脾气可不好,要想拥抱它的新功能,我们的软件必须嫁给它——在Win7下能正常运行。,个人开发者开发的中小软件,功能相对简单,与系统的紧密程度普遍较低,添加一些Win7必要的正常运行的元素就OK啦!

  嫁给Win7的必要条件

  我们必须要给软件添加的是系统版本检测和安装路径选择元素,为什么要考虑它们呢?

  必要条件1:检测系统版本

  软件在运行初期需要判断操作系统的类型及版本号,并根据操作系统类型执行特定的代码,相同的功能在不同操作系统上可能会执行不同的代码。大多数软件的在Win7下无法正常运行都是因为判断操作系统版本失败造成的。

  当版本检测出错时,很多软件也会跟着出错,用户可能会发现双击软件图片后,什么反映都没有,或者可能会看到一个对话框“你必须运行在Microsoft Windows XP或更新版本”,但实际上计算机已经安装了Win7 。

  必要条件2:适应用户权限

  Win7默认运行的是非管理员账号,权限相对较小。而软件的安装程序会往包括系统盘的Program Files、Windows安装目录、注册表中写入一些数据(软件在运行时可能会将一些用户数据保存到系统文件夹或注册表中),如果当前用户的权限不够,软件就无法正常入驻Win7。

  小知识: UAC是一种降低Windows用户默认权限的办法,这样会给用户带来安全性的提高,它可以一定程度上遏制了一些病毒的发作——关闭杀毒软件、启动复制及散播病毒进程、注入网游客户端、监听键盘操作从而盗窃密码。

  例如数据看似保存成功,在写入的地点却找不到,或者注销切换到另一个Windows用户时,无法找到保存的数据。引起这类问题的根源是Win7的UAC机制,它降低了Windows用户的默认权限,使得一些普通操作无法更改系统设置及系统保护的文件夹。

  小提示:软件要结合系统某些功能时,需要调用相应的API。API调用得当否,对软件运行非常关键,我们从下期开始结合Win7酷炫功能,单独介绍如何正确的调用。Win7最新的API,有Win7特有的任务栏个性化快捷菜单(Jump List)、程序图标轮廓效果(Icon Overlay)、程序图标进度条效果(Progress Bar)、标签式缩略图(Tabbed Thumbnail)和缩略图工具栏(Thumbnail Toolbar)……

  “婚礼”必要的元素

  我们的软件要顺利嫁给Win7,在软件中要添加以下的元素。

  1.代码检测操作系统版本号

  在软件中添加判断操作系统是Win7 或2008 Server的代码:

  C#

      if (Environment.OSVersion.Version > new Version(5, 1))
      {MessageBox.Show("Windows 7 or Windows 2008 Server","Operating System", 
                      MessageBoxButtons.OK,MessageBoxIcon.Error);
            return;
      }

  2.尽量将数据存储在非系统盘

  软件不要默认安装到系统盘,在编写软件安装路径时,要考虑这个。此外,还需要在软件中添加修改读写注册表的代码,使用HKEY_CURRENT_USER\Software下的键值作为存储数据的结点:

        static void Main(string[] args)
        {
            var registryKey = Registry.CurrentUser.CreateSubKey(
                @"Software\test");
            registryKey.SetValue("name", "zswang");
            registryKey = Registry.CurrentUser.OpenSubKey(@"Software\test");
            Console.WriteLine(string.Format("{0}={1}\r\n",
               "name", registryKey.GetValue("name")));
        }

  3.提高程序的运行权限

  如果用户使用了管理员身份进入系统,又希望把软件安装在系统盘,又该如何呢?需要判断用户权限的权限,简单的解决方案是添加清单文件。在可执行文件夹中找到与可执行文件相同名字且扩展名.manifest的文件,输入以下代码即可:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
  <assemblyIdentity version="1.0.0.0"
     processorArchitecture="X86"
     name="test"
     type="win32"/> 
  <description>Description of your application</description> 
  <!-- Identify the application security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </requestedPrivileges>
       </security>
  </trustInfo>
</assembly>
时间: 2024-11-03 09:53:31

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

iOS注册远程推送消息证书后提示此证书签发者无效的解决办法

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们在编写关于远程推送消息的App时需要注册一个相关的证书,我们可以到Apple开发网站的Certificates, Identifiers & Profiles页面首先创建一个App ID. 其中进入Push Notifications选项,并且在其子项Development SSL Certificate中选择创建证书(因为该证书是调试用的,所以在Deve

Silverlight无法启动调试,错误“Unable to start debugging. The Silverlight Developer Runtime is not installed. Please install a matching version.” 解决办法

今天调试Silverlight出现了以下错误: 意思是"无法启动调试,因为Silverlight Developer Runtime没有安装,请安装一个匹配的版本".但是按Ctrl + F5可以调试运行,不对啊,前几天还好好的,今天怎么就不行了呢? 突然想起来,前几天Silverlight升级了,于是卸载Silverlight SDK重装,还是有这个错误.下面给出解决办法: 卸载Microsoft Silverlight 然后重装Silverlight4_Tools.exe,或者解压S

打开编辑注册表时弹出被禁用怎么办

  1.使用组合键(win键+r)打开运行窗口,并输入"gpedit.msc"按回车键执行打开本地组策略编辑器,如下图所示: 2.在本地组策略编辑器窗口中依次展开"用户配置--管理模块"并单击"系统"选项,接着在右侧的设置选项列表中,找到"阻止访问注册表编辑工具"并双击打开阻止访问注册表编辑器工具窗口;如下图所示: 3.先点击阻止访问注册表编辑器工具窗口中的"未配置"项,再点击"应用--确定&qu

被恶意网站击中的解决办法——注册表使用全攻略之六_注册表

被恶意网站击中的解决办法--注册表使用全攻略之六 一.注册表被修改的原因及解决办法 恶意网页是含有有害代码的ActiveX网页文件,这些广告信息的出现是因为浏览者的注册表被恶意更改的结果. 1.IE默认连接首页被修改 IE浏览器上方的标题栏被改成"欢迎访问--网站"的样式,受到更改的注册表项目为:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\Start PageHKEY_CURRENT_USER\Softwar

Unrecognized Windows Sockets error: 0: JVM_Bind 异常解决办法

1.问题          通过Eclipse启动Tomcat时,抛出异常java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind.此异常的原因是服务器端口被占用          其解决办法包括以下两种:         一:更改服务器的端口号:         二:关闭占用当前占用该端口的进程 2.更改服务器端口号         到tomcat目录下的把conf文件夹下的server.xml文件中,找

离线方式读写Windows注册表内容

本文仅在WINDOWS XP及WINDOWS 2003上测试通过,其他平台未知. 我在2007年曾经草拟了一篇文章<成功修复一例WINDOWS系统反复登陆,无法启动>,当时的想法是觉 得这个过程很有意义,想把解决过程记录下来,结果是日复一日的忙碌,最终不了了之.其实在解决问题 的过程中,体会最深的便是在系统无法启动的情况下,同时又没有注册表备份,如何修改它的错误的注册 表键值. 一个简单的方法是利用注册表编辑器的加载配置单元. WINDOWS XP和WINDOWS 2003的注册表文件通常在%

串口大师提示找不到串口的解决办法,增加注册表项目。

          今天进行串口调试提示找不到串口,查了注册表发现串口的注册值:\Device\ProlificSerial2 ,值COM4,但是串口大师还是找不到串口,注册表中没有项目,解决办法如下: 1 .新建一个TXT文档,键入以下内容: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM] "\\Device\\Serial1"="COM1&quo

[EntLibFAQ]“不允许所请求的注册表访问权”的解释[0508Update]

[EntLibFAQ]"不允许所请求的注册表访问权"的解释 Version Date Creator Description 1.0.0.1 2006-5-2 郑昀@Ultrapower 草稿   继续阅读之前,我们假设您熟悉以下知识: n         Microsoft Enterprise Library June 2005 n         EventLog和注册表的关系  [现象] 首先,这种情况发生在第一次使用Microsoft Enterprise Library J

XP系统弹出“注册表空间不足”提示的解决办法

  XP系统弹出"注册表空间不足"提示的解决办法 具体如下: 1.点击电脑的开始菜单,找到"运行"选项并点击. 2.运行窗口打开以后,输入 "msconfig"并回车. 3.弹出"系统配置"窗口,切换到"启动"选项卡,取消一些不想要开机启动的选项. 4.然后删除一些不需要使用的软件,再对系统的垃圾进行全面的清理. 5.做前面的这些就是为了调整增加windows xp系统的虚拟内存,让内存变大来解决开机的那个