I'm having this odd error. In my program you can open files that rely on temporary files, thus I need a way to automatically remove them when the (external) program closes. By this I mean that my program A opens a file B somewhere on the disc and the file B is opened with its associated program C. When C is closed, the file B is automatically removed.
So far this works fine by using WaitForSingleObject() on the process handle you get from the call to ShellExecuteEx().
It works almost perfectly fine, however in certain cases when running a file it tends to open in the same program as an existing file instead of creating a new. One example is mp3's, if you have an mp3 loaded in winamp and try to open another it's loaded in the existing winamp.
When this happens the last opened file jumps out of WaitForSingleObject() almost immediately instead of waiting until winamp closes. Here lies my problem, why does it exit immediately? Is it impossible to have 2 separate threads waiting for the same program to close or am I just making some mistake?
It's a lot of source code, but I guess some of the relevant parts are here:
(Just a structure passed to the thread function)
Code:
struct FILE_PROCESS
{
FILE_PROCESS(HANDLE NewHandle, CONST std::string& NewFileName)
{
Handle = NewHandle;
FileName = NewFileName;
}
HANDLE Handle;
std::string FileName;
};
(Thread that removes the file when closed)
Code:
DWORD CALLBACK DestroyFileWhenNeccessary(DWORD Parameter)
{
std::string FileName;
HANDLE ProcessHandle;
FILE_PROCESS* FileProcessPointer;
FileProcessPointer = reinterpret_cast<FILE_PROCESS*>(Parameter);
if(FileProcessPointer == NULL)
{
ExitThread(0);
return 0;
}
ProcessHandle = FileProcessPointer->Handle;
FileName = FileProcessPointer->FileName;
delete FileProcessPointer;
if(WaitForSingleObject(ProcessHandle, INFINITE) == WAIT_FAILED)
{
ExitThread(0);
return 0;
}
MpqWindow.RemoveTemporaryFile(FileName);
ExitThread(0);
return 0;
}
(code that loads the file and creates the thread)
Code:
if(!ExportMpqFile(FileName, TemporaryFileName))
{
return FALSE;
}
AddTemporaryFile(TemporaryFileName);
ZeroMemory(&Info, sizeof(SHELLEXECUTEINFO));
Info.cbSize = sizeof(SHELLEXECUTEINFO);
Info.fMask = SEE_MASK_NOCLOSEPROCESS;
Info.hwnd = Window;
Info.lpVerb = "open";
Info.lpFile = TemporaryFileName.c_str();
Info.hInstApp = GetModuleHandle(NULL);
Info.nShow = SW_SHOW;
if(ScriptExtention(FileName))
{
Info.lpFile = "Notepad";
Info.lpParameters = TemporaryFileName.c_str();
}
if(!ShellExecuteEx(&Info))
{
Error.SetMessage("Unable to open \"" + TemporaryFileName + "\"!\nProbably an unassociated extention!");
RemoveTemporaryFile(TemporaryFileName);
return FALSE;
}
ZeroMemory(&Attributes, sizeof(SECURITY_ATTRIBUTES));
Attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
ThreadHandle = CreateThread(&Attributes, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(DestroyFileWhenNeccessary),
new FILE_PROCESS(Info.hProcess, TemporaryFileName), 0, &ThreadId);
if(ThreadHandle == NULL)
{
Error.SetMessage("Unable to create thread!");
RemoveTemporaryFile(TemporaryFileName);
return FALSE;
}