我用ShellExecuteEx() 执行一个外部程序, 希望的到这个程序进程句柄, 然后WaitForSingleObject等待它退出, 我执行的程序是用 "Open"方式打开一个文件, 即由系统根据文件扩展名来自动启动与该扩展名关联的程序(打开方式中设定的程序), 但如果我打开的文档是一个已经启动的多文档程序打开的话, 我得不到那个进程得句柄, 我就没办法知道那个进程什么时候退出, 我该怎么做, 请高手指点.
调试欢乐多
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
{
STARTUPINFO si;
PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) ); // 创建子进程
if( !CreateProcess( NULL, // No module name (use command line).
"MyChildProcess", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
ErrorExit( "CreateProcess failed." );
} // 等待子进程退出
WaitForSingleObject( pi.hProcess, INFINITE ); // 关闭句柄
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
CreateToolhelp32Snapshot和它的相关函数,可以枚举WIN32进程表里的所有进程,应该够用了吧.class JProcessInfo
{
public:
JProcessInfo();
virtual ~JProcessInfo();
BOOL FindProcessInfo(const CString& cstrProcessName);
BOOL NeedTerminateProcess();
void GetUpdateSystemName(const CString&);
void ClearProcessInfo();
private:
HANDLE m_hProcessSnap;
PROCESSENTRY32 m_pe32;
HANDLE m_hProcess;
HANDLE m_hRealProcess;
CString m_cstrSystemName;
};JProcessInfo::JProcessInfo():m_hProcessSnap(NULL),m_hProcess(NULL),m_hRealProcess(NULL)
{
memset(&m_pe32,0,sizeof(m_pe32));
m_pe32.dwSize = sizeof(PROCESSENTRY32);
m_hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
}JProcessInfo::~JProcessInfo()
{
try
{
if (m_hRealProcess)
::CloseHandle(m_hRealProcess);
::CloseHandle(m_hProcessSnap);
}
catch (...)
{
0;
}
}BOOL JProcessInfo::FindProcessInfo(const CString& cstrProcessName)
{
if (m_hProcessSnap != INVALID_HANDLE_VALUE)
{
if (::Process32First(m_hProcessSnap,&m_pe32))
{
do
{
HANDLE m_hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,m_pe32.th32ProcessID);
CString cstrAppName(m_pe32.szExeFile);
if (cstrAppName == cstrProcessName)
{if (m_pe32.th32ProcessID != ::GetCurrentProcessId() && m_cstrSystemName != cstrProcessName)
{
::TerminateProcess(m_hProcess,0);
if (::WaitForSingleObject(m_hProcess,INFINITE) == WAIT_OBJECT_0)
{
return TRUE;
}
}
else
m_hRealProcess = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,m_pe32.th32ProcessID);
}
}
while (::Process32Next(m_hProcessSnap,&m_pe32));
if (m_hRealProcess)
return TRUE;
return FALSE;
}
}
return FALSE;
}BOOL JProcessInfo::NeedTerminateProcess()
{
if (!m_hRealProcess)
return FALSE;
return ::TerminateProcess(m_hRealProcess,0);
}void JProcessInfo::GetUpdateSystemName(const CString& pm)
{
m_cstrSystemName = pm;
}void JProcessInfo::ClearProcessInfo()
{
m_cstrSystemName.Empty();
}