【winapi】ShellExecute

概述: ShellExecute 用法的整理和示例
官方说明:shellExecuteA 函数 (shellapi.h) - Win32 apps | Microsoft Learn

用法示例

以下示例为一个完整的用法展示,实现了调用第三方工具 devocn.exe 安装虚拟网卡(不展示安装界面)并通过获取安装进程句柄判断安装结果。

  • SEE_MASK_NOCLOSEPROCESS 参数:表示要获取进程句柄
  • 通过 GetExitCodeProcess 函数获取进程执行状态
  • SW_HIDE 参数: 不展示窗口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#define QREINSTALL_NETCARD_TOOLS_NAME   L"devcon.exe"
std::mutex g_mutex_nc_install;

bool InstallNcDrive(bool &bRes, bool &bEnd)
{
std::lock_guard<std::mutex> lock(g_mutex_nc_install);

bool bOptRt = false;
//触发重新安装虚拟网卡
TCHAR szPath[MAX_PATH];
::GetModuleFileName(NULL, szPath, MAX_PATH);
::PathRemoveFileSpec(szPath);

QLOG_INFO() << "tools[devcon.exe]'s path is" << QString::fromWCharArray(szPath);

std::string command = " install vpnvnic.inf vpnvnic";

SHELLEXECUTEINFO ShExecInfoInstall = { 0 };

try
{
ShExecInfoInstall.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfoInstall.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfoInstall.hwnd = NULL;
if (!isProcessAdmin())
{
ShExecInfoInstall.lpVerb = L"runas";
}
else
{
ShExecInfoInstall.lpVerb = L"open";
}
ShExecInfoInstall.lpFile = QREINSTALL_NETCARD_TOOLS_NAME;
ShExecInfoInstall.lpParameters = STDString2LPCWCH(command);
ShExecInfoInstall.lpDirectory = szPath;
ShExecInfoInstall.nShow = SW_HIDE;
ShExecInfoInstall.hInstApp = NULL;
ShExecInfoInstall.hProcess = NULL;

bOptRt = ShellExecuteEx(&ShExecInfoInstall);

if (bOptRt)
{
QLOG_INFO() << "驱动安装进程已启动!";

// 等待进程结束
WaitForSingleObject(ShExecInfoInstall.hProcess, INFINITE);

// 获取退出代码
DWORD exitCode;
if (GetExitCodeProcess(ShExecInfoInstall.hProcess, &exitCode))
{
// 判断进程是否成功退出
if (exitCode != STILL_ACTIVE)
{
QLOG_INFO() << "驱动安装进程已退出,退出代码: " << exitCode;
}
else
{
QLOG_INFO() << "驱动安装进程未能正常退出,退出代码: " << exitCode;
}
}
else
{
QLOG_INFO() << "获取驱动安装进程退出代码失败!错误代码: " << GetLastError();
}

// 实测 1和0 的时候安装成功
bRes = exitCode == 1 || exitCode == 0 ? true : false;

// 关闭句柄
CloseHandle(ShExecInfoInstall.hProcess);
}
else
{
QLOG_ERROR() << "启动驱动安装进程失败!错误代码: " << GetLastError();
}
}
catch (const std::exception& e)
{
QLOG_ERROR() << __FUNCTION__ << __LINE__ << e.what();

bEnd = true;
return bOptRt;
}

bEnd = true;
return bOptRt;
}

【winapi】ShellExecute
https://hodlyounger.github.io/A_OS/Windows/API/【winapi】ShellExecute/
作者
mingming
发布于
2023年10月27日
许可协议