解决C#操作注册表权限不够的问题

时间:2022-09-04 16:22:57

在Win7中,系统安全系数已经很高了,因此.NET4.0中对于注册表操作这种高级权限的东西也限制的比较紧,因此,在编程中经常会发现,使用RegistryKey类进行操作时的各种失效或者各种报错。


如何解决这问题呢?


首先,因为要操作注册表,所以,需要程序以管理员身份运行。在Win7系统中的表现即为运行程序时,弹出用户帐户控制对话框,申请以管理员身份运行。

在项目中新建一个后缀为manifest的文件,如下图所示,

解决C#操作注册表权限不够的问题

创建成功后,这个文件中默认就会产生以下内容

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<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 节点。
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 此应用程序设计使用的所有 Windows 版本的列表。Windows 将会自动选择最兼容的环境。-->

<!-- 如果应用程序设计使用 Windows 7,请取消注释以下 supportedOS 节点-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->

</application>
</compatibility>

<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->

</asmv1:assembly>

然后按照该xml文件中的提示,把默认的

<requestedExecutionLevel  level="asInvoker" uiAccess="false" />

这句代码更换成下面这句代码

<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

这样程序在运行的是否,便会自动申请管理员权限!

注:如上更改后,每次调试程序的是否,也必须将VS以管理员身份运行,这点好蛋疼

但是,仅仅按照如上做还是不够的,这样程序在运行时,如果仅仅是读取注册表一般不会有问题,可是一旦有写注册表或者删除注册表等操作时,有时候还是会出错!

这个问题出在RegistryKey这个类中的OpenSubKey函数上

OpenSubKey函数有3个重载,一般用的时候,都是使用的一个参数这个重载,如下

RegistryKey aimdir = software.OpenSubKey("Run");

在仅仅使用一个重载项打开注册表,一般只能进行读操作,对于写操作会报错崩溃

为了达到写操作的目的,需要使用两个参数的这个重载,并把第二个参数设置为true,如下所示:

string RegeditPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\";
RegistryKey hkml = Registry.LocalMachine;
RegistryKey software = hkml.OpenSubKey(RegeditPath, true);
RegistryKey aimdir = software.OpenSubKey("Run",true);
aimdir.SetValue("Pngye_Warehouse", Application.ExecutablePath);

上面的一段代码,就可以成功的设置程序的开机自动运行!进行了一次注册表写操作!