Utilisation du .NET Framework pour identifier les processus de verrouillage de fichiers
Traditionnellement, identifier le processus spécifique détenant un verrou de fichier dans le framework .NET représentait un défi de taille. Cependant, avec les avancées modernes de Windows, l'API Restart Manager fournit désormais un mécanisme fiable pour suivre ces informations.
Mise en œuvre de la solution :
L'extrait de code suivant offre une méthode robuste pour identifier les processus qui ont établi des verrous sur un fichier désigné :
<code class="language-csharp">public static List<Process> IdentifyFileLockers(string filePath) { uint sessionHandle; string sessionKey = Guid.NewGuid().ToString(); List<Process> lockedByProcesses = new List<Process>(); int result = RmStartSession(out sessionHandle, 0, sessionKey); if (result != 0) throw new Exception("Failed to initiate restart session. Unable to identify file locker."); try { const int ERROR_MORE_DATA = 234; uint processesNeeded = 0, processesReturned = 0, rebootReasons = RmRebootReasonNone; string[] resources = new string[] { filePath }; // Targeting a single resource. result = RmRegisterResources(sessionHandle, (uint)resources.Length, resources, 0, null, 0, null); if (result != 0) throw new Exception("Resource registration failed."); //Note: A race condition exists here. The initial RmGetList() call returns // the total process count. Subsequent RmGetList() calls to retrieve // actual processes might encounter an increased count. result = RmGetList(sessionHandle, out processesNeeded, ref processesReturned, null, ref rebootReasons); if (result == ERROR_MORE_DATA) { // Allocate an array to store process information. RM_PROCESS_INFO[] processInfoArray = new RM_PROCESS_INFO[processesNeeded]; processesReturned = processesNeeded; // Retrieve the process list. result = RmGetList(sessionHandle, out processesNeeded, ref processesReturned, processInfoArray, ref rebootReasons); if (result == 0) { lockedByProcesses = new List<Process>((int)processesReturned); // Iterate through results and populate the return list. for (int i = 0; i < processesReturned; i++) { try { //Attempt to get the process by ID. May fail if the process is already gone. Process p = Process.GetProcessById(processInfoArray[i].Process.dwProcessId); lockedByProcesses.Add(p); } catch (ArgumentException) { } // Ignore processes that no longer exist. } } } } finally { RmEndSession(sessionHandle); } return lockedByProcesses; }</code>
Remarque importante : L'exécution de ce code nécessite un accès non privilégié au registre. Si le processus ne dispose pas des autorisations nécessaires, il est recommandé d'implémenter un mécanisme IPC (par exemple, un canal nommé) pour déléguer l'appel à un processus privilégié.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!