看到论坛好多人问win7下写注册表的问题,我结合自己的理解写了一点东西,首先声明一下,本人初学Delphi,水平有限,大家见笑了,有什么不对之处请老鸟多指点。

[背景]
win7/Vista提供的UAC机制,是win7/Vista的新增功能之一。它的主要目的是防止对于操作系统本身的恶意修改。如果想对于win7/Vista的系统设置进行改动,必须通过UAC的验证才能够进行。通过这样的手段,大大提供了系统的安全性。关于UAC的利弊,网络上的说法褒贬不一,在这里就不具体讨论了。

[应用]
Delphi写的程序一般都可以在win7/vista上运行,但是有关注册表、程序文件夹的操作会无声的失效,这给普通用户带来很大不便,他们并不明白什么时候程序需要写注册表(因为没有提示),需要以管理员身份运行程序!现在大多数Delphier还是停留在D7的阶段,这时候一般大家都会把责任推给D7,是D7太老了,不支持Win7/Vista! 在试了D2007后,发现依然不行,于是感慨说Delphi对win7/vista支持不好,事实真是这样吗?

打开D2007(sorry,现在机子上没用以后的版本,我想应该相同)的目录:\source\Win32\vcl,找到winxp.pas这个单元,用记事本打开发现它引用了winxp.rc, 再用记事本打开windows.rc, 发现它编译的是 sample.manifest 这个文件,用记事本打开它,看到是用xml这样描述的:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="DelphiApplication"
version="1.0.0.0"
processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

对比D7相同的文件,发现多了<trustInfo>项的,这也就是所谓的支持UAC的关键,查阅msdn有关VC2008的manifes的设置,有关权限的说明如下:

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

这里要注意的是requestedExecution Level的值,一般用asInvoker或requireAdministrator,普通的程序应该用asInvoker来执行,意思是按照目前你登陆win7/Vista帐号的权限执行,requireAdministrator顾名思义就是需要你启动管理员权限才能执行。这里是win7/Vista会不会跳出UAC提示窗口的重点。
1)如果用asInvoker应该就不会再提示了,我觉得这是个鸡肋!因为win7/vista默认是不以administrator登陆的,登陆的帐号根本没有太多权限!你的程序如果操作了注册表、程序文件夹的话当然在这个帐号下会无声的失效;
2)在VC2008中,程序中如果没有manifest,则默认为requireAdministrator权限(爽呀!),requestedExecutionLevel为 requireAdministrator的可执行文件前面都会有一个小盾牌提醒使用者。好了,看到这里,大家应该明白了吧!

[解决方法]
对于D7,解决方法太简单了。如果你操作了注册表之类的“危险地带”的话,就要使用这个来提醒你的用户要以管理员权限运行,其实这个网上早就有了,我又拷过来了:)
1.建立 res 文件
建立一个文本文件,名字可以自己起,我这里叫:UAC.manifest,内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
manifestVersion="1.0"> 
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

建立文本文件,名为 UAC.rc,内容:

1 24 UAC.manifest

编译成 uac.res 文件,运行:

brcc32 uac.rc -fouac.res

2.在代码中引入
打开项目文件,加入
{$R uac.res}

3.编译程序

或者你还可以仿照xpman.pas写个VistaUAc.pas,其中引用以上资源,编译后将相应的dcu拷入lib文件夹,vistUac.pas拷入vcl文件夹,需要时,你可以在工程或单元中像引用xpman一样方便地uses VistaUac!

对于D2007(sorry,以后的版本没有试,因为本机没装,应该也一样)有些麻烦,因为它默认是启用所谓的Runtime themes的,以上uac.res是没办法正常引用的,解决方法有两种:1)关闭runtime themes才能正常引用, 但程序没有xp特效了,郁闷了吧!2)用D7的winxp.res,xpman.pas覆盖D2007的,重新编译D7的xpman.pas生成的dcu覆盖2007的(建议备份!), 当需要编写修改“危险地带”程序时,放弃使用runtime themes,转而uses xpman和引用以上资源,程序xp特效又回来了,久违的小盾也出现了!

PS:用Dejoy 的D7lite7.3里的winxp.res不行,因为他已经改过了,内容和D2007的是一模一样的,不能和uac.res 共存!

[结论]
以上解决方法并非是非完美的,UAC的提示或多或少给用户带来了不安全的感觉,最好的方法应该由程序本身和用户交互说明需要使用管理员权限运行,或者自己你像在xp以下系统上一样,自己提高权运行权限,实现一些操作,但这样做并非现实,MS能会让它的辛苦研发出的UAC项目形同虚设?MS最终的想法可能是要大家都向它申请数字签名。

以上有什么不对之处,请指正。

