如何提升应用程序启动权限

有些应用程序在启动时就需要管理员权限,比如Spy++,regedit等,如果在Windows Vista或Windows 7操作系统上面,用户把UAC打开的话,这些应用程序运行时就会弹出一个UAC对话框,请求获得管理员权限。这些程序都有一个特别,就是程序的图标上面有一个小盾牌,说明运行时是需要管理员权限,如下图:


关于提升权限,有两种方式:自动与手动。

1.手动提升权限

手动提升其实也很简单,用 ShellExecuteEx 函数就可以做到:
BOOL ShellExecuteEx(LPSHELLEXECUTEINFO pExecInfo);
typedef struct _SHELLEXECUTEINFO {
    DWORD cbSize;
    ULONG fMask;
    HWND hwnd;
    PCTSTR lpVerb;      // 必须设为runas
    PCTSTR lpFile;      // 提升后的权限启动一个可执行文件路径
    PCTSTR lpParameters;
    PCTSTR lpDirectory;
    int nShow;
    HINSTANCE hInstApp;
    PVOID lpIDList;
    PCTSTR lpClass;
    HKEY hkeyClass;
    DWORD dwHotKey;
    union {
        HANDLE hIcon;
        HANDLE hMonitor;
    } DUMMYUNIONNAME;
    HANDLE hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;

这样运行程序时就会弹出UAC对话框。

2.自动提升权限

《Windows核心编程(第五版)》 4.5.1也讲到如何实现自动提升权限,但他只是提了一下,如果真要来实现,不同的环境下的具体操作可能会有所差异,它上面是这样讲的:

如果在应用程序中可执行文件中嵌入一种特殊资源(RT_MANIFEST),其中系统会检查段,下面是示例清单文件的段。我们可以将清单保存到可知性文件所在目录中,名称和可执行文件相同且扩展名使用 *.manifest那么效果也是一样的。

不过这个清单须要在注销系统后生效,可知性文件嵌入清单的优先权会比外部清单文件大。


    
      
         
       
    


本质上是通过加一个.manifest清单文件,里面加上requestedExecutionLevel标签。这个标签可能有三个值:
[1] asInvoker:应用程序使用与主调程序一样的权限来启动。(对于标准用户程序来说,这是推荐做法)
[2] highestAvailable:应用误用与当前用户所能获得的最高权限来运行。(管理员就是管理员权限,标准用户就是标准用户的权限) 
[3] requireAdministrator:应用程序必须以管理员权限来启动。     
这一段是从《Windows核发编程(第五版)》上面摘抄过来的。前面说过,它只是大概说了一下,不是很具体。
 
   
我在实现的过程中,参考了微软给的步骤,http://msdn.microsoft.com/en-us/library/bb756929.aspx 
manifest文件的内容:


  
  Description of your application
  
  
    
      
        
      
    
  

然后在资源文件中加入: 
#define MANIFEST_RESOURCE_ID 
MANIFEST_RESOURCE_ID RT_MANIFEST "IsUserAdmin.exe.manifest" 
或者在把这个.manifest文件添加到工程设置中:
[1] Open your project in Microsoft Visual Studio 2005.
[2] Under Project, select Properties.
[3] In Properties, select Manifest Tool, and then select Input and Output.
[4] Add in the name of your application manifest file under Additional manifest files.
[5] Rebuild your application.

我几种方案都试了,但就是链接有错,什么错呢?如下:
"manifest authoring error c1010001: Values of attribute 'level' not equal in different manifest snippets."
      
我之前一直以为是我的.manifest文件写有有错,最好在网上查了一下,不是文件写错,而是环境的问题。
     
以上的做法适合在VS2005下面使用。在VS2005下面使用是没有问题的。

      
VS2008下面这种做法就不对,因为VS2008已经能生成一个.manifest文件。而且实现提升权限功能在VS2008下面相当简单:Properties->Configuration Properties->Linker->Manifest File
 
   
按照这样的设置就行了,所以在VS2008下面实现提升权限就不需要配置.manifest文件。经过配置后,重新编译出的程序的图标上面就会有一个小盾牌,运行时就会弹出UAC对话框。如下图所示。
 
   
 
  

3.参考链接 

http://hi.baidu.com/lynnux/blog/item/cb2829457e2d8f2acefca319.html 
http://msdn.microsoft.com/en-us/library/bb756929.aspx 

你可能感兴趣的:(VC++)