感想关注 ,转载引用请注明 http://blog.csdn.net/leonwei/article/details/8905703

最近一直在搞页游版的端游移植,里面用到了很多进程启动进程的情况,这种情况在XP以前的系统上是很常见的编程形式,也从来不会出现问题,但是搬到Win7系统上就不行,在很多用户的Win7系统中,进程A去启动进程B(如果直接使用CreateProcess)会创建失败,后来发现这是因为受到了UAC的控制,将解决这类问题的经验总结于此。

1.什么是UAC

UAC全称User Access Control,是Win Vista系统开始引入的一种安全机制,它在操作系统中定义了多种用户访问的安全级别(可在用户账户中修改,默认为中),

不同的安全级别对于程序的行为是有不同限定的:

从不通知:这个跟XP一样,没有限定任何程序行为,是最低的

仅当程序尝试更改计算机时通知:当你的程序会触发对计算机的修改,更简单的说就是你发生了写磁盘操作,就会弹出通知询问用户(这是默认的)

始终通知:无论是自己还是程序修改计算机都会触发询问

例如当我们在win7下打开某个程序时可能触发这样的画面

这个小盾牌我们经常看见,这就是触发了UAC的询问了

2.UAC会给编程带来哪些问题

UAC在vista上他是一个饱受诟病的东西,因为在它降低了用户使用程序软件的连贯性,经常的这种弹窗很烦,而且它能带来的安全保护又有些鸡肋,所以很多用户去控制面板里关了它,但是微软在Win7之后的版本仍然保留甚至加强了这个东西,甚至在Win8版本中用户想关它都要费点麻烦。

他对于我们的编程上更是带来一些问题,但是既然我们还在用Windows,而UAC就是Windows的一部分,我们就要Do the Microsoft Way 了。

在编程上通常有下列问题(在开启uac的情况下):

1.任何更改系统或者写磁盘的操作都会失败(例如fopen这些都会失败)

2.对其他进程的调用会失败(例如createprocess)

3.解决方案

3.1 首先对于写磁盘失败这些问题,是因为你的程序启动默认都是采用低权限启动的,突破UAC你就要使用高权限启动程序,行话叫elevate(提升)。一个程序启动后是没有办法任何办法elavate的,一个程序是不是被elevate只有在启动的那一时刻决定,查阅了一下MSDN,上面有张图如下,就是UAC起作用与elevate的整个过程。记住elevate只有在启动时可以发生,一旦它已经运行了,没有任何办法提升他的权限。

所以对待这样的程序,在win7下我们要显示的声明他们需要elevate,而如何显示声明,就是把这个信息写入exe的清单文件(,manifest),在vs下面,清单文件一般我们让他默认生成,而如果是想让在win7下获得elevate,可以建立一个新的manifest文件,内容如下

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
<ms_asmv2:security>
<ms_asmv3:requestedPrivileges xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</ms_asmv3:requestedPrivileges>
</ms_asmv2:security>
</ms_asmv2:trustInfo>
</assembly>
其中的level="requireAdministrator就标志着这个程序的执行需要elevate,在vs里附加以上清单文件,再编译链接,就会发现新生成的exe文件带有一个盾牌,如图,这标志着这个程序的启动需要以管理员权限启动,它可能会修改系统。

当这个exe双击启动时,会触发UAC,而在得到用户的询问允许后,你的程序就自然获得了高权限,就可以写磁盘了。(相反,没有这个盾牌,启动后不触发UAC,自动进入较低权限,你程序的行为可能就会被限制)

3.2还有一种情况是对process的调用,如你在A程序中想创建一个进程B,如果进程A的权限较低,而B的权限较高(即A有盾牌,B没有盾牌),那么B是回创建失败的,怎么办,一种是像前面那样把A加个盾牌,另一种就是采用ShellExecuteEx启动进程。

ShellExecuteEx是唯一一个微软允许触发UAC的进程启动函数,如下面代码

SHELLEXECUTEINFO shExInfo = {0};
 shExInfo.cbSize = sizeof(shExInfo);
 shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
 shExInfo.hwnd = 0;
 shExInfo.lpVerb = _T("open");                // Operation to perform
 shExInfo.lpFile = enginePath;       // Application to start   
 shExInfo.lpParameters = szBuf;                  // Additional parameters
 shExInfo.lpDirectory = workingPath;
 shExInfo.nShow = SW_SHOW;
 shExInfo.hInstApp = 0;

ShellExecuteEx(&shExInfo);

使用ShellExecuteEx启动中,lpVerb可以指定为Open、edit等等,这个函数不仅可以启动进程,还可以打开文件,这个函数会自动触发UAC的询问。

在Win7下使用Createprocess,如果发现权限不足,会直接失败,而ShellExecuteEx则是一个好的解决方法。

转载于:https://www.cnblogs.com/weizhixiao/archive/2013/05/09/5697313.html

