【问题标题】:FileSystemWatcher.Changed fires immediately when Excel 2007 opens XLS file in compatibility mode当 Excel 2007 以兼容模式打开 XLS 文件时,FileSystemWatcher.Changed 立即触发
【发布时间】:2011-01-25 02:41:08
【问题描述】:

我们使用 FileSystemWatcher 来监控从我们的文档管理系统打开的文档,如果用户保存了文档,我们会询问他们是否也希望在我们的系统中更新它们。

Excel 2007 中的 XLS 文件存在问题(尚未验证该问题在 2003 年不存在,但似乎只是在 2007 年以兼容模式打开的文件),其中 Changed 事件在打开时立即触发文件,然后在关闭文件时再一次,即使没有任何更改或用户选择在关闭时不保存。打开 XLSX 文件时不存在相同的行为。

我编写了一个测试应用程序来验证行为,您可以在 (http://www.just2guys.net/SOFiles/FSWExcel.zip) 找到它。在应用程序中,每个 NotifyFilter 类型都有一个 FileSystemWatcher,因此很明显为什么会触发 Changed 事件。

您能想到的任何方式仅在用户以某种方式实际保存文档时才提示用户?我可以在调用 Process.Start 后开始监视文件,这使我可以在打开文档时跳过消息,但在关闭文档时仍然会收到一条消息,即使没有任何更改。

【问题讨论】:

    标签: .net excel excel-2007 filesystemwatcher


    【解决方案1】:

    文件系统观察者通常是邪恶的。它烧了很多人,因为它在文件完全写入之前注册事件。

    我们已经能够通过移除它来代替睡眠循环模式、在采取行动之前添加静态延迟 (Thread.Sleep) 或两者的组合(接收事件、产生线程)来绕过它, 并在线程中循环,直到您认为没有通过检查最后一个 mod 日期/时间来更新它)。

    【讨论】:

    • 有趣的是,我认为我们在使用它的两种情况下都避免了这个问题,因为我们不会在事件期间立即触发对文件的任何访问。在一种情况下,它被添加到稍后处理的队列中,在另一种情况下,我们提示用户,这两者都需要足够的时间来让文件完全保存。不过,如果我们在任何其他地方使用它,我会记住这一点。
    【解决方案2】:

    我在 Word 中注意到了这一点,您可以简单地复制它:

    如果您使用 Office 应用程序打开 .doc 或 .xls 文件,时间戳会更改为打开文档的时间。

    如果您关闭应用程序,时间戳将重置为其原始值(仅当您没有保存时​​)。

    所以对于 Office 文件,您需要另外两项检查:

    • 打开时,当时间戳设置为当前时间时,检查文件是否可以独占打开

    • 在关闭时,检查时间戳是否“接近”当前日期和时间,或者检查文件的存档标志

    【讨论】:

    • 所以,我可以通过在调用 Process.Start 后立即开始监控来摆脱打开的,但关闭是让我感到悲伤的原因。似乎检查时间戳以查看它是否在当前时间的一定时间内会起作用,并提示是否是。如果他们在文档中按下“保存”按钮,您的打开检查不会以同样的方式失败吗?也许我读错了。我会尝试你的关闭建议,并适当标记。
    • 这仍然是一团糟,因为用户保存不会触发 Office 文档的 LastWrite 通知,但它们会触发其他所有内容,但这帮助我前进了很多,我非常有信心可以想办法解决。
    【解决方案3】:

    Excel 每次打开文件时都会创建一个临时文件 - 这可能就是您所看到的事件。检查 FileSystemEventArgs 的 Name 属性,如果文件名以 '~' 开头,则忽略该事件。

    【讨论】:

    • 不,不是这样。首先,它是 Changed 事件(而不是 Created),其次,我正在过滤 Filter 属性中的特定文件名。它肯定会触发该特定文件的更改事件,但仅当它是 XLS 文件时,而不是 XLSX
    猜你喜欢
    • 2017-10-22
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多