12
votes

Est-il possible de contourner un verrouillage de fichier en C # lorsqu'un autre thread / processus utilise inutilement une serrure exclusive?

Y a-t-il un moyen de contourner ou de retirer le verrou de fichier maintenu par un autre fil sans tuer le fil?

J'utilise une bibliothèque tierce partie dans mon application qui effectue les opérations lecture seule sur un fichier. J'ai besoin d'un deuxième fil, lire le fichier en même temps pour extraire des données supplémentaires que la bibliothèque tiers n'expose pas. Malheureusement, la bibliothèque tierce partie a ouvert le fichier à l'aide d'un verrou en lecture / écriture et je reçois donc l'habituel "Le processus ne peut pas accéder au fichier ... car il est utilisé par une autre procédure" Exception.

Je voudrais éviter de pré-charger le fichier entier avec mon thread car le fichier est important et causerait des retards indésirables dans le chargement de ce fichier et une utilisation en excès de mémoire. La copie du fichier n'est pas pratique en raison de la taille des fichiers. Pendant le fonctionnement normal, deux threads frappant le même fichier ne causeraient aucun problème significatif sur la contention / performance de l'IO. Je n'ai pas besoin de synchronisation de temps parfait entre les deux threads, mais ils doivent lire les mêmes données en une demi-seconde de l'autre.

Je ne peux pas changer la bibliothèque tiers.

Y a-t-il des travaux autour de ce problème?


3 commentaires

Un verrou est un verrou - s'il y avait, ce ne serait pas une serrure ...


Et comme avec de nombreux serrures, il semble que certains développeurs de bibliothèques ne comprennent pas que moins. :-) Je serais aussi content d'un travail intelligent.


Un coup long: pouvez-vous ouvrir ce fichier comme partagé avant votre bibliothèque tierce? Peut-être qu'ils ont mis en œuvre du mécanisme de secours.


7 Réponses :



1
votes

Cela ne traite pas directement de votre situation, mais un outil comme Unlocker achève ce que vous essayez de faire, mais via une interface utilisateur de Windows.


0 commentaires

2
votes

En bref, vous ne pouvez rien faire du verrouillage du fichier par une tierce partie. Vous pouvez vous éloigner de la réponse de Richard E ci-dessus qui mentionne le déverrouillage utilitaire.

Une fois que la tierce partie ouvre un fichier et définit la serrure dessus, le système sous-jacent donnera cette tierce partie une serrure pour s'assurer qu'aucun autre processus ne peut y accéder. Il y a deux trains de pensée à ce sujet.

  • Utilisation d'une injection DLL pour corriger le code pour définir explicitement la serrure ou le déséquiper. Cela peut être dangereux car vous voulez jouer avec la stabilité d'un autre processus et finir éventuellement à creuser le processus et au chagrin. Pensez-y, le système sous-jacent à garder une trace des fichiers ouverts par un processus..dll injection au point et corrigez le code - cela nécessite des connaissances techniques pour déterminer quel processus vous souhaitez injecter au moment de l'exécution et modifier les drapeaux. Lors de l'interception de l'appel de l'API Win32 OpenFile (...) .
  • Comme cela a été étiqueté comme .NET, pourquoi ne pas démonter la source de la tierce partie dans .il Fichiers et modifier le drapeau pour le verrou à partager, reconstruire la bibliothèque en recompilant tous .il Fichiers de retour dans une DLL . Bien entendu, cela nécessiterait de raconter autour du code où l'ouverture du fichier se déroule dans une classe quelque part.

    Regardez le podcast ici . Et jetez un coup d'œil ici qui explique comment faire la deuxième option mise en évidence ci-dessus, ici .

    J'espère que cela aide, Meilleures salutations, Tom.


0 commentaires

1
votes

Tout hack de niveau bas pour le faire peut entraîner une collision de fil, une corruption de fichier ou etc. p>

Par conséquent, j'ai pensé mentionner la prochaine meilleure chose, attendez-vous simplement votre tour et votre sondage jusqu'à ce que le fichier ne soit pas verrouillé: HTTPS: //stackoverflow.com/a/11060322/495455 p>

p>


Je ne pense pas que ce 2e conseil aidera, mais la chose la plus proche (que je connaisse) serait DemandeReadFileIO : P>

IntSecurity.DemandReadFileIO(filename);

internal static void DemandReadFileIO(string fileName) 
{
   string full = fileName;            
   full = UnsafeGetFullPath(fileName); 
   new FileIOPermission(FileIOPermissionAccess.Read, full).Demand();
}

0 commentaires

1
votes

Je pense que ceci est un problème qui peut être résolu avec C ++. Il est gênant mais au moins cela fonctionne (comme discuté ici: Win32 C / C ++ Lire les données d'un fichier" verrouillé ")

Les étapes sont:

  1. Ouvrez le fichier avant la troisième bibliothèque avec FSOPEN et le drapeau _SHENYNO
  2. Ouvrez le fichier avec la troisième bibliothèque
  3. Lire le fichier dans votre code

    Vous pouvez également être intéressé par ces liens:

    1. appeler c ++ de c # ( possible d'appeler C ++ code de C #? )
    2. la liaison intérieure de ce message avec un échantillon ( http://blogs.msdn.com/b/borisj/archive/2006/09/28/769708.aspx )

0 commentaires

1
votes

Avez-vous essayé de faire une copie factice du fichier avant que votre bibliothèque tiers ne reçoive une prise de cela ... Ensuite, utilisez la copie réelle pour vos manipulations, ce ne serait considéré que si le fichier dont nous parlons est assez petit. Mais c'est une sorte de triche :) bonne chance


0 commentaires

1
votes

Si le fichier est verrouillé et n'est pas utilisé, vous avez un problème avec la manière dont votre mécanisme de verrouillage / déverrouillage de fichier fonctionne. Vous ne devez verrouiller qu'un fichier lorsque vous le modifiez, puis vous le déverrouillez immédiatement pour éviter les situations comme celle-ci.


0 commentaires