最近遇到一个问题,我在实现一个C#客户端的附件上传功能时,只能上传未被其余进程占用的文件,所以每次上传文件前须要先判断被选中文件是否被占用。尤为是PDF文件,当以AdobeReaderXI打开时,文件会处于占用状态,此时若强行上传,会触发异常。html
我上网查了下使用C#判断文件是否被占用的方法。参考了这篇博客:bash
http://www.cnblogs.com/MR520/archive/2012/03/20/2408782.html函数
我实现了一个函数:测试
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Runtime.InteropServices; namespace FileStatusTest { public class FileStatusHelper { [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 static readonly IntPtr HFILE_ERROR = new IntPtr(-1); /// <summary> /// 查看文件是否被占用 /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static bool IsFileOccupied(string filePath) { IntPtr vHandle = _lopen(filePath, OF_READWRITE | OF_SHARE_DENY_NONE); CloseHandle(vHandle); return vHandle == HFILE_ERROR ? true : false; } } }
调用方法为:搜索引擎
if (FileStatusHelper.IsFileOccupied(@"文件路径")) { MessageBox.Show("文件已被占用"); } else { MessageBox.Show("文件未被占用"); }
测试结果以下:spa
一、设有一PDF文件,打开前调用函数FileStatusHelper.IsFileOccupied,显示【文件未被占用】命令行
二、使用AdobeReaderXI打开此PDF文件,调用函数FileStatusHelper.IsFileOccupied,显示【文件已被占用】code
三、关闭AdobeReaderXI后调用函数FileStatusHelper.IsFileOccupied,显示【文件未被占用】htm
在我遇到的场景中,实现对文件是否被占用进行判别就能够了,如文件已被占用,给出相应提示并让用户本身关闭占用文件的进程便可。blog
不过,在好奇心的驱使下,我仍是查了下如何使用C#语言解除其余进程对文件的占用。我用搜索引擎初步找了一下,发现要想仅使用C#作到这些还真不太容易。
后来我参考了这个stackoverflow上的问题:
http://stackoverflow.com/questions/242882/how-can-i-unlock-a-file-that-is-locked-by-a-process-in-net
里面给出了一个建议,使用Unlocker软件的命令行参数实现对指定文件的解锁。
我从百度上下载的Unlocker1.9.2,下载地址以下:
http://dlsw.baidu.com/sw-search-sp/soft/c0/12918/Unlocker1.9.2.exe
安装此程序后,使用下面的命令便可直接解锁指定文件:
Unlocker.exe 要解锁的文件名 /s
若是必定要使用C#解锁某一被占用的文件,可在Unlocker安装目录中将这四个文件提取出来:Unlocker.exe、UnlockerCOM.dll、UnlockerDriver5.sys、UnlockerHook.dll。将它们放到咱们程序目录中,经过Process.Start方法调用Unlocker.exe,并附带上相关参数,就能够实现用C#代码解锁某一指定文件了。另有一点须要注意,运行Unlocker.exe时须要用到管理员权限。
使用此方法测试结果以下:
一、设有一PDF文件,打开前调用函数FileStatusHelper.IsFileOccupied,显示【文件未被占用】
二、使用AdobeReaderXI打开此PDF文件,调用函数FileStatusHelper.IsFileOccupied,显示【文件已被占用】
三、使用Unlocker解锁后,调用函数FileStatusHelper.IsFileOccupied,显示【文件未被占用】
END