Lister tous les processus qui utilisent un fichier
staticpublicclassFileUtil
{
[StructLayout(LayoutKind.Sequential)]
structRM_UNIQUE_PROCESS
{
publicint dwProcessId;
public System.Runtime.InteropServices.ComTypes.FILETIMEProcessStartTime;
}
constintRmRebootReasonNone = 0;
constintCCH_RM_MAX_APP_NAME = 255;
constintCCH_RM_MAX_SVC_NAME = 63;
enumRM_APP_TYPE
{
RmUnknownApp = 0,
RmMainWindow = 1,
RmOtherWindow = 2,
RmService = 3,
RmExplorer = 4,
RmConsole = 5,
RmCritical = 1000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct RM_PROCESS_INFO
{
publicRM_UNIQUE_PROCESSProcess;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
publicstringstrAppName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
publicstringstrServiceShortName;
publicRM_APP_TYPEApplicationType;
publicuintAppStatus;
publicuintTSSessionId;
[MarshalAs(UnmanagedType.Bool)]
publicboolbRestartable;
}
[DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]
staticexternintRmRegisterResources(uintpSessionHandle,
UInt32nFiles,
string[] rgsFilenames,
UInt32nApplications,
[In] RM_UNIQUE_PROCESS[] rgApplications,
UInt32nServices,
string[] rgsServiceNames);
[DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]
staticexternintRmStartSession(outuintpSessionHandle, intdwSessionFlags, stringstrSessionKey);
[DllImport("rstrtmgr.dll")]
staticexternintRmEndSession(uintpSessionHandle);
[DllImport("rstrtmgr.dll")]
staticexternintRmGetList(uintdwSessionHandle,
outuintpnProcInfoNeeded,
refuintpnProcInfo,
[In, Out] RM_PROCESS_INFO[] rgAffectedApps,
refuintlpdwRebootReasons);
/// <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>staticpublicList<Process> WhoIsLocking(stringpath)
{
uinthandle;
stringkey = Guid.NewGuid().ToString();
List<Process> processes = newList<Process>();
intres = RmStartSession(outhandle, 0, key);
if (res != 0) thrownewException("Could not begin restart session. Unable to determine file locker.");
try
{
constintERROR_MORE_DATA = 234;
uintpnProcInfoNeeded = 0,
pnProcInfo = 0,
lpdwRebootReasons = RmRebootReasonNone;
string[] resources = newstring[] { path }; // Just checking on one resource.
res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
if (res != 0) thrownewException("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, outpnProcInfoNeeded, refpnProcInfo, null, reflpdwRebootReasons);
if (res == ERROR_MORE_DATA)
{
// Create an array to store the process resultsRM_PROCESS_INFO[] processInfo = newRM_PROCESS_INFO[pnProcInfoNeeded];
pnProcInfo = pnProcInfoNeeded;
// Get the list
res = RmGetList(handle, outpnProcInfoNeeded, refpnProcInfo, processInfo, reflpdwRebootReasons);
if (res == 0)
{
processes = newList<Process>((int)pnProcInfo);
// Enumerate all of the results and add them to the // list to be returnedfor (inti = 0; i < pnProcInfo; i++)
{
try
{
processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
}
// catch the error -- in case the process is no longer runningcatch (ArgumentException) { }
}
}
elsethrownewException("Could not list processes locking resource.");
}
elseif (res != 0) thrownewException("Could not list processes locking resource. Failed to get size of result.");
}
finally
{
RmEndSession(handle);
}
return processes;
}
}