ошибка при одновременном доступе к файлу
От: Аноним  
Дата: 25.05.11 10:45
Оценка:
Приветствую всех!

Столкнулся с проблемой, которую никак не могу решить, прошу помочь знающих.

Задача: по нажатию кнопки показать файл из файлохранилища.
Решение: копируем файл во временную папку, показываем с помощью 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);
}

Помогите заставить работать это чудо правильно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.