private static List <Process> EnumerateProcesses(uint pnProcInfoNeeded, uint handle, uint lpdwRebootReasons) { var processes = new List <Process>(); // Create an array to store the process results 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) { throw new Exception("Could not list processes locking resource."); } for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { } // catch the error -- in case the process is no longer running } return(processes); }
private static IProcessInfo CreateFromRmProcessInfo(RM_PROCESS_INFO procInfo) { var processId = procInfo.Process.dwProcessId; // ProcessStartTime is returned as local time, not UTC. var highDateTime = (long)procInfo.Process.ProcessStartTime.dwHighDateTime; highDateTime <<= 32; var lowDateTime = procInfo.Process.ProcessStartTime.dwLowDateTime; var fileTime = highDateTime | lowDateTime; var startTime = DateTime.FromFileTime(fileTime); var applicationName = procInfo.strAppName; var serviceShortName = procInfo.strServiceShortName; var applicationType = (ApplicationType)procInfo.ApplicationType; var applicationStatus = (ApplicationStatus)procInfo.AppStatus; var terminalServicesSessionId = procInfo.TSSessionId; var restartable = procInfo.bRestartable; return(new ProcessInfo( processId, startTime, applicationName, serviceShortName, applicationType, applicationStatus, terminalServicesSessionId, restartable )); }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing) /// /// </remarks> public static IReadOnlyCollection <RM_PROCESS_INFO> GetLockerProcesses(string path) { var key = Guid.NewGuid().ToString(); var res = RmStartSession(out uint handle, 0, key); if (res != 0) { throw new("Could not begin restart session. Unable to determine file locker."); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; var resources = new[] { path }; // Just checking on one resource. res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { throw new("Could not register resource."); } //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. res = RmGetList(handle, out var pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { return(processInfo); } else { throw new("Could not list processes locking resource."); } } else if (res != 0) { throw new("Could not list processes locking resource. Failed to get size of result."); } } finally { RmEndSession(handle); } return(Array.Empty <RM_PROCESS_INFO>()); }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs /// /// </remarks> public static List<RM_PROCESS_INFO> WhoIsLocking(string path) { uint handle; string key = Guid.NewGuid().ToString(); var result = new List<RM_PROCESS_INFO>(); int res = RmStartSession(out handle, 0, key); if (res != 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] {path}; // Just checking on one resource. res = RmRegisterResources(handle, (uint) resources.Length, resources, 0, null, 0, null); if (res != 0) throw new Exception("Could not register resource."); //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { result.Add(processInfo[i]); } } else throw new Exception("Could not list processes locking resource."); } else if (res != 0) throw new Exception("Could not list processes locking resource. Failed to get size of result."); } finally { RmEndSession(handle); } return result; }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing) /// /// </remarks> static public List <Process> GetLockingProcesses(string file) { List <Process> processes = new List <Process>(); uint handle; if (0 != RmStartSession(out handle, 0, Guid.NewGuid().ToString())) { throw new Exception("Could not RmStartSession()"); } try { string[] resources = new string[] { file }; if (0 != RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null)) { throw new Exception("Could not RmRegisterResources()"); } const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0; uint pnProcInfo = 0; uint lpdwRebootReasons = RmRebootReasonNone; int r = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (r == ERROR_MORE_DATA)//there is(are) locking process(es) { //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; if (0 != RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons)) { throw new Exception("Could not RmGetList()"); } processes = new List <Process>(); for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { }//the process is no longer running } } else if (r != 0) { throw new Exception("Could not RmGetList()"); } } finally { RmEndSession(handle); } return(processes); }
public static List <Process> GetProcessesUsingFiles(IList <string> filePaths) { List <Process> result = null; if (RmStartSession(out uint pSessionHandle, 0, Guid.NewGuid().ToString("N")) != 0) { throw new Win32Exception(); } try { string[] array = new string[filePaths.Count]; filePaths.CopyTo(array, 0); if (RmRegisterResources(pSessionHandle, (uint)array.Length, array, 0u, null, 0u, null) != 0) { throw new Win32Exception(); } uint pnProcInfoNeeded = 0u; uint pnProcInfo = 0u; uint lpdwRebootReasons = 0u; switch (RmGetList(pSessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons)) { case 234: { RM_PROCESS_INFO[] array2 = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; if (RmGetList(pSessionHandle, out pnProcInfoNeeded, ref pnProcInfo, array2, ref lpdwRebootReasons) != 0) { throw new Win32Exception(); } result = new List <Process>((int)pnProcInfo); for (int i = 0; i < pnProcInfo; i++) { try { result.Add(Process.GetProcessById(array2[i].Process.dwProcessId)); } catch (ArgumentException) { } } return(result); } default: throw new Win32Exception(); case 0: return(result); } } finally { RmEndSession(pSessionHandle); } }
public static IEnumerable <Process> GetProcessesLockingResources(params string[] resources) { Succeeded("RmStartSession", RmStartSession( pSessionHandle: out var dwSessionHandle, dwSessionFlags: 0, strSessionKey: Guid.NewGuid().ToString())); try { Succeeded("RmRegisterResources", RmRegisterResources(dwSessionHandle, (uint)resources.Length, resources, 0, null, 0, null)); var nProcInfoNeeded = 0U; var dwRebootReasons = (uint)RM_REBOOT_REASON.RmRebootReasonNone; var procInfos = default(RM_PROCESS_INFO[]); var result = 0; do { procInfos = new RM_PROCESS_INFO[nProcInfoNeeded]; result = RmGetList(dwSessionHandle, out nProcInfoNeeded, ref nProcInfoNeeded, procInfos, ref dwRebootReasons); }while (result == SystemErrorCodes.ERROR_MORE_DATA); Succeeded("RmGetList", result); foreach (var procInfo in procInfos) { var process = default(Process); try { process = Process.GetProcessById(procInfo.Process.dwProcessId); } catch { } if (process != default(Process)) { yield return(process); } } } finally { Succeeded("RmEndSession", RmEndSession(dwSessionHandle)); } void Succeeded(string name, int err) { if (err != SystemErrorCodes.ERROR_SUCCESS) { throw new Exception($"Cannot find who's locking the resources {string.Join("/", resources)}. {name} failed with error {err}."); } } }
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx public static IEnumerable <int> WhoIsLocking(params string[] resources) { const int ERROR_MORE_DATA = 234; const int SUCCESS = 0; if (RmStartSession(out var handle, 0, Guid.NewGuid().ToString()) != SUCCESS) { throw new Exception("Could not begin restart session. Unable to determine file locker."); } try { uint pnProcInfo = 0; uint lpdwRebootReasons = RmRebootReasonNone; if (RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null) != SUCCESS) { throw new Exception("Could not register resource."); } //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. var res = RmGetList(handle, out var pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list if (RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons) != SUCCESS) { throw new Exception("Could not list processes locking resource."); } foreach (var p in processInfo) { yield return(p.Process.dwProcessId); } } else if (res != SUCCESS) { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } finally { RmEndSession(handle); } }
internal ProcessInfo(RM_PROCESS_INFO processInfo) { ProcessId = (int)processInfo.Process.dwProcessId; // ProcessStartTime is returned as local time, not UTC. StartTime = DateTime.FromFileTime((((long)processInfo.Process.ProcessStartTime.dwHighDateTime) << 32) | processInfo.Process.ProcessStartTime.dwLowDateTime); ApplicationName = processInfo.strAppName; ServiceShortName = processInfo.strServiceShortName; ApplicationType = (ApplicationType)processInfo.ApplicationType; ApplicationStatus = (ApplicationStatus)processInfo.AppStatus; Restartable = processInfo.bRestartable; TerminalServicesSessionId = (int)processInfo.TSSessionId; }
public static RM_PROCESS_INFO[] FindLockerProcesses(string path) { if (NativeMethods.RmStartSession(out var handle, 0, Guid.NewGuid().ToString()) != RmResult.ERROR_SUCCESS) { throw new Exception("Could not begin session. Unable to determine file lockers."); } try { string[] resources = { path }; // Just checking on one resource. if (NativeMethods.RmRegisterResources(handle, (uint)resources.LongLength, resources, 0, null, 0, null) != RmResult.ERROR_SUCCESS) { throw new Exception("Could not register resource."); } // The first try is done expecting at most ten processes to lock the file. uint arraySize = 10; RmResult result; do { var array = new RM_PROCESS_INFO[arraySize]; result = NativeMethods.RmGetList(handle, out var arrayCount, ref arraySize, array, out _); if (result == RmResult.ERROR_SUCCESS) { // Adjust the array length to fit the actual count. Array.Resize(ref array, (int)arrayCount); return(array); } else if (result == RmResult.ERROR_MORE_DATA) { // We need to initialize a bigger array. We only set the size, and do another iteration. // (the out parameter arrayCount contains the expected value for the next try) arraySize = arrayCount; } else { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } while (result != RmResult.ERROR_SUCCESS); } finally { NativeMethods.RmEndSession(handle); } return(new RM_PROCESS_INFO[0]); }
/// <summary> /// Gets ids of any processes using the handle of a file /// </summary> public static bool GetProcessIdsUsingHandle(string absolutePath, out List <int> processIds) { processIds = new List <int>(); uint handle; int sessionStartResult = RmStartSession(out handle, 0, Guid.NewGuid().ToString("N")); if (sessionStartResult == 0) { int sessionEndResult; try { int registerResourcesResult = RmRegisterResources(handle, 1, new string[] { absolutePath }, 0, null, 0, null); if (registerResourcesResult == 0) { RM_PROCESS_INFO[] processInfo = null; uint pnProcInfoNeeded; uint pnProcInfo = 0; uint lpdwRebootReasons = RmRebootReasonNone; int getListResult = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); while (getListResult == ERROR_MORE_DATA) { processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)processInfo.Length; getListResult = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); } if (getListResult == 0 && processInfo != null) { for (var i = 0; i < pnProcInfo; i++) { RM_PROCESS_INFO procInfo = processInfo[i]; processIds.Add(procInfo.Process.dwProcessId); } } } } finally { sessionEndResult = RmEndSession(handle); } if (sessionEndResult == 0) { return(true); } } return(false); }
public bool IsResourcesLocked() { uint arraySize = 1; while (true) { var array = new RM_PROCESS_INFO[arraySize]; var result = NativeMethods.RmGetList(SessionHandle, out var arrayCount, ref arraySize, array, out _); if (result == RmResult.ERROR_SUCCESS || result == RmResult.ERROR_MORE_DATA) { return(arrayCount > 0); } throw new Win32Exception((int)result, $"RmGetList failed ({result})"); } }
public static RM_PROCESS_INFO[] FindLockerProcesses(string[] files) { int handle; if (RestartManagerNativeMethods.RmStartSession(out handle, 0, strSessionKey: Guid.NewGuid().ToString()) != RmResult.ERROR_SUCCESS) { throw new Exception("Could not begin session. Unable to determine file lockers."); } try { string[] resources = files.ToArray(); if (RestartManagerNativeMethods.RmRegisterResources(handle, (uint)resources.LongLength, resources, 0, null, 0, null) != RmResult.ERROR_SUCCESS) { throw new Exception("Could not register resource."); } uint arraySize = MAX_LOCK_PROCESS_COUNT; RmResult result; do { var array = new RM_PROCESS_INFO[arraySize]; uint arrayCount; RM_REBOOT_REASON lpdwRebootReasons; result = RestartManagerNativeMethods.RmGetList(handle, out arrayCount, ref arraySize, array, out lpdwRebootReasons); if (result == RmResult.ERROR_SUCCESS) { Array.Resize(ref array, (int)arrayCount); return(array); } else if (result == RmResult.ERROR_MORE_DATA) { arraySize = arrayCount; } else { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } while (result != RmResult.ERROR_SUCCESS); } finally { RestartManagerNativeMethods.RmEndSession(handle); } return(new RM_PROCESS_INFO[0]); }
/// <summary> /// Given a list of filenames with absolute path, returns enumerable of process currently locking those files. /// </summary> /// <param name="filePaths">Filenames with absolute path.</param> /// <returns>Enumerable of processes locking the files. Empty if it encounters any error.</returns> public static IEnumerable <Process> GetProcessesUsingFiles(string[] filePaths) { uint sessionHandle; int error = NativeMethods.RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString("N")); if (error == 0) { try { error = NativeMethods.RmRegisterResources(sessionHandle, (uint)filePaths.Length, filePaths, 0, null, 0, null); if (error == 0) { RM_PROCESS_INFO[] processInfo = null; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; error = NativeMethods.RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); while (error == ERROR_MORE_DATA) { processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)processInfo.Length; error = NativeMethods.RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); } if (error == 0 && processInfo != null) { for (var i = 0; i < pnProcInfo; i++) { RM_PROCESS_INFO procInfo = processInfo[i]; Process proc = null; try { proc = Process.GetProcessById(procInfo.Process.dwProcessId); } catch (ArgumentException) { // Eat exceptions for processes which are no longer running. } if (proc != null) { yield return(proc); } } } } } finally { NativeMethods.RmEndSession(sessionHandle); } } }
/// <summary> /// Wraps the raw RmGetList in an easier to use function. Gets the list of affected apps and stores it into rgAffectedApps. /// Attempts to retrieve processes up to maxAttempts times (due to inherent race condition present in restart manager) /// </summary> /// <param name="dwSessionHandle"></param> /// <param name="rgAffectedApps"></param> /// <param name="lpdwRebootReasons"></param> /// <returns></returns> public static int RmGetListEx(uint dwSessionHandle, ref List <RM_PROCESS_INFO> rgAffectedApps, ref RM_REBOOT_REASON lpdwRebootReasons, int maxAttempts = 5) { int attempts = 0; RM_PROCESS_INFO[] rawAffectedApps = null; uint affectedApps = 0; uint rawAffectedAppsSize = 0; int result = 0; //Only attempt to pull processes until we reach the maximum attempts. There is an inherent race condition: RmGetList returns //ERROR_MORE_DATA if you did not supply an array large enough to hold all the processes. HOWEVER, if the number of processes //increases before you call RmGetList again with the larger array, it will no longer be large enough to hold it. This can repeat //forever if processes keep increasing (for some reason). Thus, we only retry a set amount of times. do { uint lpdwInt = (uint)lpdwRebootReasons; result = RmGetList(dwSessionHandle, out affectedApps, ref rawAffectedAppsSize, rawAffectedApps, out lpdwInt); if (result == ERROR_MORE_DATA) { //If we didn't make a big enough array to hold all the processes, increase the size of the array. rawAffectedApps = new RM_PROCESS_INFO[Convert.ToInt32(affectedApps) + 1]; rawAffectedAppsSize = Convert.ToUInt32(rawAffectedApps.Length); } else if (result == ERROR_SUCCESS) { //Otherwise, if everything is fine, fill the provided list with the affected apps and be on our way if (rawAffectedApps != null) { rgAffectedApps = new List <RM_PROCESS_INFO>(rawAffectedApps.Take(Convert.ToInt32(affectedApps))); } break; } else { //Oof, something we don't recognize? It's probably an error; just exit so the user knows the results. break; } attempts += 1; } while (attempts < maxAttempts); return(result); }
public IReadOnlyList <Process> GetProcessesLockingResources() { uint arraySize = 10; while (true) { var array = new RM_PROCESS_INFO[arraySize]; var result = NativeMethods.RmGetList(SessionHandle, out var arrayCount, ref arraySize, array, out _); if (result == RmResult.ERROR_SUCCESS) { var processes = new List <Process>((int)arrayCount); for (var i = 0; i < arrayCount; i++) { try { var process = Process.GetProcessById(array[i].Process.dwProcessId); if (process != null) { processes.Add(process); } } catch { } } return(processes); } else if (result == RmResult.ERROR_MORE_DATA) { arraySize = arrayCount; } else { throw new Win32Exception((int)result, $"RmGetList failed ({result})"); } } }
private static RM_PROCESS_INFO[] GetProcessInfoList(RmSafeHandle handle) { uint lpdwRebootReasons = 0; uint pnProcInfo = 0; int status = RmGetList(handle, out uint pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (status != ERROR_MORE_DATA && status != 0) { throw new Win32Exception(status); } RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; status = RmGetList(handle, out _, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (status != 0) { throw new Win32Exception(status); } return(processInfo); }
/// <summary> /// Given a list of filenames with absolute path, returns enumerable of process currently locking those files. /// </summary> /// <param name="filePaths">Filenames with absolute path.</param> /// <returns>Enumerable of processes locking the files. Empty if it encounters any error.</returns> public static IEnumerable<Process> GetProcessesUsingFiles(string[] filePaths) { uint sessionHandle; int error = NativeMethods.RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString("N")); if (error == 0) { try { error = NativeMethods.RmRegisterResources(sessionHandle, (uint)filePaths.Length, filePaths, 0, null, 0, null); if (error == 0) { RM_PROCESS_INFO[] processInfo = null; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; error = NativeMethods.RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); while (error == ERROR_MORE_DATA) { processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)processInfo.Length; error = NativeMethods.RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); } if (error == 0 && processInfo != null) { for (var i = 0; i < pnProcInfo; i++) { RM_PROCESS_INFO procInfo = processInfo[i]; Process proc = null; try { proc = Process.GetProcessById(procInfo.Process.dwProcessId); } catch (ArgumentException) { // Eat exceptions for processes which are no longer running. } if (proc != null) { yield return proc; } } } } } finally { NativeMethods.RmEndSession(sessionHandle); } } }
public static List<Process> WhoIsLocking(string path) { var processes = new List<Process>(); try { uint handle; string key = Guid.NewGuid().ToString(); int res = RmStartSession(out handle, 0, key); if (res != 0) { throw new Exception("Could not begin restart session. Unable to determine file locker."); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { path }; // Just checking on one resource. res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { throw new Exception("Could not register resource."); } res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { processes = new List<Process>((int)pnProcInfo); for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { } } } else { } } else if (res != 0) { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } finally { RmEndSession(handle); } } catch(Exception ex) { //GeneralSettings.LogException(ex); MessageBox.Show(ex.Message + " WhoIsLocking() [ die datei konnte nicht gelöscht werden ] "); } return processes; }
// Return a list of processes that have locks on a file. static public List <Process> FindLockers(string filename) { // Start a new Restart Manager session. uint session_handle; string session_key = Guid.NewGuid().ToString(); int result = RmStartSession(out session_handle, 0, session_key); if (result != 0) { throw new Exception("Error " + result + " starting a Restart Manager session."); } List <Process> processes = new List <Process>(); try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, num_procs = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { filename }; result = RmRegisterResources( session_handle, (uint)resources.Length, resources, 0, null, 0, null); if (result != 0) { throw new Exception("Could not register resource."); } // There's a race around condition here. The first call to RmGetList() // returns the total number of process. However, when we call RmGetList() // again to get the actual processes this number may have increased. result = RmGetList(session_handle, out pnProcInfoNeeded, ref num_procs, null, ref lpdwRebootReasons); if (result == ERROR_MORE_DATA) { // Create an array to store the process results. RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; num_procs = pnProcInfoNeeded; // Get the list. result = RmGetList(session_handle, out pnProcInfoNeeded, ref num_procs, processInfo, ref lpdwRebootReasons); if (result != 0) { throw new Exception("Error " + result + " listing lock processes"); } // Add the results to the list. for (int i = 0; i < num_procs; i++) { try { processes.Add( Process.GetProcessById(processInfo[i]. Process.dwProcessId)); } // Catch the error in case the process is no longer running. catch (ArgumentException) { } } } else if (result != 0) { throw new Exception("Error " + result + " getting the size of the result."); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { RmEndSession(session_handle); } return(processes); }
public bool IsProcessLockWithException(string fileNameFull, out string message) { message = string.Empty; if (!AccessProcessLock || string.IsNullOrEmpty(fileNameFull)) { return(false); } string sessionkey = Guid.NewGuid().ToString(); List <Process> processes = new List <Process>(); int res = RmStartSession(out uint handle, 0, sessionkey); if (res != 0) { throw new Exception("Could not begin restart session!"); } try { uint pnProcInfo = 100, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { fileNameFull }; RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfo]; res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { throw new Exception("Could not register resource."); } res = RmGetList(handle, out uint pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { if (pnProcInfo != 0) { var isLock = false; for (int i = 0; i < pnProcInfo; i++) { message = $"Applicaion locking the file: {processInfo[i].strAppName}."; isLock = true; } if (isLock) { return(true); } } else { message = "The specified file is not locked by any process"; } } else { throw new Exception("Could not list processes locking resource."); } if (res != 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } catch (Exception exception) { message = exception.Message; throw exception; } finally { RmEndSession(handle); } return(false); }
internal static IEnumerable <ProcessInfo> GetLockingProcessInfos(params string[] paths) { if (paths == null) { throw new ArgumentNullException("paths"); } const int maxRetries = 6; // See http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx. var key = new StringBuilder(new string('\0', CCH_RM_SESSION_KEY + 1)); uint handle; int res = RmStartSession(out handle, 0, key); if (res != 0) { throw GetException(res, "RmStartSession", "Failed to begin restart manager session."); } try { string[] resources = paths; res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { throw GetException(res, "RmRegisterResources", "Could not register resources."); } // // Obtain the list of affected applications/services. // // NOTE: Restart Manager returns the results into the buffer allocated by the caller. The first call to // RmGetList() will return the size of the buffer (i.e. nProcInfoNeeded) the caller needs to allocate. // The caller then needs to allocate the buffer (i.e. rgAffectedApps) and make another RmGetList() // call to ask Restart Manager to write the results into the buffer. However, since Restart Manager // refreshes the list every time RmGetList()is called, it is possible that the size returned by the first // RmGetList()call is not sufficient to hold the results discovered by the second RmGetList() call. Therefore, // it is recommended that the caller follows the following practice to handle this race condition: // // Use a loop to call RmGetList() in case the buffer allocated according to the size returned in previous // call is not enough. // uint pnProcInfo = 0; RM_PROCESS_INFO[] rgAffectedApps = null; int retry = 0; do { uint lpdwRebootReasons = (uint)RM_REBOOT_REASON.RmRebootReasonNone; uint pnProcInfoNeeded; res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, rgAffectedApps, ref lpdwRebootReasons); if (res == 0) { // If pnProcInfo == 0, then there is simply no locking process (found), in this case rgAffectedApps is "null". if (pnProcInfo == 0) { return(Enumerable.Empty <ProcessInfo>()); } var lockInfos = new List <ProcessInfo>((int)pnProcInfo); for (int i = 0; i < pnProcInfo; i++) { lockInfos.Add(new ProcessInfo(rgAffectedApps[i])); } return(lockInfos); } if (res != ERROR_MORE_DATA) { throw GetException(res, "RmGetList", string.Format("Failed to get entries (retry {0}).", retry)); } pnProcInfo = pnProcInfoNeeded; rgAffectedApps = new RM_PROCESS_INFO[pnProcInfo]; } while ((res == ERROR_MORE_DATA) && (retry++ < maxRetries)); } finally { res = RmEndSession(handle); if (res != 0) { throw GetException(res, "RmEndSession", "Failed to end the restart manager session."); } } return(Enumerable.Empty <ProcessInfo>()); }
// http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx (How do I find out which process has a file open?) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa373682(v=vs.85).aspx (Using Restart Manager with a Secondary Installer ) // http://msdn.microsoft.com/en-us/magazine/cc163450.aspx ( Restart Manager -- C# example) public static List <Process> GetProcessesUsingFiles(IList <string> filePaths) { uint sessionHandle; List <Process> processes = null; // Create a restart manager session int rv = RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString("N")); if (rv != 0) { throw new Win32Exception(); } try { // Let the restart manager know what files we’re interested in string[] pathStrings = new string[filePaths.Count]; filePaths.CopyTo(pathStrings, 0); rv = RmRegisterResources(sessionHandle, (uint)pathStrings.Length, pathStrings, 0, null, 0, null); if (rv != 0) { throw new Win32Exception(); } // Ask the restart manager what other applications // are using those files const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (rv == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (rv == 0) { processes = new List <Process>((int)pnProcInfo); // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } // catch the error -- in case the process is no longer running catch (ArgumentException) { } } } else { throw new Win32Exception(); } } else if (rv != 0) { throw new Win32Exception(); } } finally { // Close the resource manager RmEndSession(sessionHandle); } return(processes); }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing) /// /// </remarks> public static List <Process> WhoIsLocking(string path) { string key = Guid.NewGuid().ToString(); List <Process> processes = new List <Process>(); int res = RmStartSession(out var handle, 0, key); if (res != 0) { throw new Exception("Could not begin restart session. Unable to determine file locker."); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { path }; // Just checking on one resource. res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { throw new Exception("Could not register resource."); } //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. res = RmGetList(handle, out var pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { processes = new List <Process>((int)pnProcInfo); // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } // catch the error -- in case the process is no longer running catch (ArgumentException) { } } } else { throw new Exception("Could not list processes locking resource."); } } else if (res != 0) { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } finally { RmEndSession(handle); } return(processes); }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing) /// /// </remarks> static public FileLockCheckResult CheckFile(string path) { //mxd. Do it the clunky way? (WinXP) if (Environment.OSVersion.Version.Major < 6) { bool locked = false; try { using (File.Open(path, FileMode.Open)) { } } catch (IOException e) { int errorcode = Marshal.GetHRForException(e) & ((1 << 16) - 1); locked = (errorcode == 32 || errorcode == 33); } return(new FileLockCheckResult { Error = (locked ? "Unable to save the map. Map file is locked by another process." : string.Empty) }); } //mxd. Needs Vista or newer... uint handle; string key = Guid.NewGuid().ToString(); FileLockCheckResult result = new FileLockCheckResult(); //mxd string errorstart = "Unable to save the map: target file is locked by another process." + Environment.NewLine + "Also, unable to get the name of the offending process:" + Environment.NewLine + Environment.NewLine; int res = RmStartSession(out handle, 0, key); if (res != 0) { RmEndSession(handle); //mxd result.Error = errorstart + "Error " + res + ". Could not begin restart session. Unable to determine file locker."; //mxd return(result); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new[] { path }; // Just checking on one resource. res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { result.Error = errorstart + "Error " + res + ". Could not register resource."; //mxd return(result); } //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { result.Processes = new List <Process>((int)pnProcInfo); // Enumerate all of the results and add them to the list to be returned for (int i = 0; i < pnProcInfo; i++) { try { Process process = Process.GetProcessById(processInfo[i].Process.dwProcessId); result.Processes.Add(process); } // catch the error -- in case the process is no longer running catch (ArgumentException) {} } //mxd if (result.Processes.Count > 0) { result.Error = "Unable to save the map: target file is locked by the following process" + (result.Processes.Count > 1 ? "es" : "") + ":" + Environment.NewLine + Environment.NewLine; foreach (Process process in result.Processes) { string processpath = string.Empty; try { // All manner of exceptions are possible here... processpath = process.MainModule.FileName; }catch {} result.Error += process.ProcessName + " (" + (!string.IsNullOrEmpty(processpath) ? "\"" + processpath + "\"" : "") + ", started at " + process.StartTime + ")" + Environment.NewLine; } } } else { result.Error = "Error " + res + ". Could not list processes locking the resource."; //mxd return(result); } } else if (res != 0) { result.Error = "Error " + res + ". Could not list processes locking resource. Failed to get result size."; //mxd return(result); } } finally { RmEndSession(handle); } return(result); }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing) /// /// </remarks> public static List<Process> WhoIsLocking(string path) { uint handle; string key = Guid.NewGuid().ToString(); List<Process> processes = new List<Process>(); int res = RmStartSession(out handle, 0, key); if (res != 0) throw new Exception("Could not begin restart session. Unable to determine file locker."); try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { path }; // Just checking on one resource. res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) throw new Exception("Could not register resource."); //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { processes = new List<Process>((int)pnProcInfo); // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } // catch the error -- in case the process is no longer running catch (ArgumentException) { } } } else throw new Exception("Could not list processes locking resource."); } else if (res != 0) throw new Exception("Could not list processes locking resource. Failed to get size of result."); } finally { RmEndSession(handle); } return processes; }
public static IList<Process> GetProcessesUsingFile(string filePath) { uint sessionHandle; var processes = new List<Process>(); // Create a restart manager session int rv = RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString()); if (rv != 0) throw new Win32Exception(); try { // Let the restart manager know what files we’re interested in var pathStrings = new[]{filePath}; rv = RmRegisterResources(sessionHandle, (uint) pathStrings.Length, pathStrings, 0, null, 0, null); if (rv != 0) throw new Win32Exception(); // Ask the restart manager what other applications // are using those files const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (rv == ERROR_MORE_DATA) { // Create an array to store the process results var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint) processInfo.Length; // Get the list rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (rv == 0) { // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { // in case the process is no longer running } } } else throw new Win32Exception(); } else if (rv != 0) throw new Win32Exception(); } finally { // Close the resource manager RmEndSession(sessionHandle); } return processes; }
protected List <Process> GetLockProcesses(string path) { uint handle; string key = Guid.NewGuid().ToString(); List <Process> processes = new List <Process>(); uint res = RmStartSession(out handle, (uint)0, key); if (res != 0) { throw new Exception("Could not begin restart session. " + "Unable to determine file locker."); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { path }; res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, 0, 0, 0); if (res != 0) { throw new Exception("Could not register resource."); } res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results. RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { processes = new List <Process>((int)pnProcInfo); // Enumerate all of the results and add them to the // list to be returned. for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } // Catch the error in case the process is no longer running. catch (ArgumentException) { } } } else { throw new Exception("Could not list processes locking resource"); } } else if (res != 0) { throw new Exception("Could not list processes locking resource." + "Failed to get size of result."); } } finally { RmEndSession(handle); } return(processes); }
private static void Main() { // CCH_RM_SESSION_KEY: Character count of the Text-Encoded session key,defined in RestartManager.h var sessKey = new StringBuilder(CCH_RM_SESSION_KEY + 1); // NOTE:We register two calc executable files. The second one is for the redirection of 32 bit calc on 64 bit machines. Even if // you are using a 32 bit machine, you don't need to comment out the second line. string[] rgsFiles = { "C:\\Windows\\System32\\calc.exe", "C:\\Windows\\SysWow64\\calc.exe" }; uint nRetry = 0; uint nAffectedApps = 0; RM_PROCESS_INFO[] rgAffectedApps = null; RM_REBOOT_REASON dwRebootReasons; // Start a Restart Manager Session var dwErrCode = RmStartSession(out var dwSessionHandle, 0, sessKey); if (Win32Error.ERROR_SUCCESS != dwErrCode) { goto RM_CLEANUP; } // // Register items with Restart Manager // // NOTE: we only register two calc executable files //in this sample. You can register files, processes // (in the form of process ID), and services (in the // form of service short names) with Restart Manager. // dwErrCode = RmRegisterResources(dwSessionHandle, (uint)rgsFiles.Length, rgsFiles); if (Win32Error.ERROR_SUCCESS != dwErrCode) { goto RM_CLEANUP; } // Obtain the list of affected applications/services. // // NOTE: Restart Manager returns the results into the buffer allocated by the caller. The first call to RmGetList() will return // the size of the buffer (i.e. nProcInfoNeeded) the caller needs to allocate. The caller then needs to allocate the buffer // (i.e. rgAffectedApps) and make another RmGetList() call to ask Restart Manager to write the results into the buffer. However, // since Restart Manager refreshes the list every time RmGetList()is called, it is possible that the size returned by the first // RmGetList()call is not sufficient to hold the results discovered by the second RmGetList() call. Therefore, it is recommended // that the caller follows the following practice to handle this race condition: // // Use a loop to call RmGetList() in case the buffer allocated according to the size returned in previous call is not enough. // // In this example, we use a do-while loop trying to make 3 RmGetList() calls (including the first attempt to get buffer size) // and if we still cannot succeed, we give up. do { dwErrCode = RmGetList(dwSessionHandle, out var nProcInfoNeeded, ref nAffectedApps, rgAffectedApps, out dwRebootReasons); if (Win32Error.ERROR_SUCCESS == dwErrCode) { // RmGetList() succeeded break; } if (Win32Error.ERROR_MORE_DATA != dwErrCode) { // RmGetList() failed, with errors other than ERROR_MORE_DATA goto RM_CLEANUP; } // RmGetList() is asking for more data nAffectedApps = nProcInfoNeeded; rgAffectedApps = new RM_PROCESS_INFO[nAffectedApps]; } while ((Win32Error.ERROR_MORE_DATA == dwErrCode) && (nRetry++ < 3)); if (Win32Error.ERROR_SUCCESS != dwErrCode) { goto RM_CLEANUP; } if (RM_REBOOT_REASON.RmRebootReasonNone != dwRebootReasons) { // Restart Manager cannot mitigate a reboot. We goes to the clean up. The caller may want to add additional code to handle // this scenario. goto RM_CLEANUP; } // Now rgAffectedApps contains the affected applications and services. The number of applications and services returned is // nAffectedApps. The result of RmGetList can be interpreted by the user to determine subsequent action (e.g. ask user's // permission to shutdown). // // CALLER CODE GOES HERE... // Shut down all running instances of affected applications and services. dwErrCode = RmShutdown(dwSessionHandle); if (Win32Error.ERROR_SUCCESS != dwErrCode) { goto RM_CLEANUP; } // An installer can now replace or update the calc executable file. // // CALLER CODE GOES HERE... // Restart applications and services, after the files have been replaced or updated. dwErrCode = RmRestart(dwSessionHandle); if (Win32Error.ERROR_SUCCESS != dwErrCode) { goto RM_CLEANUP; } RM_CLEANUP: if (0xFFFFFFFF != dwSessionHandle) { // Clean up the Restart Manager session. RmEndSession(dwSessionHandle); } }
public static IList <Process> GetProcessesUsingFiles(IEnumerable <string> filePaths) { var filePathsList = filePaths.ToList(); uint sessionHandle; List <Process> processes = new List <Process>(); // Create a restart manager session int rv = RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString("N")); if (rv != 0) { throw new Win32Exception(); } try { // Let the restart manager know what files we're interested in string[] pathStrings = new string[filePathsList.Count]; filePathsList.CopyTo(pathStrings, 0); rv = RmRegisterResources(sessionHandle, (uint)pathStrings.Length, pathStrings, 0, null, 0, null); if (rv != 0) { throw new Win32Exception(); } // Ask the restart manager what other applications are using those files const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (rv == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)processInfo.Length; // Get the list. rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (rv == 0) { // Enumerate all of the results and add them to the list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { } // in case process is no longer running } } // It's possible that the number of processes could have changed between previous call to RmGetList // and this one, in which case our array might not be big enough and rv could be // ERROR_MORE_DATA. In that case, we could retry, but for now we'll just throw an exception. else { throw new Win32Exception(); } } else if (rv != 0) { throw new Win32Exception(); } } finally { // Close the resource manager RmEndSession(sessionHandle); } return(processes); }
/// <summary> /// Find out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file.</param> /// <returns>Processes locking the file</returns> /// <remarks>See also: /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing) /// /// </remarks> static public List <Process> WhoIsLocking(string path) { uint handle; string key = Guid.NewGuid().ToString(); List <Process> processes = new List <Process>(); int res = RmStartSession(out handle, 0, key); if (res != 0) { throw new Exception("Could not begin restart session. Unable to determine file locker."); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; string[] resources = new string[] { path }; res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null); if (res != 0) { throw new Exception("Could not register resource."); } res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (res == ERROR_MORE_DATA) { RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (res == 0) { processes = new List <Process>((int)pnProcInfo); for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { } } } else { throw new Exception("Could not list processes locking resource."); } } else if (res != 0) { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } finally { RmEndSession(handle); } return(processes); }
FindLockFinder #endif (string path) { string key = Guid.NewGuid().ToString(); #if !WAPICP3 var processes = new List <Process>(); #endif if (RmStartSession(out uint handle, 0, key) != 0) { throw new Exception(UnableToDetermineFileLocker); } try { uint pnProcInfo = 0; string[] resources = new string[] { path }; if (RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null) != 0) { throw new Exception(CouldNotRegisterResource); } // There's a race around condition here. The first call to RmGetList() // returns the total number of process. However, when we call RmGetList() // again to get the actual processes this number may have increased. uint res = RmGetList(handle, out uint pnProcInfoNeeded, ref pnProcInfo, null, out RM_REBOOT_REASON lpdwRebootReasons); if ((ErrorCode)res == ErrorCode.MoreData) { // Create an array to store the process results. var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list. if (RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, out lpdwRebootReasons) == 0) { #if WAPICP3 var #endif processes = new List <Process>((int)pnProcInfo); // Enumerate all of the results and add them to the list to be returned. for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); #if WAPICP3 return(processes); #endif } // Catch the error in case the process is no longer running. catch (ArgumentException) { } } } else { throw new Exception(CouldNotListProcessesLockingResource); } } else if (res != 0) { throw new Exception(FailedToGetSizeOfResult); } } //catch (Exception exception) //{ // MessageBox.Show(exception.Message, "Lock Finder", MessageBoxButtons.OK, // MessageBoxIcon.Error); //} finally { _ = RmEndSession(handle); } return (#if WAPICP3 null); #else processes; #endif }
public static IList <Process> GetProcessesUsingFile(string filePath) { uint sessionHandle; var processes = new List <Process>(); // Create a restart manager session int rv = RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString()); if (rv != 0) { throw new Win32Exception(); } try { // Let the restart manager know what files we’re interested in var pathStrings = new[] { filePath }; rv = RmRegisterResources(sessionHandle, (uint)pathStrings.Length, pathStrings, 0, null, 0, null); if (rv != 0) { throw new Win32Exception(); } // Ask the restart manager what other applications // are using those files const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (rv == ERROR_MORE_DATA) { // Create an array to store the process results var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)processInfo.Length; // Get the list rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (rv == 0) { // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { // in case the process is no longer running } } } else { throw new Win32Exception(); } } else if (rv != 0) { throw new Win32Exception(); } } finally { // Close the resource manager RmEndSession(sessionHandle); } return(processes); }
// http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx (How do I find out which process has a file open?) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa373682(v=vs.85).aspx (Using Restart Manager with a Secondary Installer ) // http://msdn.microsoft.com/en-us/magazine/cc163450.aspx ( Restart Manager -- C# example) public static List<Process> GetProcessesUsingFiles(IList<string> filePaths) { uint sessionHandle; List<Process> processes = null; // Create a restart manager session int rv = RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString("N")); if (rv != 0) throw new Win32Exception(); try { // Let the restart manager know what files we’re interested in string[] pathStrings = new string[filePaths.Count]; filePaths.CopyTo(pathStrings, 0); rv = RmRegisterResources(sessionHandle, (uint)pathStrings.Length, pathStrings, 0, null, 0, null); if (rv != 0) throw new Win32Exception(); // Ask the restart manager what other applications // are using those files const int ERROR_MORE_DATA = 234; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; //Note: there's a race condition here -- the first call to RmGetList() returns // the total number of process. However, when we call RmGetList() again to get // the actual processes this number may have increased. rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (rv == ERROR_MORE_DATA) { // Create an array to store the process results RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list rv = RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (rv == 0) { processes = new List<Process>((int)pnProcInfo); // Enumerate all of the results and add them to the // list to be returned for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } // catch the error -- in case the process is no longer running catch (ArgumentException) { } } } else throw new Win32Exception(); } else if (rv != 0) throw new Win32Exception(); } finally { // Close the resource manager RmEndSession(sessionHandle); } return processes; }
// private delegate void AddTreeNode(TreeNode node); // private static List<Process> LastProcessList; /// <summary> /// This function finds out what process(es) have a lock on the specified file. /// </summary> /// <param name="path">Path of the file</param> /// <returns>Processes locking the file</returns> public static List <Process> FindLockFinder(string path) { string key = Guid.NewGuid().ToString(); var processes = new List <Process>(); if (RmStartSession(out uint handle, 0, key) != 0) { throw new Exception("Could not begin restart session. Unable to determine file locker."); } try { const int ERROR_MORE_DATA = 234; uint pnProcInfo = 0; string[] resources = new string[] { path }; if (RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null) != 0) { throw new Exception("Could not register resource."); } // There's a race around condition here. The first call to RmGetList() // returns the total number of process. However, when we call RmGetList() // again to get the actual processes this number may have increased. uint res = RmGetList(handle, out uint pnProcInfoNeeded, ref pnProcInfo, null, out RM_REBOOT_REASON lpdwRebootReasons); if (res == ERROR_MORE_DATA) { // Create an array to store the process results. var processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = pnProcInfoNeeded; // Get the list. if (RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, out lpdwRebootReasons) == 0) { processes = new List <Process>((int)pnProcInfo); // Enumerate all of the results and add them to the list to be returned. for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } // Catch the error in case the process is no longer running. catch (ArgumentException) { } } } else { throw new Exception("Could not list processes locking resource"); } } else if (res != 0) { throw new Exception("Could not list processes locking resource. Failed to get size of result."); } } //catch (Exception exception) //{ // MessageBox.Show(exception.Message, "Lock Finder", MessageBoxButtons.OK, // MessageBoxIcon.Error); //} finally { _ = RmEndSession(handle); } return(processes); }
private bool GetUsingFiles(IList <string> filePaths) { uint sessionHandle; bool flag = false; int rv = NativeMethods.RmStartSession(out sessionHandle, 0, Guid.NewGuid().ToString("N")); if (rv != 0) { throw new Win32Exception(); } try { string[] pathStrings = new string[filePaths.Count]; filePaths.CopyTo(pathStrings, 0); rv = NativeMethods.RmRegisterResources(sessionHandle, (uint)pathStrings.Length, pathStrings, 0, null, 0, null); if (rv != 0) { throw new Win32Exception(); } const int ERROR_MORE_DATA = 234; const uint RmRebootReasonNone = 0; uint pnProcInfoNeeded = 0, pnProcInfo = 0, lpdwRebootReasons = RmRebootReasonNone; rv = NativeMethods.RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons); if (rv == ERROR_MORE_DATA) { RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)processInfo.Length; rv = NativeMethods.RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons); if (rv != 0) { throw new Win32Exception(); } for (int i = 0; i < pnProcInfo; i++) { try { string name = Process.GetProcessById(processInfo[i].Process.dwProcessId).ProcessName; if (name.Equals("x-APPLICATION") || name.Equals("x-APPLISMO")) { flag = true; break; } } catch (Exception) { } } } else if (rv != 0) { throw new Win32Exception(); } } finally { NativeMethods.RmEndSession(sessionHandle); } return(flag); }