描述:
在程序中我先把一个文件放到一个目录下,用shellexecute他(各种格式),在用户手动关闭此文件时,我需要用程序把他删除掉。关键就是不知道此文件何时被关闭。
解决方案1:
一楼正解 像是MSDN的例程
/*等待调用程序结束
SHELLEXECUTEINFO exeInfo;
exeInfo.cbSize = sizeof(SHELLEXECUTEINFO);
exeInfo.fMask = (SEE_MASK_DOENVSUBST|SEE_MASK_FLAG_DDEWAIT|0x04000000|SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NO_CONSOLE);
exeInfo.hwnd = NULL;
exeInfo.lpVerb = "open";
exeInfo.lpFile = (LPCTSTR)"文件路径";
exeInfo.lpParameters = NULL;
exeInfo.lpDirectory = NULL;
exeInfo.nShow = SW_SHOWNORMAL;
exeInfo.hInstApp = NULL;
exeInfo.lpIDList = NULL;
exeInfo.lpClass = NULL;
exeInfo.hkeyClass = NULL;
exeInfo.dwHotKey = NULL;
exeInfo.hMonitor = NULL;
exeInfo.hIcon = NULL;
exeInfo.hProcess = NULL;
::ShellExecuteEx(&exeInfo);//执行后 主程会被挂起 等待被调用程序结束 才继续执行
if(exeInfo.hProcess)
{
::WaitForSingleObject(exeInfo.hProcess,INFINITE);
::CloseHandle(exeInfo.hProcess);
}
*/
这问题比较麻烦,想不出完美的解决方案。
软件“打开”文件通常是CreateFile、读出数据然后就CloseHandle了,后面需要时会再次CreateFile、CloseHandle,所以不能根据文件的状态来判断文件是否被软件“打开”。
很多软件在打开了一个文件之后,再打开其它文件都使用同一个进程,这种情况ShellExecuteEx不能得到进程句柄,CreateProcess创建的进程可能很快就会退出,而文件由另一进程来打开。
比较可靠一点的方法是Hook打开文件和读文件操作,判断读文件的进程结束后再删除文件。
也可以考虑用SetWindowsHookEx的方式,在启动程序后,记录新创建的窗口,当窗口关闭后删除文件。这种方法的可靠性差一些。
用 ShellExecuteEx 吧,这样打开的进程的句柄会填充到你传递的结构体里面,然后通过 WaitForSingleObject(sei.hProcess, ...) 来等待进程信号,当打开的进程结束时会收到这个信号。或者随时调用GetExitCodeProcess来检测进程的返回码,也能判断进程是否退出。