使用 ShellExecuteEx 手动提升进程的权限
函数原型:
BOOL ShellExecuteEx( Inout SHELLEXECUTEINFO *pExecInfo);
参数介绍:
typedef struct _SHELLEXECUTEINFO {
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCTSTR lpVerb;
LPCTSTR lpFile;
LPCTSTR lpParameters;
LPCTSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
LPVOID lpIDList;
LPCTSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
} DUMMYUNIONNAME;
HANDLE hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
fMask 参数,可为下列值的组合:
SEE_MASK_DEFAULT (0)默认
SEE_MASK_CLASSNAME 使用 lpClass 参数,如果 SEE_MASK_CLASSKEY 也有效,则用后者
SEE_MASK_CLASSKEY 使用 hkeyClass 参数
SEE_MASK_IDLIST 使用 lpIDList 参数
SEE_MASK_INVOKEIDLIST 使用选定项目的快捷菜单 IContextMenu 接口处理程序
SEE_MASK_ICON 使用 hIcon 给出的菜单,不能与 SEE_MASK_HMONITOR 共用,Vista之后
SEE_MASK_HOTKEY 使用 dwHotKey 参数
SEE_MASK_NOCLOSEPROCESS 如果执行之后需要返回进程句柄,或者等待执行完毕的话,则需要指定该参数,从结构参数意义可以看到 hProcess 和 hInstApp 都依赖该选项
SEE_MASK_CONNECTNETDRV 验证共享并连接到驱动器号
SEE_MASK_NOASYNC 不等待操作完成,直接返回,会创建一个后台线程运行。
SEE_MASK_FLAG_DDEWAIT 弃用,使用 SEE_MASK_NOASYNC
SEE_MASK_DOENVSUBST 环境变量会被展开
SEE_MASK_FLAG_NO_UI 出现错误,不显示错误消息框,比如不会弹出找不到文件之类的窗口,直接返回失败
SEE_MASK_UNICODE UNICODE 程序
SEE_MASK_NO_CONSOLE 继承父进程的控制台,而不是创建新的控制台,与 CREATE_NEW_CONSOLE 相反
SEE_MASK_ASYNCOK 执行在后台线程,调用立即返回
SEE_MASK_NOQUERYCLASSSTORE 弃用
SEE_MASK_HMONITOR 使用 hmonitor,不能与 SEE_MASK_ICON 共存
SEE_MASK_NOZONECHECKS 不执行区域检查
SEE_MASK_WAITFORINPUTIDLE 创建新进程后,等待进程变为空闲状态再返回,超时时间为1分钟
SEE_MASK_FLAG_LOG_USAGE 跟踪应用程序启动次数
SEE_MASK_FLAG_HINST_IS_SITE
lpVerb 参数与 ShellExecute 的 lpOperation 参数一致:
edit 用编辑器打开 lpFile 指定的文档,如果 lpFile 不是文档,则会失败
explore 浏览 lpFile 指定的文件夹
find 搜索 lpDirectory 指定的目录
open 打开 lpFile 文件,lpFile 可以是文件或文件夹
print 打印 lpFile,如果 lpFile 不是文档,则函数失败
properties 显示属性
runas 请求以管理员权限运行,比如以管理员权限运行某个exe
NULL 执行默认”open”动作
nShow 与 ShellExecute 的该参数一致:
SW_HIDE 隐藏窗口,活动状态给令一个窗口
SW_MINIMIZE 最小化窗口,活动状态给令一个窗口
SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态
SW_SHOWMAXIMIZED 最大化窗口,并将其激活
SW_SHOWMINIMIZED 最小化窗口,并将其激活
SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口
SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口
SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口
SW_SHOWNORMAL 与SW_RESTORE相同
如果设置了 SEE_MASK_NOCLOSEPROCESS ,调用成功则 hInstApp 返回大于32的值,调用失败会返回:
SE_ERR_FNF (2) 文件未找到
SE_ERR_PNF (3) 路径未找到
SE_ERR_ACCESSDENIED (5) 拒绝访问
SE_ERR_OOM (8) 内存不足
SE_ERR_DLLNOTFOUND (32) 动态库未找到
SE_ERR_SHARE (26) 无法共享打开的文件
SE_ERR_ASSOCINCOMPLETE (27) 文件关联信息不完整
SE_ERR_DDETIMEOUT (28) 操作超时
SE_ERR_DDEFAIL (29) 操作失败
SE_ERR_DDEBUSY (30) DDE 操作忙
SE_ERR_NOASSOC (31) 文件关联不可用
返回值:
函数执行成功,返回 TRUE ,否则返回 FALSE ,可使用 GetLastError 获取错误码。
ERROR_FILE_NOT_FOUND 文件不存在
ERROR_PATH_NOT_FOUND 路径不存在
ERROR_DDE_FAIL DDE(动态数据交换)失败
ERROR_NO_ASSOCIATION 未找到与指定文件拓展名关联的应用
ERROR_ACCESS_DENIED 拒绝访问
ERROR_DLL_NOT_FOUND 未找到dll
ERROR_CANCELLED 功能提示用户提供额外信息,但是用户取消请求。
ERROR_NOT_ENOUGH_MEMORY 内存不足
ERROR_SHARING_VIOLATION 发生共享冲突
以下是一些例子(进程提权,提升另一进程,非本进程)
//这是windows核心编程的一些提升权限的代码
SHELLEXECUTEINFO sei=sizeof(SHELLEXECUTEINFO)
sei.lpVerb = _T("runas")
sei.lpFile = _T("cmd.exe")
if(! ShellExecuteEx(&sei))
{
DWORD dwStatus=GetLastError()
if(dwStatus==ERROR_CANCELLED)
{
}
}
SHELLEXECUTEINFO sei
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO))
sei.cbSize = sizeof(SHELLEXECUTEINFO)
sei.lpFile = _T("cmd.exe")
sei.nShow = SW_SHOW
sei.lpVerb = _T("runas")
ShellExecuteEx(&sei)
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO))
sei.cbSize = sizeof(SHELLEXECUTEINFO)
sei.lpFile = _T("c:\\")
sei.nShow = SW_SHOW
sei.fMask = SEE_MASK_INVOKEIDLIST
sei.lpVerb = _T("properties")
ShellExecuteEx(&sei)
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO))
sei.cbSize = sizeof(SHELLEXECUTEINFO)
sei.lpFile = _T("c")
sei.nShow = SW_SHOW
sei.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI
sei.lpVerb = _T("properties")
ShellExecuteEx(&sei)
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO))
sei.cbSize = sizeof(SHELLEXECUTEINFO)
sei.lpFile = _T("cmd.exe")
sei.nShow = SW_SHOW
sei.fMask = SEE_MASK_NOCLOSEPROCESS
sei.lpVerb = _T("open")
if (ShellExecuteEx(&sei))//执行成功
{
if (sei.hProcess)//指定 SEE_MASK_NOCLOSEPROCESS 并其成功执行,则 hProcess 将会返回执行成功的进程句柄
WaitForSingleObject(sei.hProcess, INFINITE)
}
else
{
CString s
s.Format(_T("ShellExecuteEx error,error code:%d"), GetLastError())
MessageBox(s)
}