123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- namespace Optimizer
- {
- public static class FileHandleHelper
- {
- public static List<Process> GetProcessesLockingFile(string path)
- {
- uint handle;
- string key = Guid.NewGuid().ToString();
- int res = RmStartSession(out handle, 0, key);
- if (res != 0) return null;
- try
- {
- const int MORE_DATA = 234;
- uint pnProcInfoNeeded, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone;
- string[] resources = { path };
- res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
- if (res != 0) return null;
- res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
- if (res == MORE_DATA)
- {
- return EnumerateProcesses(pnProcInfoNeeded, handle, lpdwRebootReasons);
- }
- else if (res != 0) return null;
- }
- finally
- {
- RmEndSession(handle);
- }
- return new List<Process>();
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct RM_UNIQUE_PROCESS
- {
- public int dwProcessId;
- public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
- }
- const int RmRebootReasonNone = 0;
- const int CCH_RM_MAX_APP_NAME = 255;
- const int CCH_RM_MAX_SVC_NAME = 63;
- public enum RM_APP_TYPE
- {
- RmUnknownApp = 0,
- RmMainWindow = 1,
- RmOtherWindow = 2,
- RmService = 3,
- RmExplorer = 4,
- RmConsole = 5,
- RmCritical = 1000
- }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct RM_PROCESS_INFO
- {
- public RM_UNIQUE_PROCESS Process;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)] public string strAppName;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)] public string strServiceShortName;
- public RM_APP_TYPE ApplicationType;
- public uint AppStatus;
- public uint TSSessionId;
- [MarshalAs(UnmanagedType.Bool)] public bool bRestartable;
- }
- [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]
- static extern int RmRegisterResources(uint pSessionHandle, uint nFiles, string[] rgsFilenames,
- uint nApplications, [In] RM_UNIQUE_PROCESS[] rgApplications, uint nServices,
- string[] rgsServiceNames);
- [DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]
- static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);
- [DllImport("rstrtmgr.dll")]
- static extern int RmEndSession(uint pSessionHandle);
- [DllImport("rstrtmgr.dll")]
- static extern int RmGetList(uint dwSessionHandle, out uint pnProcInfoNeeded,
- ref uint pnProcInfo, [In, Out] RM_PROCESS_INFO[] rgAffectedApps,
- ref uint lpdwRebootReasons);
- private static List<Process> EnumerateProcesses(uint pnProcInfoNeeded, uint handle, uint lpdwRebootReasons)
- {
- var processes = new List<Process>(10);
- var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];
- var pnProcInfo = pnProcInfoNeeded;
- // Get the list
- var res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
- if (res != 0) return null;
- for (int i = 0; i < pnProcInfo; i++)
- {
- try
- {
- processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
- }
- catch { }
- }
- return processes;
- }
- }
- }
|