簡體   English   中英

如何在 C# 中關閉文件的現有句柄

[英]How to close existing handle on file in C#

如何在 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM