【问题标题】:check if a text file is opened in notepad检查是否在记事本中打开了文本文件
【发布时间】:2013-08-06 13:15:07
【问题描述】:

如何在记事本中查看是否打开了特定的.txt文件?

我已经尝试过这里提到的解决方案

Is there a way to check if a file is in use?

但它们适用于 Word 和 pdf 文件,但不适用于在记事本中打开的 txt 文件。

这是我写的代码。

public bool IsFileOpen(string strFileName)
{
    bool retVal = false;
    try
    {
        if (File.Exists(pstrFileName))
        {
            using (FileStream stream = File.OpenWrite(pstrFileName))
            {
                try
                {    
                }
                catch (IOException)
                {
                    retVal = true;
                }
                finally
                {
                    stream.Close();
                    stream.Dispose();
                }
            }
        }
    }
    catch (IOException)
    { //file is opened at another location 
        retVal = true;
    }
    catch (UnauthorizedAccessException)
    { //Bypass this exception since this is due to the file is being set to read-only 
    }
    return retVal;
} 

我在这里错过了什么吗??

我的要求: 我有类似于 VSS 的应用程序。当用户签出特定文件并打开并尝试签入相同的文件时,它已打开。假设应用程序会发出警告消息。为此,我使用了上述功能。它适用于 word 和 pdf。

【问题讨论】:

  • 我相信这是因为记事本只是打开文件,读取流并关闭流,因此没有锁定文件。但是 Word 会保持文件的打开和锁定状态。
  • Belogix 是正确的,文件没有被使用,因此你的代码工作正常
  • 您这样做是为了达到什么目的?正如已经评论的那样,这种方法对于任何加载/读取/关闭的应用程序都会失败
  • 你的最终目标是什么?如果文件不影响文件,为什么有兴趣知道文件是否在记事本中打开?
  • 不可能,唯一关闭的方法是检查所有打开的记事本的窗口标题,但它们只包含文件名,而不是路径,所以它不会真正起作用

标签: c# winforms file file-io


【解决方案1】:

扩展我的评论。仅当句柄被应用程序保持打开时,文件才会被锁定。例如,Word 将打开文件、读取流并维护句柄,以便其他应用程序无法在用户处理该文件时删除该文件。

记事本和其他应用程序,只需打开文件,读入整个流,然后关闭文件释放它们所拥有的锁。这意味着该文件不再被锁定,并且可以被另一个应用程序编辑甚至删除,并且记事本不会关心,因为它在内存中有自己的副本。

您可以尝试获取记事本实例并检查文件是否打开,但这最终不是一个好主意。如果文件没有被锁定,那么您应该可以随意使用它。

【讨论】:

  • 不确定我是否应该投票,因为“2,222”是一个很好的数字;)
  • 我知道,我一直将我的大部分答案作为 cmets 发布,因为我喜欢 2,222,但我认为 3,333 看起来更好! ;-)
  • 没有一种机制来确定文件是否从进程实例打开,因为进程在读取文件后没有与文件交互。
  • 它必须以某种方式保持至少文件路径 - 否则 Ctrl+S 将不起作用。
  • @AlexK。 - 你是对的,但你可以得到应用程序的标题,所以“记事本 - 我的示例文件.txt”但是一个 hack 以及为什么我不建议这样做!
【解决方案2】:

这是我刚想出的一个 hack 解决方案,但它应该对你有用。这利用了 System.Diagnostics。

Process[] processes = Process.GetProcessesByName("notepad");
        for (int i = 0; i < processes.Length; i++)
        {
            Console.WriteLine(processes[i].MainWindowTitle);
            if (processes[i].MainWindowTitle.Equals("myFile.txt - Notepad"))
            {
                Console.WriteLine("The file myFile is Open!");
            }
        }
        Console.ReadLine();

希望这应该可以解决问题。我的示例查看是否以窗口标题“myFile.txt - Notepad”打开了记事本实例。窗口名称始终为“filename.extension - Notepad”,因此您可以根据需要进行处理。

我想您可以调用 System.IO.File.GetLastAccessTime(filePath)。然后,您可以每隔一段时间轮询文件,当访问时间更改时,您知道文件已打开,然后您可以触发文件已打开的事件。请参阅此处的 Jeffs 帖子: Detect File Read in C#

【讨论】:

  • 唯一的问题是如果我有一个文件C:\Pete.txtC:\Test\Pete.txt。在记事本中打开的是哪一个?
  • 我已经用可能对 Vijay 有用的东西修改了我的答案。
  • 我喜欢这个新想法,但这只会帮助您了解上次访问的时间,而不是用户是否仍然打开它?他们可能会立即关闭它或将其最小化并忘记它,因此文件仍将打开。
  • Belogix 这是一个没有吃蛋糕的例子。正如其他人所说,记事本没有打开文件句柄。我的建议充其量只是黑客工作,但如果真的需要,可能总比没有好。
  • 成功了 谢谢@DanielLane 为我节省了时间。
【解决方案3】:

您也可以使用以下策略执行此操作:记事本似乎确实对托管文件夹进行了某种锁定(尝试删除该文件夹,您会发现不能)。

您可以使用以下代码Using C#, how does one figure out what process locked a file? 来检查锁定文件夹的进程列表。 其中一个过程将是您的记事本。

您可以将它们按标题进行比较,作为提到的另一个答案。 如果您要打开文件 - 您可以保存 PID 并将其与返回的进程之一进行比较。

【讨论】:

    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2017-06-04
    相关资源
    最近更新 更多