最近遇到一個問題,我在實現一個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