使用C#一个人如何弄清楚哪些进程锁定的文件

 我来答
huanglenzhi
推荐于2016-10-19 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117529 获赞数:517219
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部

请了大量的代码转储,但这里有一个小的类来做到这一点。它适用于Windows 7和Windows Server 2003(只有两个我已经测试通过为止),线程,以防止讨厌的Win32错误。大多的东西上发现 更新,以防止少数异常。使线程的背景,所以Win32的错误将不会退出停止你的过程。

using System;

using System.Collections.Generic;

using System.Runtime.InteropServices;

using System.Diagnostics;

using System.Text;

using System.Threading;

namespace FileLockInfo

{

 public class Win32Processes

 {

  /// <summary>

  /// Return a list of processes that hold on the given file.

  /// </summary>

  public static List<Process> GetProcessesLockingFile(string filePath)

  {

   var procs = new List<Process>();

   var processListSnapshot = Process.GetProcesses();

   foreach (var process in processListSnapshot)

   {

    if (process.Id <= 4) { continue; } // system processes

    var files = GetFilesLockedBy(process);

    if (files.Contains(filePath)) procs.Add(process);

   }

   return procs;

  }

  /// <summary>

  /// Return a list of file locks held by the process.

  /// </summary>

  public static List<string> GetFilesLockedBy(Process process)

  {

   var outp = new List<string>();

   ThreadStart ts = delegate

   {

    try

    {

     outp = UnsafeGetFilesLockedBy(process);

    }

    catch { Ignore(); }

   };

   try

   {

    var t = new Thread(ts);

    t.IsBackground = true;

    t.Start();

    if (!t.Join(250))

    {

     try

     {

      t.Interrupt();

      t.Abort();

     }

     catch { Ignore(); }

    }

   }

   catch { Ignore(); }

   return outp;

  }


  #region Inner Workings

  private static void Ignore() { }

  private static List<string> UnsafeGetFilesLockedBy(Process process)

  {

   try

   {

    var handles = GetHandles(process);

    var files = new List<string>();

    foreach (var handle in handles)

    {

     var file = GetFilePath(handle, process);

     if (file != null) files.Add(file);

    }

    return files;

   }

   catch

   {

    return new List<string>();

   }

  }

  const int CNST_SYSTEM_HANDLE_INFORMATION = 16;

  private static string GetFilePath(Win32API.SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process)

  {

   var ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id);

   var objBasic = new Win32API.OBJECT_BASIC_INFORMATION();

   var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION();

   var objObjectName = new Win32API.OBJECT_NAME_INFORMATION();

   var strObjectName = "";

   var nLength = 0;

   IntPtr ipTemp, ipHandle;

   if (!Win32API.DuplicateHandle(ipProcessHwnd, systemHandleInformation.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS))

    return null;

   IntPtr ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));

   Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength);

   objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());

   Marshal.FreeHGlobal(ipBasic);

   IntPtr ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength);

   nLength = objBasic.TypeInformationLength;

   // this one never locks...

   while ((uint)(Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH)

   {

    if (nLength == 0)

    {

     Console.WriteLine("nLength returned at zero! ");

     return null;

    }

    Marshal.FreeHGlobal(ipObjectType);

    ipObjectType = Marshal.AllocHGlobal(nLength);

   }

   objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType());

   if (Is64Bits())

   {

    ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32);

   }

   else

   {

    ipTemp = objObjectType.Name.Buffer;

   }

   var strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);

   Marshal.FreeHGlobal(ipObjectType);

   if (strObjectTypeName != "File")

    return null;

   nLength = objBasic.NameInformationLength;

   var ipObjectName = Marshal.AllocHGlobal(nLength);

   // ...this call sometimes hangs. Is a Windows error.

   while ((uint)(Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectNameInformation, ipObjectName, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH)

   {

    Marshal.FreeHGlobal(ipObjectName);

    if (nLength == 0)

    {

     Console.WriteLine("nLength returned at zero! " + strObjectTypeName);

     return null;

    }

    ipObjectName = Marshal.AllocHGlobal(nLength);

   }

   objObjectName = (Win32API.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ipObjectName, objObjectName.GetType());

   if (Is64Bits())

   {

    ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);

   }

   else

   {

    ipTemp = objObjectName.Name.Buffer;

   }

   if (ipTemp != IntPtr.Zero)

   {

    var baTemp = new byte[nLength];

    try

    {

     Marshal.Copy(ipTemp, baTemp, 0, nLength);

     strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()));

    }

    catch (AccessViolationException)

    {

     return null;

    }

    finally

    {

     Marshal.FreeHGlobal(ipObjectName);

     Win32API.CloseHandle(ipHandle);

    }

   }

   string path = GetRegularFileNameFromDevice(strObjectName);

   try

   {

    return path;

   }

   catch

   {

    return null;

   }

  }


推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式