Autorizzazione file Win32 che condivide violazione durante l'eliminazione di un file temporaneo
-
07-07-2019 - |
Domanda
Ho un'applicazione in cui sto cercando di implementare un "quot file sicuro con sovrascrittura" da:
- Creazione di un file (
A
) - Riempiendo
A
con i dati - Copia di
A
nella destinazione finale (B
) tramiteSHFileOperation
- Eliminazione di
A
utilizzandoDeleteFile
Tuttavia, al passaggio 4 DeleteFile
restituisce sempre ERROR_SHARING_VIOLATION. L'intero processo richiede millisecondi, quindi non riesco a immaginare chi altro interferirebbe con il mio file. Un paio di domande:
- Esiste una tecnica Win32 (C / C ++) migliore per eseguire quanto sopra?
- Come posso ottenere maggiori informazioni sull'altro processo " questo mi impedisce di eliminare il file
A
? - Come posso forzare ( wink wink nudge nudge ) a forzare Windows a cancellare il mio file temporaneo?
Qualsiasi altro suggerimento è il benvenuto
Soluzione
La mia ipotesi migliore è che è necessario un passaggio 2.5) Chiudere l'handle del file creato in 1)
Cosa stai usando per creare / aprire il file?
Se si utilizza CreateFile, assicurarsi di chiudere l'handle del file prima della chiamata da eliminare, oppure accertarsi di specificare il flag di condivisione FILE_SHARE_DELETE
.
HANDLE hFile = CreateFile("C:\\test.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, NULL);
Potresti anche voler semplificare la tua copia del codice file usando l'API Win32 CopyFile .
Altri suggerimenti
Un modo per eliminare il file sarebbe quello di aprirlo con FILE_FLAG_DELETE_ON_CLOSE
che richiederà al sistema operativo di eliminare automaticamente il file dopo la chiusura dell'ultimo handle. Se crei il file con FILE_SHARE_READ
, SHFileOperation
dovrebbe essere in grado di leggerlo per copiarlo, quindi puoi immediatamente chiudere l'handle al file. Quando la shell chiude il suo handle sul file, il file verrà automaticamente eliminato.
-
Prova a utilizzare Handles.exe da www.sysinternals.com per vedere se e come il file è in uso.
-
È possibile utilizzare GetLastError e FormatMessage per ottenere ulteriori informazioni sull'ultima funzione non riuscita:
Alcuni codici di esempio:
char tx2[1024];
DWORD l;
if(l = GetLastError())
{
LPVOID lpMessageBuffer = 0;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
l,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
(LPTSTR) &lpMessageBuffer,
0,
NULL
);
SetLastError(0);
MessageBox(NULL, tx2, "MyApplication", MB_ICONINFORMATION | MB_OK | (MB_SETFOREGROUND | MB_TOPMOST | MB_TASKMODAL));
}