public static Error CloseHandle(Process handleOwnerProcess, FileHandleInfo handle, Process currentProcess) { SafeProcessHandle remoteProcess = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, handleOwnerProcess.Id); bool result = NativeMethods.DuplicateHandle(remoteProcess.DangerousGetHandle(), handle.Handle, currentProcess.Handle, out SafeObjectHandle duplicateHandle, 0, false, DuplicateHandleOptions.CloseSourceHandle); if (!result) { return(Error.DuplicateHandleFails); } result = NativeMethods.GetHandleInformation(duplicateHandle.DangerousGetHandle(), out HandleFlag flag); if (!result) { return(Error.GetHandleInformationFails); } if (flag == HandleFlag.ProtectFromClose) { return(Error.HandleProtectedFromClosed); } result = NativeMethods.CloseHandle(duplicateHandle.DangerousGetHandle()); if (!result) { int lastError = Marshal.GetLastWin32Error(); return((Error)lastError); } return(Error.None); }
private static bool UnlockFiles(string[] files, Process currentProcess) { bool found = false; var processes = Unlocker.FindLockerProcesses(files); foreach (RM_PROCESS_INFO info in processes) { Console.WriteLine($"Closing handle locked by {info.strAppName}..."); using (SmartPtr sptr = SystemInformation.GetSystemHandleInformation()) { var information = (SystemHandlesInformation)Marshal.PtrToStructure(sptr.Pointer, typeof(SystemHandlesInformation)); int handleCount = information.Count; var process = Process.GetProcessById(info.Process.dwProcessId); var infoEnumerator = ProcessHelper.GetCurrentProcessOpenFilesEnumerator(info.Process.dwProcessId, sptr, handleCount); Dictionary <string, bool> skip = new Dictionary <string, bool>(); while (infoEnumerator.MoveNext()) { FileHandleInfo current = infoEnumerator.Current; skip.TryGetValue(current.FileSystemInfo.FullName, out bool skipped); if (skipped || files.All(file => string.Compare(file, current.FileSystemInfo.FullName, StringComparison.OrdinalIgnoreCase) != 0)) { continue; } Console.WriteLine( $"Found locked file {current.FileSystemInfo.FullName}! {process.ProcessName} -> {process.MainModule.FileName}"); found = true; skip[current.FileSystemInfo.FullName] = true; var result = ProcessHelper.CloseHandle(process, current, currentProcess); Console.WriteLine(result == 0 ? "Success." : $"Error: {Enum.GetName(typeof(Error), result)}"); } } } return(found); }
public static Error Run(params string[] args) { if (args == null || args.Length != 1) { return(Error.InvalidArguments); } string fileName = args[0]; if (!File.Exists(fileName)) { return(Error.TargetFileNotFound); } string[] exclusionProcesses = File.ReadAllLines("ExclusionProcesses.txt"); string[] exclusionFolders = File.ReadAllLines("ExclusionFolders.txt"); Process currentProcess = Process.GetCurrentProcess(); Process[] processes = Process .GetProcesses() .Where(x => x.HandleCount > 0 && !exclusionProcesses.Contains(x.ProcessName.ToLowerInvariant())) .ToArray(); Console.WriteLine($"Found {processes.Length} processes."); using (SmartPtr sptr = SystemInformation.GetSystemHandleInformation()) { var information = (SystemHandlesInformation)Marshal.PtrToStructure(sptr.Pointer, typeof(SystemHandlesInformation)); int handleCount = information.Count; //int handleCount = Marshal.ReadInt32(sptr.Pointer); for (int i = 0; i < processes.Length; i++) { Process process = processes[i]; if (!ProcessHelper.IsCurrentUserProcess(process.Id)) { continue; } if (exclusionFolders.Any(y => process.MainModule.FileName.ToLowerInvariant().StartsWith(y))) { continue; } Console.Write("#"); var infoEnumerator = ProcessHelper.GetCurrentProcessOpenFilesEnumerator(process.Id, sptr, handleCount); while (infoEnumerator.MoveNext()) { FileHandleInfo current = infoEnumerator.Current; if (string.Compare(fileName, current.FileSystemInfo.FullName, StringComparison.OrdinalIgnoreCase) != 0) { continue; } Console.WriteLine(); Console.WriteLine($"Found!: {process.ProcessName} -> {process.MainModule.FileName}"); return(ProcessHelper.CloseHandle(process, current, currentProcess)); } } } return(Error.HandleNotFound); }