近来研究程序启动,稍微总结一下,以后继续补充:
感触注关 ,转载用引请注明
近来一直在搞页游版的端游移植,里头用到了很多程进启动程进的情况,种这情况在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则是一个好的处理方法。
文章结束给大家分享下程序员的一些笑话语录: 爱情观
爱情就是死循环,一旦执行就陷进去了。 爱上一个人,就是内存泄露--你永远释放不了。 真正爱上一个人的时候,那就是常量限定,永远不会改变。 女朋友就是私有变量,只有我这个类才能调用。 情人就是指针用的时候一定要注意,要不然就带来巨大的灾难。