使用c#检测文件正在被那个进程占用 判断文件是否被占用的两种方法
C# 判断文件是否被占用的三种方法
using System.IO; using System.Runtime.InteropServices; [DllImport("kernel32.dll")] public static extern IntPtr _lopen(string lpPathName, int iReadWrite); [DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr hObject); public const int OF_READWRITE = 2; public const int OF_SHARE_DENY_NONE = 0x40; public readonly IntPtr HFILE_ERROR = new IntPtr(-1); private void button1_Click(object sender, EventArgs e) { string vFileName = @"c:\temp\temp.bmp"; if (!File.Exists(vFileName)) { MessageBox.Show("文件都不存在!"); return; } IntPtr vHandle = _lopen(vFileName, OF_READWRITE | OF_SHARE_DENY_NONE); if (vHandle == HFILE_ERROR) { MessageBox.Show("文件被占用!"); return; } CloseHandle(vHandle); MessageBox.Show("没有被占用!"); }
上述方法容易导致未占用文件被过程占用了,不可取的检查方案
public static bool IsFileInUse(string fileName) { bool inUse = true; FileStream fs = null; try { fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None); inUse = false; } catch { } finally { if (fs != null) fs.Close(); } return inUse;//true表示正在使用,false没有使用 }
第三种方案
/// <summary> /// 返回指示文件是否已被其它程序使用的布尔值 /// </summary> /// <param name="fileFullName">文件的完全限定名,例如:“C:\MyFile.txt”。</param> /// <returns>如果文件已被其它程序使用,则为 true;否则为 false。</returns> public static Boolean FileIsUsed(String fileFullName) { Boolean result = false; //判断文件是否存在,如果不存在,直接返回 false if (!System.IO.File.Exists(fileFullName)) { result = false; }//end: 如果文件不存在的处理逻辑 else {//如果文件存在,则继续判断文件是否已被其它程序使用 //逻辑:尝试执行打开文件的操作,如果文件已经被其它程序使用,则打开失败,抛出异常,根据此类异常可以判断文件是否已被其它程序使用。 System.IO.FileStream fileStream = null; try { fileStream = System.IO.File.Open(fileFullName, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None); result = false; } catch (System.IO.IOException ioEx) { result = true; } catch (System.Exception ex) { result = true; } finally { if (fileStream != null) { fileStream.Close(); } } }//end: 如果文件存在的处理逻辑 //返回指示文件是否已被其它程序使用的值 return result; }//end method FileIsUsed
要检测文件被那个进程占用,需要使用微软提供的工具Handle.exe,这里有微软提供的下载
我们可以在c#中调用Handle.exe 来检测到底哪个进程占用了文件
string fileName = @"c:\aaa.doc";//要检查被那个进程占用的文件 Process tool = new Process(); tool.StartInfo.FileName = "handle.exe"; tool.StartInfo.Arguments = fileName+" /accepteula"; tool.StartInfo.UseShellExecute = false; tool.StartInfo.RedirectStandardOutput = true; tool.Start(); tool.WaitForExit(); string outputTool = tool.StandardOutput.ReadToEnd(); string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)"; foreach(Match match in Regex.Matches(outputTool, matchPattern)) { Process.GetProcessById(int.Parse(match.Value)).Kill(); }