ShellExecuteEx启动WORD进程关不掉的处理
来源:互联网 发布:干部网络培训挂机软件 编辑:程序博客网 时间:2024/05/17 00:52
需求:启动一个WORD进程给用户操作,用户关闭进程后进行后续操作
一般处理方法,用ShellExecuteEx或者CreateProcess函数启动进程,然后等待进程退出。代码如下:
m_localFilePath="C:\DocExc006926.doc";
SHELLEXECUTEINFO ShExecInfo ;
memset(&ShExecInfo,0,sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "open";
ShExecInfo.lpFile =(LPCTSTR)m_localFilePath;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_NORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINATE);
但是在用这种方式处理WORD的时间出现了一个大问题,当关闭WORD的时候,WORD进入了不响应状态,CPU占用率90%+,界面无法绘制,调用程序也失去响应。
在网上找资料,在大富翁论坛上有人讲到这个问题,他们是DELPHI的实现。把WaitForSingleObject的参数INFINATE改成一个特定的值,循环检测。
While (WaitForSingleObject(ShExecInfo.hProcess,1000)=WAIT_TIMEOUT) do
Application.ProcessMessages();
End
我比葫芦画瓢,只是C++中并没有Application.ProcessMessages这样的函数,我用Sleep(1000)来代替,发现并没有效果,而如果我在循环里面用MessageBox函数弹一个模式窗口而且不关掉这个窗口的话Word就可以正常关闭。看来原因不是在循环检测上面,而是在ProcessMessages处理了消息队列。由此猜测WORD关闭的时候要向调用者发消息并等待响应的原因,所以解决这个问题关键在于处理消息队列,即实现ProcessMessages的功能。
在BBS上一位仁兄的启发下我找到Delphi CLX框架的源码,然后读之,发现了三个关键的Windows API函数。
BOOL PeekMessage(
LPMSG lpMsg, // message information
HWND hWnd, // handle to window
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax, // last message
UINT wRemoveMsg // removal options
);
这个函数是分派收到的消息,检查线程的消息队列,并获取消息
BOOL TranslateMessage(
CONST MSG *lpMsg // message information
);
这个函数是翻译实际的键盘消息为字符消息,字符消息送到该线程消息队列,用于下次调用GetMessage或者PeekMessage时读取。
LRESULT DispatchMessage(
CONST MSG *lpmsg // message information
);
这个函数将消息分派到窗口处理程序段。
最终的处理程序如下,这次没有WaitForSingleObject,而是使用了GetExitCodeProcess函数进程退出结果达到同样的轮询效果。
m_localFilePath="C:\DocExc006926.doc";
SHELLEXECUTEINFO ShExecInfo ;
memset(&ShExecInfo,0,sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "open";
ShExecInfo.lpFile =(LPCTSTR)m_localFilePath;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_NORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
DWORD exCode;
GetExitCodeProcess(ShExecInfo.hProcess,&exCode);
while(exCode==STILL_ACTIVE)
{
Sleep(10);
MSG msg;
memset(&msg,0,sizeof(MSG));
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetExitCodeProcess(ShExecInfo.hProcess,&exCode);
}
http://wking.ycool.com/post.680483.html
一般处理方法,用ShellExecuteEx或者CreateProcess函数启动进程,然后等待进程退出。代码如下:
m_localFilePath="C:\DocExc006926.doc";
SHELLEXECUTEINFO ShExecInfo ;
memset(&ShExecInfo,0,sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "open";
ShExecInfo.lpFile =(LPCTSTR)m_localFilePath;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_NORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINATE);
但是在用这种方式处理WORD的时间出现了一个大问题,当关闭WORD的时候,WORD进入了不响应状态,CPU占用率90%+,界面无法绘制,调用程序也失去响应。
在网上找资料,在大富翁论坛上有人讲到这个问题,他们是DELPHI的实现。把WaitForSingleObject的参数INFINATE改成一个特定的值,循环检测。
While (WaitForSingleObject(ShExecInfo.hProcess,1000)=WAIT_TIMEOUT) do
Application.ProcessMessages();
End
我比葫芦画瓢,只是C++中并没有Application.ProcessMessages这样的函数,我用Sleep(1000)来代替,发现并没有效果,而如果我在循环里面用MessageBox函数弹一个模式窗口而且不关掉这个窗口的话Word就可以正常关闭。看来原因不是在循环检测上面,而是在ProcessMessages处理了消息队列。由此猜测WORD关闭的时候要向调用者发消息并等待响应的原因,所以解决这个问题关键在于处理消息队列,即实现ProcessMessages的功能。
在BBS上一位仁兄的启发下我找到Delphi CLX框架的源码,然后读之,发现了三个关键的Windows API函数。
BOOL PeekMessage(
);
这个函数是分派收到的消息,检查线程的消息队列,并获取消息
BOOL TranslateMessage(
);
这个函数是翻译实际的键盘消息为字符消息,字符消息送到该线程消息队列,用于下次调用GetMessage或者PeekMessage时读取。
LRESULT DispatchMessage(
);
这个函数将消息分派到窗口处理程序段。
最终的处理程序如下,这次没有WaitForSingleObject,而是使用了GetExitCodeProcess函数进程退出结果达到同样的轮询效果。
m_localFilePath="C:\DocExc006926.doc";
SHELLEXECUTEINFO ShExecInfo ;
memset(&ShExecInfo,0,sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "open";
ShExecInfo.lpFile =(LPCTSTR)m_localFilePath;
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_NORMAL;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
DWORD exCode;
GetExitCodeProcess(ShExecInfo.hProcess,&exCode);
while(exCode==STILL_ACTIVE)
{
Sleep(10);
MSG msg;
memset(&msg,0,sizeof(MSG));
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetExitCodeProcess(ShExecInfo.hProcess,&exCode);
}
http://wking.ycool.com/post.680483.html
0 0
- ShellExecuteEx启动WORD进程关不掉的处理
- 关于提升某个进程的权限(ShellExecuteEx)
- 进程 等待 关闭 ShellExecuteEx WaitForSingleObject
- ShellExecuteEx提升子进程权限
- Linux启动中init进程的处理
- ShellExecuteEx的用法 .
- ShellExecuteEx的“副作用”
- ShellExecuteEx
- ShellExecuteEx
- ShellExecuteEx
- Linux启动中init进程的处理(转)
- 发现远程启动的挖矿进程后处理方法
- linux启动、进程、文本处理
- ShellExecute与ShellExecuteEx的用法
- ShellExecute与ShellExecuteEx的用法
- SHELLEXECUTEINFO 和 ShellExecuteEx的使用
- ShellExecute与ShellExecuteEx的用法
- ShellExecute与ShellExecuteEx的用法
- Teaching course1 : How to improve your code quality
- js函数3-作用域与作用域链
- POJ3660 Cow Contests,TYVJ2024 运动员身高
- 高扩展软件架构设计
- 4_scala_类相关
- ShellExecuteEx启动WORD进程关不掉的处理
- XML命名空间与DTD(愚见)
- 【转】ORACLE制作表时的“小计”和“合计” (ROLLUP)
- DynamicDataExchange(DDE)机制引发的卡死有一个bug
- android studio引用第三方库
- JavaScript —— Date() 函数方法
- dev -c++ 快捷键
- Oracle 检查表的数据变动
- 模拟Spring解析xml文件,以及实现IOC (DI)的示例