从Vista以后UAC机制导致很多程序被限制在权限里,感觉所有东西都是需要权限的,当年Vista预览版时QQ也必须右击管理员身份才能运行。
mfc程序自然也遇到这个问题,一般我是用VS2005开发的,这样开发出的程序小巧,绿色,但是配置中没有“UAC执行级别”的选项。
所以只能自己建立一个xml,比如:
“jaskle_intermediate.manifest”
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
将它放在代码目录里,然后打开:
项目属性->配置属性->清单工具->输入和输出->附加清单文件
填入:$(ProjectDir)\jaskle_intermediate.manifest
重新编译即可
编译出来的文件在需要UAC的系统里就有小盾牌了
现在说一下用这种方式的弊端:
如果用户系统是win10,且使用了UAC那么一个低权限程序是无法调用一个高权限程序,这个问题在win7是不存在的,所以为了兼容必须使用runas:
SHELLEXECUTEINFO sei={sizeof(SHELLEXECUTEINFO)};
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = TEXT("runas");
sei.lpFile = jexe_path;
sei.lpDirectory = jrun_dir;
sei.nShow = jshow_state;
sei.lpParameters = jcmdline;
if(!ShellExecuteEx(&sei))
{
DWORD dwStatus=GetLastError();
if(dwStatus==ERROR_CANCELLED)
{
//提权失败
return -1;
}
else if(dwStatus==ERROR_FILE_NOT_FOUND)
{
//运行失败
return -2;
}
}
这也从另一个角度告诉我们,不要随意将自己的程序设为管理员权限,很吃不开的,到时候换到win10直接就掉不出来。
还有一种很好玩的方法:
微软为了兼容性考虑,如果你是双击鼠标打开的程序(以explorer打开的),那么凡是文件名带有“install”、“setup”等字样,就会自动带上小盾牌,以管理员身份运行,真是如微的细致啊!
VS2005及以前的程序很有可能被win7以上系统视为“不兼容的程序”,出现兼容性助手。
微软6.x内核引入作业机制,感觉就像沙箱,简单说如果应用程序没有说明对win7的支持,那么就是认为不一定支持。运行程序时就被套在作业里,如图:
解决方法就是上面的xml再改一下:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</application>
</compatibility>
</assembly>
这样微软就知道你的程序已经做了兼容
恩,就说到这~~~