[写在最后]
Borland及CG真的太好了,每次更新都巴不得把大家项目中所用的控件全提供了,以致于现在倒像是个制作控件的公司,每次基本都是几个控件升级,编译器很少改动!授之以鱼不如授之以渔,Delphi让很多人养成了一种习惯,遇到问题先去想有没有什么控件可以实现,有的人编程就是用VCL控件堆积木,还到处挑VCL的bug,真是深在福中不知福呀!源代码都给你了,你不会学着改吗?你要是用用VC,好多都要从头做起,编程好像是直接在用api(程序当然执行效率高了,可真没效率),MFC不是真正面向对象,写个界面能把人急疯了,你会真觉得Delphi太好了!可人家MS也知道自己家的东西烂,编了庞大的MSDN让它的程序员模仿,有如老师亲临,大大给他的用户壮了胆,也给了他们创造了更广阔的想象空间... 扯远了,大家见笑了!

参考:http://m.blog.csdn.net/blog/fghydx/35218457

Delphi在win7/vista下写注册表等需要管理员权限的解决方案的更多相关文章

  1. delphi在64位系统下写注册表注意事项

    HKEY_LOCAL_MACHINE写这个主键下的项,在64位系统下可能会重定向,所以构造时要加KEY_WOW64_64KEY reg := TRegistry.Create(KEY_WRITE or ...

  2. Win7,Vista UAC下应用程序标注为“需要管理员权限”的四种方法(可以修改注册表)

    [转]Vista UAC下应用程序标注为“需要管理员权限”的四种方法 在Microsoft 的UACBlog里对此有过叙述.总结如下: 首先,如果一个程序被识别为管理员程序时,Vista会在它的图标上 ...

  3. win7 64bit+vs2010 操作注册表

    注册表五个根键 HKEY_CLASSES_ROOT--管理文件系统  HKEY_LOCAL_MACHINE--管理当前系统硬件配置  HKEY_LOCAL_USER--管理系统当前用户配置  HKEY ...

  4. VB6之写注册表

    难免会遇到写注册表的情况,写了个实用点的RegWrite函数.为了减少代码量,用WScript.Shell取代了API来实现. 使用方式就在注释中了,就不再过多解释了.PS:注释比实现代码要丰富多了, ...

  5. IE 内使用ActiveX,写注册表被重定向到如下注册表

    IE 内使用ActiveX,写注册表被重定向到如下注册表,所以使用注册表做标记要注意下,目前还没找为什么会这样 HKEY_CURRENT_USER\Software\Microsoft\Interne ...

  6. C++写注册表

    1.       注册表简介 注册表是为Windows NT和Windows95中所有32位硬件/驱动和32位应用程序设计的数据文件,用于存储系统和应用程序的设置信息.16位驱动在Winnt (Win ...

  7. WinCE下读取注册表获得SD路径

    WinCE下读取注册表获得SD路径 [要点]WinCE注册表中[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\] 下键Folde ...

  8. Java Windows下读取注册表的工具类

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...

  9. 系统开启UAC情形下开机自启动程序如何以管理员权限启动

    系统开启UAC情形下开机自启动程序如何以管理员权限启动 题记:本文阐述的是在Windows系统开启UAC的情况下,开机自启动程序需要以管理员权限启动, 系统弹出UAC对话框,用户同意的情形下启动程序 ...

随机推荐

  1. AWVS介绍

    使用AWVS对域名进行全局分析,深入探索: 首先,介绍一下AWVS这个工具. Acunetix Web Vulnerability Scanner(简称AWVS)是一款知名的网络漏洞扫描工具,它通过网 ...

  2. json <--->List集合,实体类 之间的相互转换

    json所依赖的jar包http://files.cnblogs.com/files/wenjie123/json_jar%E5%8C%85.rar package com.hp.svse; impo ...

  3. CentOS7安装Cobbler

    安装EPEL源 # rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 安装cobbler ...

  4. readonly时禁用删除键,readonly按删除键后页面后退解决方案

    readonly时禁用删除键, readonly按删除键后页面后退解决方案 >>>>>>>>>>>>>>>&g ...

  5. WisDom.Net 框架设计(八) 持久层

    WisDom.Net ---持久层  1.什么是持久层        持久层负责最基础的功能支撑,为项目提供一个高层,统一,和并发的数据持久机制,提供了比如建立数据库连接,关闭数据库连接,执行sql语 ...

  6. [PDF] PDFOperation--C#PDF文件操作帮助类 (转载)

    点击下载 PDFOperation.rar 这个类是关于PDFOperation的帮助类,主要是实现C#PDF的文件操作,具体实现功能如下1.构造函数2.私有字段3.设置字体4.设置页面大小5.实例化 ...

  7. python中文件类的应用

    python中对文件.文件夹的操作需要涉及到os模块和shutil模块. 创建文件: 1) os.mknod("test.txt") 创建空文件 2) open("tes ...

  8. T-SQL切割字符串方法小结 2

    有表tb, 如下: id value ----------- ----------- 1 aa,bb 2 aaa,bbb,ccc 欲按id,分拆value列, 分拆后结果如下: id value -- ...

  9. .NET中的消息队列

    下文参考:http://hi.baidu.com/21tian/blog/item/ce5464097ddf10cb3ac76335.html为何使用消息队列 您可能认为您能够通过一个简单的数据库表( ...

  10. 给右键 添加dos命令

    reg add "HKEY_CURRENT_USER\Console" /v "ScreenBufferSize" /t REG_DWORD /d 655361 ...