Приветствую всех!
Столкнулся с проблемой, которую никак не могу решить, прошу помочь знающих.
Задача: по нажатию кнопки показать файл из файлохранилища.
Решение: копируем файл во временную папку, показываем с помощью ShellExecute, удаляем временный файл.
Когда удалять временный файл? Можно, конечно, подождать когда закончится дочерний процесс, запущенный ShellExecute, но как получить его хендл?
К тому же если запускающий процесс закончит работу раньше дочернего, будет нехорошо.
Вообще не удалять, запуская раз в месяц сборщик мусора — тоже не вариант, файлы могут занимать сотни мегабайт.
Пытаюсь решить задачу так: создаю временный, расшаренный на чтение, запись и удаление файл функцией CreateFile с ключом FILE_FLAG_DELETE_ON_CLOSE,
копирую данные из файла в хранилище, запускаю ShellExecute, закрываю хэндл файла.
Дочерний процесс пишет, что файл занят другим приложением. Подставив свою прожку определяю код ошибки (GetLastError) после попытки открыть этот файл — 32 (ERROR_SHARING_VIOLATION)
Открываю новый хендл на тот же файл, закрываю старый. Открытие файла дочерним процессом дает ошибку 5 (Access is denied).
Пробовал даже создать дескриптор защиты на полный доступ для всех — результат тот же.
Вот мой код:
void WINAPI ViewFile(char* from, char* to)
{
HANDLE hNew,hOld,hNewRead;
DWORD dwBytesRead, dwBytesWrite, dwFilePos;
char buff[32768];
int z;
hOld=CreateFile(from, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOld==INVALID_HANDLE_VALUE){MessageBox(0,"Can't open file from file storage","File error", MB_OK+MB_ICONERROR);goto cleanup;}
z=GetLastError();
hNew=CreateFile(to, FILE_APPEND_DATA+GENERIC_READ, FILE_SHARE_READ+FILE_SHARE_WRITE+FILE_SHARE_DELETE, NULL,CREATE_NEW, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_DELETE_ON_CLOSE, hOld);
if (hOld==INVALID_HANDLE_VALUE){MessageBox(0,"Can't create file to temporary folder","File error", MB_OK+MB_ICONERROR);goto cleanup;}
z=GetLastError();
while (ReadFile(hOld,buff,sizeof(buff),&dwBytesRead,NULL)&&dwBytesRead>0)
{
dwFilePos=SetFilePointer(hNew,0,0,FILE_END);
LockFile(hNew,dwFilePos,0,dwBytesRead,0);
WriteFile(hNew,buff,dwBytesRead,&dwBytesWrite,NULL);
UnlockFile(hNew,dwFilePos,0,dwBytesRead,0);
}
CloseHandle(hOld);
hNewRead=CreateFile(to, GENERIC_READ, FILE_SHARE_READ+FILE_SHARE_WRITE+FILE_SHARE_DELETE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, hOld);
//для предотвращения удаления файла оставшегося без ссылок
FlushFileBuffers(hNew);
CloseHandle(hNew);
Sleep(500); //если не подождать - файл удалится раньше запуска дочернего процесса
//ShellExecute(0,"open",to,0,0,3);
system("D:\\Документы_Несмачный\\MyProjects\\FileAccessTest\\Debug\\FileAccessTest.exe C:\\temp\\tmp\\zzz.zts");
z=GetLastError();
Sleep(500);
z=GetLastError();
CloseHandle(hNewRead);
}
Помогите заставить работать это чудо правильно.