| 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;        }    }}
 |