如何在C#中关闭文件的现有句柄?可能吗?
假设我使用管理员帐户运行代码?我可以强制关闭文件吗?
在另一篇文章中,其中一个答案是使用互操作:
[Flags]
enum MoveFileFlags {
MOVEFILE_REPLACE_EXISTING = 0x00000001,
MOVEFILE_COPY_ALLOWED = 0x00000002,
MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
MOVEFILE_WRITE_THROUGH = 0x00000008,
MOVEFILE_CREATE_HARDLINK = 0x00000010,
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);
static void delete() {
string fileName = @"c:\temp\test.xlsx";
bool success = false;
foreach(var e in Enum.GetNames(typeof(MoveFileFlags))) {
success = MoveFileEx(fileName, null, (MoveFileFlags) Enum.Parse(typeof(MoveFileFlags), e));
MessageBox.Show(string.Format("{0} success : {1}", e, success));
}
}
此解决方案无效。我们需要重新启动才能删除该文件。
另一个例子告诉我要杀死这个过程:
string fileName = @"c:\aaa.doc"; //Path to locked file
Process tool = new Process();
tool.StartInfo.FileName = "handle.exe";
tool.StartInfo.Arguments = fileName;
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();
}
问题是我不想杀死进程,因为锁定文件的进程是IIS或资源管理器。
我需要刷新网站的文件。
这是我正在使用的解决方案,它运行良好:
static void delete(string fileName) {
string handleTools = Path.Combine(Application.StartupPath, "handle.exe");
Process tool = new Process();
tool.StartInfo.FileName = handleTools;
tool.StartInfo.Arguments = fileName;
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();
Regex reg = new Regex(@"(?<pid>pid:\s+[0-9]*)\s*(?<type>type:\s+\w*)\s*(?<handle>[A-F0-9]*:\s+)");
Match match = reg.Match(outputTool);
string pid = null;
string handle = null;
if (match.Groups["pid"].Value != null) {
pid = match.Groups["pid"].Value;
if (!string.IsNullOrEmpty(pid)) {
pid = pid.Replace("pid: ", string.Empty);
}
}
if (match.Groups["handle"].Value != null) {
handle = match.Groups["handle"].Value;
if (!string.IsNullOrEmpty(handle)) {
handle = handle.Replace("handle: ", string.Empty).Replace(":", string.Empty);
}
}
if (!string.IsNullOrEmpty(handle) && !string.IsNullOrEmpty(pid)) {
tool = new Process();
tool.StartInfo.FileName = handleTools;
tool.StartInfo.Arguments = string.Format("-p {0} -c {1} -y", pid, handle);
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
File.Delete(fileName);
}
}
要使用此解决方案,您需要使用sysinternal
中的handle.exe