今天来说说ShellExecuteEx这个函数,先翻译MSDN,然后看个样例。
ShellExecuteEx Function
对指定应用程序运行某个操作
语法:
BOOL ShellExecuteEx( LPSHELLEXECUTEINFO lpExecInfo
);
參数:
lpExecInfo
[in, out] 一个指向 SHELLEXECUTEINFO 结构的指针,用来传递和保存应用程序运行相关的信息。
返回值:
假设函数成功运行就返回TRUE,否则返回 FALSE 。可调用 GetLastError 获取错误信息。
备注:
因为ShellExecuteEx 可以将运行托付给那些由组件对象模型COM激活的Shell 扩展(数据源,上下文菜单句柄,动词实现),因此在调用ShellExecuteEx 之前要先初始化 COM。某些Shell 扩展要求单线程单元模型的COM,在这样的情况下,应当像以下一般初始化COM:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
在某些情况下 ShellExecuteEx 并没有使用这样的类型的Shell 扩展,这时就无需初始化COM。尽管如此,总是在使用这个函数之前初始化COM是个不错的举措。
假设有多个显示器,而且你指定了一个HWND 同一时候设置lpExecInfo 的成员lpVerb 为 "Properties",那么由ShellExecuteEx 创建的不论什么窗体都有可能显示在不对的位置上。
假设这个函数运行成功,它会设置 SHELLEXECUTEINFO 的hInstApp 成员为一个大于32的值。假设函数运行失败,hInstApp 成员被设置为SE_ERR_XXX(提示失败的原因)。尽管为了兼容16位的windows应用程序hInstApp 被声明成一个句柄,但它并非一个句柄。它仅仅能被转型为整数,并同32或SE_ERR_XXX之类的错误代码比較。
提供SE_ERR_XXX 之类的错误代码是为了兼容ShellExecute。使用GetLastError能够获得更具体的错误信息。返回值能够使下列之中的一个:
Error |
Description |
ERROR_FILE_NOT_FOUND |
指定文件不存在 |
ERROR_PATH_NOT_FOUND |
指定路径不存在 |
ERROR_DDE_FAIL |
动态数据交换 (DDE) 处理失败 |
ERROR_NO_ASSOCIATION |
没有与制定文件名称扩展相应的应用程序 |
ERROR_ACCESS_DENIED |
訪问指定文件被拒绝 |
ERROR_DLL_NOT_FOUND |
无法找到执行应用程序所必须的库文件 |
ERROR_CANCELLED |
这个函数要求用户提供很多其它其它信息(译注:比方弹出对话框),但请求用户被取消了 |
ERROR_NOT_ENOUGH_MEMORY |
没有足够的内存来运行操作 |
ERROR_SHARING_VIOLATION |
共享违规发生了 |
Windows 95/98/Me: ShellExecuteEx 为Microsoft Layer for Unicode (MSLU)所支持。为了使用这个函数,必须加入额外的文件到应用程序中去,请參考:Microsoft Layer for Unicode on Windows Me/98/95 Systems.
函数信息:
Minimum DLL Version |
shell32.dll version 3.51 or later |
Custom Implementation |
No |
Header |
shellapi.h |
Import library |
shell32.lib |
Minimum operating systems |
Windows NT 4.0, Windows 95 |
Unicode |
Implemented as ANSI and Unicode versions |
以下举例说明怎样使用这个函数,executePackage 这个函数用来运行某个应用程序。
bool executePackage(LPCWSTR fileName, LPCWSTR args, LPCWSTR baseDir, bool wait)
{
SHELLEXECUTEINFOW sei = { sizeof(SHELLEXECUTEINFOW) };
sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
sei.lpFile = fileName;
sei.lpParameters = args;
sei.lpDirectory = baseDir;
if (!ShellExecuteExW(&sei)) {
return false;
}
if (wait) {
HANDLE hProcess = sei.hProcess;
if (hProcess != 0) {
WaitForSingleObject(hProcess, INFINITE);
CloseHandle(hProcess);
}
}
return true;
}