<PackageReference Include="Relativity.Server.Transfer.SDK" Version="7.7.0" />

InUseDetection

static class InUseDetection
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; namespace Relativity.Transfer { internal static class InUseDetection { private struct RM_UNIQUE_PROCESS { public int dwProcessId; public FILETIME ProcessStartTime; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct RM_PROCESS_INFO { public RM_UNIQUE_PROCESS Process; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string strAppName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string strServiceShortName; public RM_APP_TYPE ApplicationType; public uint AppStatus; public uint TSSessionId; [MarshalAs(UnmanagedType.Bool)] public bool bRestartable; } private enum RM_APP_TYPE { RmUnknownApp = 0, RmMainWindow = 1, RmOtherWindow = 2, RmService = 3, RmExplorer = 4, RmConsole = 5, RmCritical = 1000 } private const int RmRebootReasonNone = 0; private const int CCH_RM_MAX_APP_NAME = 255; private const int CCH_RM_MAX_SVC_NAME = 63; [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey); [DllImport("rstrtmgr.dll")] private static extern int RmEndSession(uint pSessionHandle); [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int RmRegisterResources(uint pSessionHandle, uint nFiles, string[] rgsFilenames, uint nApplications, [In] RM_UNIQUE_PROCESS[] rgApplications, uint nServices, string[] rgsServiceNames); [DllImport("rstrtmgr.dll", SetLastError = true)] private static extern int RmGetList(uint dwSessionHandle, out uint pnProcInfoNeeded, ref uint pnProcInfo, [In] [Out] RM_PROCESS_INFO[] rgAffectedApps, ref uint lpdwRebootReasons); public static IList<Process> GetProcessesUsingFiles(IList<string> filePaths) { uint num = CreateSession(); try { RegisterResources(filePaths, num); return GetProcesses(num); } finally { RmEndSession(num); } } private static List<Process> GetProcesses(uint sessionHandle) { List<Process> list = new List<Process>(); uint pnProcInfoNeeded = 0; uint pnProcInfo = 0; uint lpdwRebootReasons = 0; switch (RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons)) { case 234: { RM_PROCESS_INFO[] array = new RM_PROCESS_INFO[pnProcInfoNeeded]; pnProcInfo = (uint)array.Length; if (RmGetList(sessionHandle, out pnProcInfoNeeded, ref pnProcInfo, array, ref lpdwRebootReasons) != 0) { int lastWin32Error2 = Marshal.GetLastWin32Error(); throw new Win32Exception($"""{lastWin32Error2}"); } AddFoundProcesses(pnProcInfo, list, array); break; } default: { int lastWin32Error = Marshal.GetLastWin32Error(); throw new Win32Exception($"""{lastWin32Error}"); } case 0: break; } return list; } private static void AddFoundProcesses(uint pnProcInfo, List<Process> processes, RM_PROCESS_INFO[] processInfo) { for (int i = 0; i < pnProcInfo; i++) { try { processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId)); } catch (ArgumentException) { } } } private static uint CreateSession() { uint pSessionHandle = default(uint); if (RmStartSession(out pSessionHandle, 0, Guid.NewGuid().ToString("N")) == 0) return pSessionHandle; int lastWin32Error = Marshal.GetLastWin32Error(); throw new Win32Exception($"""{lastWin32Error}"); } private static void RegisterResources(IList<string> filePaths, uint sessionHandle) { string[] array = new string[filePaths.Count]; filePaths.CopyTo(array, 0); if (RmRegisterResources(sessionHandle, (uint)array.Length, array, 0, null, 0, null) != 0) { int lastWin32Error = Marshal.GetLastWin32Error(); throw new Win32Exception($"""{lastWin32Error}"); } } } }