c# - 有关正在使用的文件或文件夹的问题 : get the name of another Process that use file or folder

标签 c# process ioexception access-denied

我使用 C# .NET,对比 2008,.net 3.5

对我来说,这很困难,但我需要 C# 中的示例代码:

  1. 检查文件或文件夹是否正在使用

  2. 如果文件或文件夹正在使用中,使用它的进程的名称

例如,在我的问题中。

我尝试删除文件,但我得到“该进程无法访问文件‘XYZ’,因为它正被另一个进程使用。”异常。

File.Delete(infoFichero.Ruta);

我想检查文件是否正在使用,以及使用它的进程的名称。

我需要示例代码、源代码。我不想使用 C++,我不知道 C、C++、非托管代码或 WinApi。我只想使用 C# 代码(托管代码 .net)。

我已经阅读了几个引用资料但没有得到示例代码源,

如何检查文件是否在使用中?

Emulate waiting on File.Open in C# when file is locked

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/9dabc172-237a-42db-850e-ada08885a5d5

How to check if a file is in use?

Easiest way to read text file which is locked by another application

Using C# is it possible to test if a lock is held on a file

编辑: 来自严俊-MSFT

  string path = "D:\\temp2.xlsx";
            foreach (Process c in Process.GetProcesses()) {

                if (c.MainWindowTitle.Contains(Path.GetFileName(path))){
                    MessageBox.Show(c.ProcessName);
                    return;
                }
            }

            try{
                FileInfo f = new FileInfo(path);

                f.Delete();
            }
            catch (Exception ex){

                MessageBox.Show(ex.Message);
            }

... 但很难 100% 解决所有问题。

  1. 如果 c.MainWindowTitle == null 或不包含文件名时出现问题。

  2. 另一台机器、PC、服务器等中的共享文件夹出现问题,例如:

文件.删除(@\desiis\TEmporal\Project\script.targets);

任何示例代码,我向专家、MVP 和任何人寻求帮助。

更新:文件夹的相同问题

最佳答案

我认为,如果不进入 WinApi,就无法找到打开文件的进程。至于检查它是否在使用中,正如您链接到状态的 SO 问题一样,您真正可以做的唯一事情就是将文件访问尝试包装在 try/catch block 中。

查找打开了哪个文件的代码可能很丑陋,但可能有一个 API 可以很好地包装它。有 3rd 方实用程序会告诉你这一点(Unlocker 是最著名的例子)。您也可以使用 ProcessExplorer按文件名搜索打开的文件句柄。那些并没有真正帮助你。

我在这里想要表达的简短回答是,您在已经链接的 SO 问题中找到了问题第一部分的答案,而第二部分可能需要 WIN32 调用,而您想要避免,但您可能不得不在 Win32 中亲自动手……还需要帮助吗?

编辑:您可以支付给 sysinternals Handle公用事业。您需要获取该命令的输出并自行解析。您可以像这样读取已执行进程的输出

string result = proc.StandardOutput.ReadToEnd();

问题是您将在第一次运行 Handle 实用程序时弹出许可协议(protocol)。如果这是您希望部署的东西,更不用说整个许可问题...

如果您仍然感兴趣,我可以向您展示如何进行此操作。

编辑:这是一个可运行的程序,它将找到任何具有文件打开句柄的程序的 exe 名称和 pid。我添加了评论,但如有必要可以进一步详细说明。我在这里使用正则表达式来解析输出,因为考虑到手头的任务,这最有意义。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ProcessStartInfo si = new ProcessStartInfo();
            si.FileName = "handle.exe";     //name of the handle program from sysinternals
                                            //assumes that its in the exe directory or in your path 
                                            //environment variable

            //the following three lines are required to be able to read the output (StandardOutput)
            //and hide the exe window.
            si.RedirectStandardOutput = true;
            si.WindowStyle = ProcessWindowStyle.Hidden;
            si.UseShellExecute = false;

            si.Arguments = "test.xlsx";     //this is the file you're trying to access that is locked

            //these 4 lines create a process object, start it, then read the output to 
            //a new string variable "s"
            Process p = new Process();
            p.StartInfo = si;
            p.Start();
            string s = p.StandardOutput.ReadToEnd();

            //this will use regular expressions to search the output for process name
            //and print it out to the console window
            string regex = @"^\w*\.EXE";
            MatchCollection matches = Regex.Matches(s, regex, RegexOptions.Multiline);
            foreach (var match in matches)
            {
                Console.WriteLine(match);
            }

            //this will use regex to search the output for the process id (pid)
            //and print it to the console window.
            regex = @"pid: (?<pid>[0-9]*)";
            matches = Regex.Matches(s, regex, RegexOptions.Multiline);
            foreach (var obj in matches)
            {
                Match match = (Match)obj;   //i have to cast to a Match object
                                            //to be able to get the named group out
                Console.WriteLine(match.Groups["pid"].Value.ToString());
            }

            Console.Read();
        }
    }
}

关于c# - 有关正在使用的文件或文件夹的问题 : get the name of another Process that use file or folder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3258704/

相关文章:

c# - IIS 应用程序池、内存管理

c# - 从另一个进程接收消息

c# - 在 .net 中显示文件上传进度

javascript - 在 Node.js 脚本中运行两个脚本

c++ - 使用 C++,如何在终止之前检测进程

c# - System.Diaganostics.Process.Id 与任务管理器中显示的进程 ID 不同。为什么?

android - 删除谷歌服务 json 文件

java - Android M 中 File.createNewFile() 方法抛出异常

java - 从文本文件中搜索特定文本

c# - 如何检测委托(delegate)类型之间的兼容性?