ShellExecuteInfo是Windows系统提供的一个结构体,能够启动外部程序,并可根据具体需要处理程序调用的结果。在程序开发中,这个结构体常常被用来处理文件打开和调用网页等操作。本文将详细介绍ShellExecuteInfo的使用方法。
一、ShellExecuteInfo结构体
ShellExecuteInfo结构体包含了Windows系统中启动外部进程所需要的各种参数,其定义如下:
```c
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;
HANDLE hIcon;
HANDLE hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
```
结构体中各个参数的含义如下:
- cbSize:结构体大小,单位字节;
- fMask:标识结构体的哪些成员是有效的;
- hwnd:父窗口句柄;
- lpVerb:操作参数,默认为“Open”
- lpFile:被执行的文件名;
- lpParameters:程序运行时的参数;
- lpDirectory:程序执行的起始目录;
- nShow:程序窗口的显示方式;
- hInstApp:启动的程序的实例句柄;
- lpIDList:文件在Shell内部标示的PIDL;
- lpClass:文件的类型;
- hkeyClass:在“HKEY_CLASSES_ROOT”中的类型关联的键句柄;
- dwHotKey:打开这个文件时热键值;
- hIcon:文件图标的句柄;
- hProcess:被执行程序的句柄。
二、ShellExecute函数
ShellExecute函数是Windows系统的API函数,其定义如下:
```c
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
```
ShellExecute函数可以启动指定的可执行程序,或用指定的应用程序打开指定的文档文件(文件不一定需要是可执行文件),这个函数的参数传递方式和ShellExecuteInfo结构体类似。
三、使用ShellExecute函数启动进程
ShellExecute函数启动处理程序的示例代码如下:
```c
ShellExecute(
NULL,//父窗口句柄,此处为空
_T("open"),//操作参数,此处为“open”
_T("C:\\Windows\\system32\\notepad.exe"),//被执行的文件,启动记事本
NULL,//任意自定义参数
NULL,//起始目录,此处为空
SW_SHOWNORMAL//窗口默认状态为“正常显示”
);
```
以上代码启动了Windows自带的记事本程序。当然,我们还可根据自己的需求选择调用其他可执行程序。
四、使用ShellExecuteInfo结构体启动进程
使用ShellExecuteInfo结构体启动进程时,需要先给结构体赋值,然后调用ShellExecuteEx函数来启动进程。ShellExecuteEx函数与ShellExecute函数的一个最大区别是ShellExecuteEx函数能够得到进程启动的相关信息。
下面是使用ShellExecuteInfo结构体启动进程的示例代码:
```c
SHELLEXECUTEINFO sei;
ZeroMemory(&sei,sizeof(sei));
sei.cbSize = sizeof(sei);
sei.lpFile = _T("notepad.exe");//被执行程序
sei.lpDirectory = _T("C:\\Windows\\system32");//程序的起始目录
sei.lpVerb = _T("open");//操作参数
sei.nShow = SW_SHOWNORMAL;//窗口显示方式
ShellExecuteEx(&sei);
```
上述代码等价于前面使用ShellExecute函数启动进程的方法。
五、使用ShellExecuteInfo结构体获取进程相关信息
除了能够启动进程外,ShellExecuteInfo结构体还能够得到进程启动的一些基本信息,包括进程的句柄、进程ID等。
下面是使用ShellExecuteInfo结构体获取进程相关信息的示例代码:
```c
SHELLEXECUTEINFO sei;
ZeroMemory(&sei,sizeof(sei));
sei.cbSize = sizeof(sei);
sei.lpFile = _T("notepad.exe");//被执行程序
sei.lpDirectory = _T("C:\\Windows\\system32");//程序的起始目录
sei.lpVerb = _T("open");//操作参数
sei.nShow = SW_SHOWNORMAL;//窗口显示方式
sei.fMask = SEE_MASK_NOCLOSEPROCESS;//获取进程句柄
if(!ShellExecuteEx(&sei))
{
return FALSE;
}
WaitForSingleObject(sei.hProcess,INFINITE);//等待进程退出
CloseHandle(sei.hProcess);//关闭进程句柄
```
上述代码使用了SEE_MASK_NOCLOSEPROCESS这个常量,这个常量用于告知操作系统在执行进程的同时,需要获取进程句柄。
最后,等待进程的退出和关闭进程句柄是保证程序稳定性和安全性的必要操作。
六、使用ShellExecuteInfo结构体处理文档关联
Windows系统会根据文件的扩展名,关联相应的程序来打开这个文件,但在有些情况下人们需要自定义文件扩展名的关联。ShellExecuteInfo结构体也可以帮助我们实现这一操作。
下面是使用ShellExecuteInfo结构体处理文档关联的示例代码:
```c
SHELLEXECUTEINFO sei;
ZeroMemory(&sei,sizeof(sei));
sei.cbSize = sizeof(sei);
sei.lpFile = _T(".txt");//文件扩展名
sei.lpVerb = _T("open");//操作参数
sei.fMask = SEE_MASK_CLASSKEY;
if(ShellExecuteEx(&sei))//调用Windows文档关联
{
return TRUE;
}
else//如果文档关联没有被注册,则注册
{
HKEY hKey;
RegOpenKey(HKEY_CLASSES_ROOT,_T(".txt"),&hKey);
TCHAR szExePath[MAX_PATH];
GetModuleFileName(NULL,szExePath,MAX_PATH);
//注册Open操作
RegSetValue(hKey,_T(""),REG_SZ,_T("Text File"),(DWORD)_tcslen(_T("Text File"))*sizeof(TCHAR));
HKEY hKey2;
RegCreateKey(hKey,_T("shell\\open\\command"),&hKey2);
RegSetValue(hKey2,_T(""),REG_SZ,szExePath,(DWORD)_tcslen(szExePath)*sizeof(TCHAR));
RegCloseKey(hKey);
RegCloseKey(hKey2);
return TRUE;
}
```
上述代码先尝试调用Windows文档关联,如果关联已经存在,那么会由系统来打开这种类型的文件,否则就自定义关联,并将文件的打开操作映射到当前程序。
七、结语
ShellExecuteInfo结构体是一个强大的API函数,它可以满足我们在程序开发中启动进程的需求,并提供了获取进程相关信息和处理文件关联的功能。熟练掌握这个API能够使我们的程序更加完善和实用。