2010-12-14 79 views
3

Im utilisant l'API CreateFile et parfois échoue de manière aléatoire avec l'erreur: ERROR_SHARING_VIOLATION.CreateFile échoue avec l'erreur ERROR_SHARING_VIOLATION

J'ai googlé et il n'y a presque rien à propos de cette erreur. Ce qui est étrange, c'est que la prochaine fois, il est assez content d'ouvrir le même fichier.

Voici mon code:

void FileHandle::open(const char* fileName, FILE_MODE mode) 
{ 
    if (m_bIsOpen) 
     close(); 

    HANDLE fh = NULL; 

    DWORD dwDesiredAccess = GENERIC_READ; 
    DWORD dwShareMode = FILE_SHARE_READ; 
    DWORD dwCreationDisposition = OPEN_EXISTING; 

    switch (mode) 
    { 
    case FILE_READ: 
     break; 

    case FILE_WRITE: 
     dwDesiredAccess = GENERIC_WRITE; 
     dwShareMode = 0; 
     dwCreationDisposition = CREATE_ALWAYS; 
     break; 

    case FILE_APPEND: 
     dwDesiredAccess = GENERIC_WRITE; 
     dwShareMode = 0; 
     dwCreationDisposition = OPEN_ALWAYS; 
     break; 

    default: 
     throw gcException(ERR_INVALID, "The mode was invalid"); 
     break; 
    } 

    fh = CreateFile(fileName, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, 0, NULL); 

    if (!fh || fh == INVALID_HANDLE_VALUE) 
     throw gcException(ERR_INVALIDFILE, GetLastError(), gcString("Failed to open the file {0}", fileName)); 

    m_hFileHandle = fh; 
    m_bIsOpen = true; 

    if (mode == FILE_APPEND) 
    { 
     DWORD high = 0; 
     DWORD low = GetFileSize(fh, &high); 

     uint64 pos = (((uint64)high)<<32) + (uint64)low; 
     seek(pos); 
    } 
} 

que je fais quelque chose de mal ou est-il un problème avec l'api?

Edit: Im en utilisant le nom complet du fichier (par exemple C: \ somefile.txt) et le mode = FILE_Write

+0

Quel cas s'exécute lorsque l'appel échoue? Aussi, vous devriez vérifier seulement si le handle de fichier est égal à INVALID_HANDLE_VALUE, ne vérifiez pas s'il est NULL. Veuillez également déplacer l'appel GetLastError avant le lancer et le stocker dans un DWORD. –

+0

Peu importe si je le compare à NULL, le code d'erreur est 32 (pense que j'ai été mélangé avec et devrait être ERROR_SHARING_VIOLATION). – Lodle

+0

Utilisez le moniteur de processus (http://technet.microsoft.com/en-us/sysinternals/bb896645) et configurez un filtre pour le chemin d'accès au fichier que vous ouvrez. Vérifiez qu'aucun autre processus (par exemple, anti-malware, recherche de bureau, sauvegarde) ne l'ouvre. –

Répondre

6

Il n'y a rien de mal avec CreateFile - une violation de partage signifie que quelque chose d'autre a le même fichier ouvert. Ce qui pourrait être votre propre programme, si vous avez le fichier ouvert avec un mode de partage de 0, vous ne serez pas en mesure de l'ouvrir à nouveau.

Lorsque vous obtenez l'erreur, vous pouvez utiliser Process Explorer pour déterminer les processus dans lesquels le fichier est ouvert.

+0

Sa création d'un nouveau fichier qui n'a jamais existé auparavant et rien d'autre a le nom du nouveau fichier à ce stade (c'est un magasin de cache d'image). – Lodle

+1

J'ai juste découvert qu'une partie de mon code téléchargeait la même image deux fois dans deux threads différents, donc le premier thread ouvrirait le fichier et le second mourrait. – Lodle

1

Y at-il anti-virus sur la machine? Parfois, les opérations d'un AV (ou tout autre logiciel qui surveille les fichiers) et le calendrier peuvent entraîner des conflits de partage.

Ceci est particulièrement vrai si vous ouvrez un fichier existant pour un accès exclusif (ce serait le cas pour les cas FILE_WRITE et FILE_APPEND si le fichier existe déjà).

+0

No av. Happen environ 1 sur 20 va – Lodle

1

Je ne veux pas manquer de respect, mais je me suis tiré dans le pied de la semaine dernière sur quelque chose de similaire:

Êtes-vous rien que autre a le fichier ouvert d'une manière qui empêcherait l'accès requis? Dans mon cas, j'avais utilisé ctrl-Z dans une fenêtre de commande Linux pour suspendre un programme qui créait une connexion socket, puis je suis allé me ​​coucher. Le lendemain matin, après quelques changements simples, j'ai continué à recevoir des messages "Impossible de créer un socket: service en cours d'utilisation" lors de l'exécution du programme. Malheureusement, j'ai passé des heures à débugger ce que j'avais cassé. Une fois que j'ai tué le processus suspendu suspendu, ça a bien fonctionné.

0

Microsoft dit here que cela peut arriver et c'est à l'application de réessayer quand il le fait. Horride mais là vous allez.

+0

Liens vers des ressources externes sont encouragés, mais s'il vous plaît ajouter un contexte autour du lien afin que vos autres utilisateurs auront une idée de ce que c'est et pourquoi il est là.Toujours citer la partie la plus pertinente d'un lien important, dans le cas où le site cible est inaccessible ou va définitivement hors ligne. –