VC程序在win7系统上运行,自动获取管理员权限

在win7 上运行程序,经常需要管理员权限,如何让自己编写的程序启动的时候获取管理员权限呢?方法如下:

 

1: 在VS2010中,可以参考《VS2010与Win7共舞:UAC与数据重定向》这篇文章,为了方便,这里复制过来:

 

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

 禁用UAC Virtualization

  凡事都没有绝对。如果因为一些特殊的要求(众所周知,客户的要求千奇百怪,无奇不有),我们一定要向“Program Files”目录写入数据,这时该怎么办呢?面对这种极其特殊的情况,我们可以在应用程序的Manifest禁用UAC Virtualization,取消其对数据写操作的重定向。在项目属性中,我们设置启用UAC(Enable User Account Control),并且在UAC Execution Level中设置请求管理员权限。这样,应用程序在启动的时候,就会向用户请求管理员权限,当应用程序获得管理员执行权限后,当然可以向任意目录写入数据,UAC Virtualization也就不会起作用了。

  图2  通过Manifest禁用UAC Virtualization

  对于64位应用程序,本身是不具备UAC Virtualization机制的,所以根本不存在禁用的问题。当我们在64位应用程序中尝试向“Program Files”等敏感目录写入数据时,就会遇到一个“拒绝访问”的错误:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> //  测试文件夹是否存在
BOOL IsDirectoryExists(TCHAR  * dirName)
{
    WIN32_FILE_ATTRIBUTE_DATA dataDirAttrData;
    
if  ( ! ::GetFileAttributesEx(dirName, GetFileExInfoStandard,  & dataDirAttrData))
    {
        DWORD lastError 
=  ::GetLastError();
        
if  (lastError  ==  ERROR_PATH_NOT_FOUND  ||  lastError  ==  ERROR_FILE_NOT_FOUND  ||  lastError  ==  ERROR_NOT_READY)
            
return  FALSE;
    }

    
return  (dataDirAttrData.dwFileAttributes  &  FILE_ATTRIBUTE_DIRECTORY)  !=   0 ;
}

//  …
    
//  获取文件夹路径
    
// if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramData,
    
//            0, NULL, &pszPath)))
    
//  错误的做法: 
     if  (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFiles,
        
0 , NULL,  & pszPath)))
    {
        
//  提示错误
        MessageBox(hwndDlg, _T( " SHGetKnownFolderPath无法获取文件路径 " ),
            _T(
" Error " ), MB_OK  |  MB_ICONERROR);
        
return  FALSE;
    }

//
       
//  检查文件夹是否存在
     if  (::IsDirectoryExists(dataFilePath))
    {
        
//  如果文件夹不存在,则创建文件夹
         if  ( ! ::CreateDirectory(dataFilePath, NULL))
        {
            DWORD dwErrorCode 
=  ::GetLastError();
            LPCWSTR lpBuffer; 
            
//  获取错误信息
            FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER    |
                   FORMAT_MESSAGE_IGNORE_INSERTS  
|
                 FORMAT_MESSAGE_FROM_SYSTEM,
                 NULL,
                 dwErrorCode, 
//   错误代码
                 LANG_NEUTRAL,
                 (LPTSTR)
& lpBuffer,
                 
0  ,
                 NULL );
             
            
//  显示错误对话框
            MessageBox(hwndDlg, lpBuffer, _T( " 创建文件夹错误 " ), MB_OK  |  MB_ICONERROR);
            LocalFree((HLOCAL)lpBuffer);
            
            
return  FALSE;
        }
    }

  当这段代码执行到创建文件夹的时候,会遇到一个“拒绝访问”错误:

  图3  创建文件夹的“拒绝访问”错误

  为了避免这个错误,同样的,我们可以通过在项目属性中设置,使得Manifest中嵌入UAC相关的信息,在应用程序启动的时候请求管理员权限,就像我们在运行其他大多数需要管理器权限的应用程序一样。当应用程序获得管理员权限后,这个错误就不存在了。但是这里必须要指出,这种做法是不太安全的,能够避免尽量避免。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 

按照上述文章,VS2010编写的程序可以运行时获取管理员权限;

 

但是如果是VS2010以前的程序呢?

方法1:当然是移植到VS2010上了;

 

方法2:(这才是要说的):

(1)按照《VS2010与Win7共舞:UAC与数据重定向》上述方法,随便写一个VS2010工程,编译,在这个工程的Debug目录下会有两个文件:   *.exe.embed.manifest 和 *.exe.intermediate.manifest ;

(2)随便复制一个 .manifest 文件到你现在的工程目录的资源文件夹(res)下,然后在工程的资源中Import这个文件;

(3)资源文件夹设置为“24”,资源ID设置为“1”;

 

现在ok了,你编译的程序,可以获取管理员权限了。

 

用一下这个函数就可以启动其他程序以管理员权限,当然可以自己启动自己


BOOL ElevateCurrentProcess(CString sCmdLine)

{
 
 TCHAR szPath[MAX_PATH] = {0}; 
 
 if (::GetModuleFileName(NULL, szPath, MAX_PATH))
  
 {
  
  // Launch itself as administrator.
  
  SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
  
  sei.lpVerb = _T("runas");
  
  sei.lpFile = szPath;
  
  sei.lpParameters = (LPCTSTR)sCmdLine;
  
  //     sei.hwnd = hWnd;
  
  sei.nShow = SW_SHOWNORMAL;
  
  
  
  if (!ShellExecuteEx(&sei))
   
  {
   
   DWORD dwStatus = GetLastError();
   
   if (dwStatus == ERROR_CANCELLED) 
    
   {
    
    // The user refused to allow privileges elevation.
    
    return FALSE;
    
   }
   
   else
    
    if (dwStatus == ERROR_FILE_NOT_FOUND) 
     
    {
     
     // The file defined by lpFile was not found and
     
     // an error message popped up.
     
     return FALSE;
     
    }
    
    
    
    return FALSE;
    
    
    
  }     
  
  return TRUE;
  
 }
 
 return FALSE;
 
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值