在日常工作中用到的一些知识,很久没有总结过,前几日参加一个会议,很是无聊。自己思索着自己这两年来所做过的东西,写着写着居然也写下了 100 个知识点。想把它一条一条总结下来,动笔总不是很容易。就拿这篇文章作为第一篇。
很多东西取之于网络,也有一些自己的心得。才疏学浅,就当一个知识梳理的过程吧。
第一篇 SHELLEXECUTEINFO 和 ShellExecuteEx 的使用
使用 SHELLEXECUTEINFO 和 ShellExecuteEx ,我也主要是在 cab 包的安装时使用的。基本上是这样使用的,如下:
SHELLEXECUTEINFO ShellInfo ;
memset (&ShellInfo , 0, sizeof (ShellInfo ));
ShellInfo .cbSize = sizeof (ShellInfo );
ShellInfo .hwnd = NULL ;
ShellInfo .lpVerb = _T ("open" );
ShellInfo .lpFile = szFilePath ;
ShellInfo .nShow = SW_SHOWNORMAL ;
ShellInfo .fMask = SEE_MASK_NOCLOSEPROCESS ;
BOOL bResult = ShellExecuteEx (&ShellInfo );
在 MSDN 中,它这样定义:
Contains information used by ShellExecuteEx
原型如下:
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;
参数详解:
cbSize
结构大小,以字节为单位。
fMask
一个标志数组,用来设置其他成员的有效性。
hwnd
可选。执行 ShellExecuteEx 的窗口句柄,可设为 NULL 。
lpVerb
指定执行的动作,包括: edit , explore , find , open , print , properties
lpFile
以 /0 结尾的字符串,指出 lpVerb 的操作对象的路径,被系统支持的操作包括文本的 open 、 print 等
lpParameters
可选。运行 / 打开程序的参数,如果打开的是一个文档,则该项无效
lpDirectory
可选。指明工作目录的名字,成员没有说明,则默认为当前目录
nShow
必须。指定打开的程序的显示方式,为 SW_ 值中的一个。
hInstApp
【 out 】如果设置 SEE_MASK_NOCLOSEPROCESS S 值并且 ShellExecuteEx 调用成功,则该项的值大于 32 ,如果调用失败,则将设置为 SE_ERR_XXX 的错误值。
lpIDList
一个 ITEMIDLIST 结构的地址,用来存储成员的特别标识符,当 fMask 不包括 SEE_MASK_IDLIST
或 SEE_MASK_INVOKEIDLIST
时该项被忽略
lpClass
用以指明文件类别的名字或 GUID ,当 fMask 不包括 SEE_MASK_CLASSNAME
时该项被忽略
hkeyClass
获得已在系统注册的文件类型的 Handle ,当 fMask 不包括 SEE_MASK_HOTKEY
时该项被忽略
dwHotKey
程序的热键关联,低位存储虚拟关键码( Key Code ),高位存储修改标志位 (HOTKEYF_) ,修改标志为( modifier flags )的详细列表请看 WM_SETHOTKEY 消息的描述,当 fmask 不包括 SEE_MASK_HOTKEY
时该项被忽略
DUMMYUNIONNAME
hIcon
取得对应文件类型的图标的 Handle ,当 fMask 不包括 SEE_MASK_ICON 时该项被忽略
hMonitor
将文档显示在显示器上的 Handle ,当 fMask 不包括 SEE_MASK_HMONITOR 时该项被忽略
hProcess
指向新启动的程序的句柄。若 fMask 不设为 SEE_MASK_NOCLOSEPROCESS
则该项值为 NULL 。但若程序没有启动,即使 fMask 设为 SEE_MASK_NOCLOSEPROCESS
,该值也仍为 NULL 。
功能 : Performs an operation on a specified file 。 对指定应用程序执行某个操作
原型:
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 是个不错的举措。
1 、打开一个应用程序
SHELLEXECUTEINFO ShellInfo ;
memset (&ShellInfo , 0, sizeof (ShellInfo ));
ShellInfo .cbSize = sizeof (ShellInfo );
ShellInfo .hwnd = NULL ;
ShellInfo .lpVerb = _T ("open" );
ShellInfo .lpFile = szFilePath ; // 此处写执行文件的绝对路径
ShellInfo .nShow = SW_SHOWNORMAL ;
ShellInfo .fMask = SEE_MASK_NOCLOSEPROCESS ;
BOOL bResult = ShellExecuteEx (&ShellInfo );
2 、如何打开一个文档
程序代码如上
3 、如何打开一个网页
SHELLEXECUTEINFO ShellInfo ;
memset (&ShellInfo , 0, sizeof (ShellInfo ));
ShellInfo .cbSize = sizeof (ShellInfo );
ShellInfo .hwnd = NULL ;
ShellInfo .lpVerb = _T ("open" );
ShellInfo .lpFile = _T ("http://www.sina.com" );
ShellInfo .nShow = SW_SHOWNORMAL ;
ShellInfo .fMask = SEE_MASK_NOCLOSEPROCESS ;
BOOL bResult = ShellExecuteEx (&ShellInfo );
4 、如何启动一个程序,直到它运行结束?
SHELLEXECUTEINFO ShellInfo ;
memset (&ShellInfo , 0, sizeof (ShellInfo ));
ShellInfo .cbSize = sizeof (ShellInfo );
ShellInfo .hwnd = NULL ;
ShellInfo .lpVerb = _T ("open" );
ShellInfo .lpFile = szFilePath ;
ShellInfo .nShow = SW_SHOWNORMAL ;
ShellInfo .fMask = SEE_MASK_NOCLOSEPROCESS ;
ShellExecuteEx (&ShellInfo );
WaitForSingleObject(ShellInfo.hProcess,INFINITE);
1 、 MSDN
http://msdn.microsoft.com/en-us/library/bb759784(VS.85).aspx
http://msdn.microsoft.com/en-us/library/bb762154(VS.85).aspx
2 、 SHELLEXECUTEINFO 结构
http://kaweh.candy.blog.163.com/blog/static/36818772200827352870/
SHELLEXECUTEINFO 结构
在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;
union {
HANDLE hIcon;
HANDLE hMonitor;
} DUMMYUNIONNAME;
HANDLE hProcess;
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
在C#中其结构为
public struct SHELLEXECUTEINFO // 用于 ShellExecuteEx
{
public int cbSize;
public int fMask;
public int hwnd;
public string lpVerb;
public string lpFile;
public string lpParameters;
public string lpDirectory;
public int nShow;
public int hInstApp;
public int lpIDList;
public string lpClass;
public int hkeyClass;
public int dwHotKey;
public int hIcon;
public int hProcess;
}
参数详解:
cbSize
存储该结构的长度,以字节为单位。
fMask
一个标志数组,用来设置其他成员的有效性
SEE_MASK_CLASSKEY 0x3
SEE_MASK_CLASSNAME 0x1
SEE_MASK_CONNECTNETDRV 0x80
SEE_MASK_DOENVSUBST 0x200
SEE_MASK_FLAG_DDEWAIT 0x100
SEE_MASK_FLAG_LOG_USAGE 0x4000000
SEE_MASK_FLAG_NO_UI 0x400
SEE_MASK_HMONITOR 0x200000
SEE_MASK_HOTKEY 0x20
SEE_MASK_ICON 0x10
SEE_MASK_IDLIST 0x4
SEE_MASK_INVOKEIDLIST 0xC
SEE_MASK_NOASYNC 0x100000
SEE_MASK_NOCLOSEPROCESS 0x40
SEE_MASK_NOZONECHECKS 0x800000
SEE_MASK_NO_CONSOLE 0x8000
SEE_MASK_UNICODE 0x100000
SEE_MASK_FILEANDURL 0x4000000
hwnd
调用这个 ShellExecuteEx 的窗口句柄
lpVerb
设定这个 ShellExecuteEx 的动作,包括:
edit
打开编辑器编辑文档,如果 lpFile 不是一个文档,则这个函数会失败
explore
以 lpFile 为路径打开资源管理器
find
从指定目录开始搜索
open
根据 lpFile 打开对应文件,该文件可以为可执行文件、文档或者文件夹
print
根据 lpFile 打印文档,若 lpFile 不是一个文档则该函数会失败
properties
显示文件或文件夹的属性
lpFile
以 /0 结尾的字符串,指出 lpVerb 的操作对象的路径,被系统支持的操作包括文本的 open 、 print 等,其中 print 要求必须有一个已经注册的打印机,而其他种类的文档会通过系统关联进行查询执行。若要设置一个空的 namespace ,则需要设置 fMask 的值为 see_mask_invokeidlist 。
注意: 若 see_mask_invokeidlist 已设置,则可以藉由 lpFile 或者 lpIDList 确定 item 的系统路径或者 PIDL
lpParameters
运行 / 打开程序的参数,如果打开的是一个文档,则该项无效
lpDirectory
指明工作目录的名字,成员没有说明,则默认为当前目录
nShow
说明 ShellExecuteEx 打开的程序将以什么形式出现
hInstApp
如果函数运行成功,该项的值将大于 32 ,否则会是下列错误对应的值
SE_ERR_FNF
没有找到文件
SE_ERR_PNF
没有找到路径
SE_ERR_ACCESSDENIED
拒绝访问
SE_ERR_OOM
内存不足
SE_ERR_DLLNOTFOUND
没有找到动态链接库
SE_ERR_SHARE
不能操作一个以打开的文件
SE_ERR_ASSOCINCOMPLETE
文件关联信息不完整
SE_ERR_DDETIMEOUT
DDE 操作超时
SE_ERR_DDEFAIL
DDE 操作失败
SE_ERR_DDEBUSY
DDE 繁忙
SE_ERR_NOASSOC
没有找到文件关联
lpIDList
一个 itemidlist 结构的地址,用来存储成员的特别标识符,当 fMask 不包括 see_mask_idlist 或 see_mask_invokeidlist 时该项被忽略
lpClass
用以指明文件类别的名字或 GUID ,当 fMask 不包括 see_mask_classname 时该项被忽略
hkeyClass
获得已在系统注册的文件类型的 Handle ,当 fMask 不包括 see_mask_classkey 时该项被忽略
dwHotKey
程序的热键关联,低位存储虚拟关键码( Key Code ),高位存储修改标志位 (HOTKEYF_) ,修改标志为( modifier flags )的详细列表请看 wm_sethotkey 消息的描述,当 fmask 不包括 see_mask_hotkey 时该项被忽略
DUMMYUNIONNAME
hIcon
取得对应文件类型的图标的 Handle ,当 fMask 不包括 SEE_MASK_ICON 时该项被忽略
hMonitor
将文档显示在显示器上的 Handle ,当 fMask 不包括 SEE_MASK_HMONITOR 时该项被忽略
hProcess
用于进行 return 操作的成员,若 fMask 不设为 see_mask_nocloseprocess 则该项值为 null ,即使 fMask 设为 see_mask_nocloseprocess ,若没有进程启动,该项值仍为 null 。即没有新的进程启动,则该项值一只为 null
3 、说说 ShellExecuteEx
http://blog.csdn.net/kesalin/category/242901.aspx
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 这个函数用来执行某个应用程序。