Delphi在win7/vista下写注册表等需要管理员权限的解决方案
看到论坛好多人问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下写注册表等需要管理员权限的解决方案的更多相关文章
- delphi在64位系统下写注册表注意事项
HKEY_LOCAL_MACHINE写这个主键下的项,在64位系统下可能会重定向,所以构造时要加KEY_WOW64_64KEY reg := TRegistry.Create(KEY_WRITE or ...
- Win7,Vista UAC下应用程序标注为“需要管理员权限”的四种方法(可以修改注册表)
[转]Vista UAC下应用程序标注为“需要管理员权限”的四种方法 在Microsoft 的UACBlog里对此有过叙述.总结如下: 首先,如果一个程序被识别为管理员程序时,Vista会在它的图标上 ...
- win7 64bit+vs2010 操作注册表
注册表五个根键 HKEY_CLASSES_ROOT--管理文件系统 HKEY_LOCAL_MACHINE--管理当前系统硬件配置 HKEY_LOCAL_USER--管理系统当前用户配置 HKEY ...
- VB6之写注册表
难免会遇到写注册表的情况,写了个实用点的RegWrite函数.为了减少代码量,用WScript.Shell取代了API来实现. 使用方式就在注释中了,就不再过多解释了.PS:注释比实现代码要丰富多了, ...
- IE 内使用ActiveX,写注册表被重定向到如下注册表
IE 内使用ActiveX,写注册表被重定向到如下注册表,所以使用注册表做标记要注意下,目前还没找为什么会这样 HKEY_CURRENT_USER\Software\Microsoft\Interne ...
- C++写注册表
1. 注册表简介 注册表是为Windows NT和Windows95中所有32位硬件/驱动和32位应用程序设计的数据文件,用于存储系统和应用程序的设置信息.16位驱动在Winnt (Win ...
- WinCE下读取注册表获得SD路径
WinCE下读取注册表获得SD路径 [要点]WinCE注册表中[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\] 下键Folde ...
- Java Windows下读取注册表的工具类
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...
- 系统开启UAC情形下开机自启动程序如何以管理员权限启动
系统开启UAC情形下开机自启动程序如何以管理员权限启动 题记:本文阐述的是在Windows系统开启UAC的情况下,开机自启动程序需要以管理员权限启动, 系统弹出UAC对话框,用户同意的情形下启动程序 ...
随机推荐
- (转载)SVN 提交操作缩写(A D M R) .
前言: 今天使用SVN提交代码,发现提交后的代码找不到之前的版本. 操作的字母缩写为R.一般我们常见的操作为 A D M R A:add,新增 C:conflict,冲突 D:delete,删除 ...
- 功能模块图、业务流程图、处理流程图、ER图,数据库表图(概念模型和物理模型)画法
如果你能使用计算机规范画出以下几种图,那么恭喜你,你在我这里被封为学霸了,我膜拜ing-- 我作为前端开发与产品经理打交道已有5-6年时间,产品经理画的业务流程图我看过很多.于是百度搜+凭以往经验脑补 ...
- android线程与线程池-----线程池(二)《android开发艺术与探索》
android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的 ...
- Linux强制踢出登录用户(断线账户剔除)
首先,用w查看登录用户 :: up days, :, users, load average: 1.00, 1.01, 1.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU ...
- redis安装与使用
linux: 1.下载redis 下载redis: 可以在redis的官网下载 : http://redis.io/ 也可以去谷歌的code下载: http://code.google.com/p/r ...
- [转载]Access to the path '' is denied.解决方案
原文地址:Access to the path '' is denied.解决方案作者:趴着墙等红杏 ccess to the path '路径' is denied.我在网上找了很多资料,最后终于解 ...
- [PDF] PDFOperation--C#PDF文件操作帮助类 (转载)
点击下载 PDFOperation.rar 这个类是关于PDFOperation的帮助类,主要是实现C#PDF的文件操作,具体实现功能如下1.构造函数2.私有字段3.设置字体4.设置页面大小5.实例化 ...
- Android MVP模式的初识
MVP是什么?或许在之前更多的人知道的是MVC这个模式(Model View Controller),然而MVP与MVC最不同的一点是M与V是不直接 关联的也是就Model与View不存在直接关系 ...
- Git命令详解【2】
git的工作区 git 安装 sudo apt-get insall git 查看git 版本 git --version git的配置 #配置用户名 git config --global ...
- MFC可编辑的ListCtrl
近期由于项目的要求,需要一个可以编辑的列表控件,由于MFC提供的列表控件只支持第一行可编辑,无法满足项目需求,故只能自己动手重写一个列表控件.重写列表控件的思想为:当点击列表的某行某列时,在此处创建一 ...