【问题标题】:Saving changes in Beyond Compare does not trigger FileSystemWatcher Changed event在 Beyond Compare 中保存更改不会触发 FileSystemWatcher Changed 事件
【发布时间】:2018-02-15 21:22:53
【问题描述】:

这没有任何意义,但是如标题所述,当在 FileSystemWatcher 监视的文件夹中使用 Beyond Compare 修改文件时,不会触发 Changed 事件。

当使用 Notepad++ 修改同一个文件时,会触发 Changed 事件。 当我在使用 Beyond Compare 保存后在记事本中打开它并且更改存在时,我确实验证了在 Beyond Compare 中保存时文件实际上已更改。

以前有人遇到过这种奇怪的情况,知道为什么会发生这种情况,以及如何在从 Beyond Compare 保存时触发 Changed 事件?

与 IMO 无关的标准 FSW 代码:

fswDir = new FileSystemWatcher
{
    Path = dirPath,
    NotifyFilter = NotifyFilters.LastWrite,
    Filter = "*.*",
    EnableRaisingEvents = true
};

private void OnFswDirf_Changed(object sender, FileSystemEventArgs e)
{           
    var filePath = e.FullPath;
    // Not executed when file saved by BC, executed when file saved by Notepad++.
}

【问题讨论】:

  • 把你的代码放在那里,让我们在那里出错......
  • 行为良好的程序不会修改文件。风险太大,崩溃可能会导致永久性数据丢失。任何程序也不能可靠地修改文本文件。它重新创建一个文件,你应该看到创建、重命名和删除事件。
  • @HansPassant 我的代码不会以任何方式修改磁盘上的文件。该文件由 Notepad++ 或 Beyond Compare 修改,当文件保存在 Notepad++ 中时,会触发 Changed 事件,并且 Change Type 是 WatcherChangeTypes.Changed,而不是 Created,因此很明显 Notepad++ 表现不佳或 FileSystemWatcher 对更改类型有误。无论哪种方式,Changed 事件都会被触发,但是当文件被 Beyond Compare 更改时,该事件不会触发,因此这些程序到底在做什么与我的 FielSystemWatcher Changed 事件没有触发的问题无关。
  • 尚不确定 Beyond Compare 到底在做什么,但在我更改 FSW 过滤器属性以监视所有文件后,我发现它写入了两个 XXXX.temp 文件,然后写入了一个 MyFileName~XXXX.temp,之后是原始文件文件已修改,但所触发的 Changed 事件均未包含原始文件 FullPath...
  • Beyond Compare 保存文件时,它首先将内容写入临时文件,然后使用 Win32 ReplaceFile 函数将原始文件的内容替换为新内容。根据错误代码,我相信 Windows 在幕后将其作为重命名处理,并带有一些额外的簿记。我本来希望文件系统观察器中会出现这种变化,但这并不是我第一次听说这种技术会混淆其他软件。

标签: .net filesystemwatcher beyondcompare


【解决方案1】:

订阅所有 FSW 事件和所有 NotifyFilter 枚举后,我设法获得了 Beyond Compare 4 File>Save 功能触发的完整 FSW 事件序列,以防将来有人需要:

  1. 已创建:XXXXXX.tmp 文件。
  2. 已更改:XXXXXX.tmp 文件。
  3. 已更改:XXXXXX.tmp 文件。
  4. 已创建:OriginalFileName.ext~XXXXXXXXX.TMP 文件。
  5. 已更改:OriginalFileName.ext~XXXXXXXXX.TMP 文件。
  6. 重命名:OriginalFileName.ext 文件。
  7. 已更改:OriginalFileName.ext~XXXXXXXXX.TMP 文件。
  8. 已更改:OriginalFileName.ext 文件。

经过消除过程后发现,为了获得 BC NotifyFilter 所做的更改,需要将其设置为:

NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Attributes;

之后 Changed 事件将捕获 BC 的文件更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 2017-05-07
    • 1970-01-01
    相关资源
    最近更新 更多