冲出UAC-解决Win UAC问题的编程经验相关推荐

  1. xp系统怎么关dhcp服务器,怎样解决Win XP操作系统DHCP故障:获取未使用的IP地址

    怎样解决Win XP操作系统DHCP故障:获取未使用的IP地址 发布时间:2011-05-12 14:57:29   作者:佚名   我要评论 在我们解决Windows 操作系统的DHCP故障时,有时 ...

  2. SVN地址正确,能在网页打开,但是检出失败解决方法

    SVN地址正确,能在网页打开,但是检出失败解决方法 参考文章: (1)SVN地址正确,能在网页打开,但是检出失败解决方法 (2)https://www.cnblogs.com/zzd0916/p/76 ...

  3. 在 Linux 上找出并解决程序错误的主要方法【转】

    在 Linux 上找出并解决程序错误的主要方法[转] 参考文章: (1)在 Linux 上找出并解决程序错误的主要方法[转] (2)https://www.cnblogs.com/sky-heaven ...

  4. 成功解决win系统电脑中网络仅看到自己计算机图文教程

    成功解决win系统电脑中网络仅看到自己计算机图文教程 目录 解决问题 解决思路 解决方法 解决问题 解决win系统电脑中网络仅看到自己计算机 解决思路 很可能未开启服务! 解决方法 1.先查看是否能通 ...

  5. mac数字键盘错乱_苹果手机数字键盘 苹果电脑键盘打不出数字解决办法

    苹果电脑跟苹果手机一样,是电子设备中的佼佼者.但也因为其好看的外表和出色的性能受到很多人的喜爱.那么苹果电脑键盘打不出数字解决办法有什么呢?下面就让afU123小编来告诉大家吧,欢迎阅读. 进行基本设 ...

  6. mac数字键盘错乱_苹果电脑键盘打不出数字解决办法

    苹果电脑键盘打不出数字解决办法 1.首先可能用户粗心操作造成的.硬件问题包括因为苹果电脑键盘数字键和字母键是整合在一起的,一般按fn Numlk键可以智能切换到小数字键盘. 2.如果还是没用的话,那么 ...

  7. Dism解决win 10访问服务器共享问题,共享需要过时的SMB1协议,安装时错误代码:0x800736B3

    Dism解决win 10访问服务器共享问题,共享需要过时的SMB1协议,安装时错误代码:0x800736B3 参考文章: (1)Dism解决win 10访问服务器共享问题,共享需要过时的SMB1协议, ...

  8. 饥荒联机版连不上服务器_《饥荒》无法连接klei服务器 刷不出服务器解决办法...

    <<饥荒>无法连接klei服务器 刷不出服务器解决办法>文章已经归档,不再展示相关内容,编辑建议你查看最新于此相关的内容: <饥荒:联机版>服务器卡顿原因分析及解决 ...

  9. 成功解决WIN系统如何更改默认放在C盘的【我的文档】/【图片】位置的存储路径(修改到其它非系统的盘符)

    成功解决WIN系统如何更改默认放在C盘的[我的文档]/[图片]位置的存储路径(修改到其它非系统的盘符) 目录 解决问题 解决思路 解决方法 解决问题 解决WIN系统如何更改默认放在C盘的[我的文档]/ ...

最新文章

  1. python使用matplotlib绘制水平条形图并在条形图上添加实际数值标签实战
  2. ORM框架之------Dapper,Net下无敌的ORM
  3. 什么东西都要用一句话总结出来:这是最重要的
  4. 使用request简单爬虫
  5. php传二维数组,JS用POST怎么传送二维数组给PHP
  6. linux lua socket编程,CentOs 安装lua,luasocket
  7. Apache log4j是领先的日志记录框架
  8. 布尔表达式的语法及语义分析程序_XSS语义分析的阶段性总结(一)
  9. 配置 BeautifulSoup
  10. (转载)OC学习篇之---Foundation框架中的NSDirctionary类以及NSMutableDirctionary类
  11. Python画数码晶体管日期(年月日时分秒)
  12. oracle dbms_lob trim,DBMS_LOB
  13. 电驴使用经验谈(转)
  14. 不用第三方写一个简单的推流软件
  15. CSS---足球场的实现,纪念2022世界杯(:root的使用)
  16. unity打包报错,又是血压升高的一天
  17. 【小波变换】小波变换入门----haar小波
  18. 吴式太极大师修丕勋简介
  19. Android开发-简介(一)
  20. 如何给App快速搭建虚拟服务器

热门文章

  1. windows 检查cuda安装_Windows环境CUDA 4.0:安装与验证
  2. android 布局翻页,安卓APP_ 布局(8) —— 基于 RecyclerView 的 ViewPager2翻页
  3. 蓝桥杯四平方和Java_蓝桥杯 四平方和
  4. STM32单片机真的落后?
  5. php5.3.6安装教程,apache2.2.19+php5.3.6配置教程
  6. rust墙壁升级点什么_分享:如何在阅读Rust项目源码中学习
  7. 【MySQL】MySQL的事务
  8. poj1386(判断一个有向图是否存在欧拉回路)
  9. python初始化_Python list初始化
  10. java取list中最大数值_Java后台通过Collections获取list集合中最大数,最小数代码