【问题标题】:Why is FileSystemWatcher never triggered on changes in open BDE/Paradox database file?为什么 FileSystemWatcher 从未在打开的 BDE/Paradox 数据库文件中发生更改时触发?
【发布时间】:2018-11-10 00:44:50
【问题描述】:

我有一个用 Borland Delphi 编写的旧本机应用程序:

应用程序与特殊硬件接口,并在.db 文件中的 BDE/Borland Paradox 数据库中创建/存储其数据。我不是此应用程序的作者,创建它的公司早已不复存在。

我需要向这个应用程序添加一些自定义功能,即当某个硬件相关事件发生时能够读取数据库。我找到了一个旧的 C 库,它允许我读取悖论 .db 文件。所以这部分被覆盖了。

我现在想要完成的是找到一种方法来跟踪此应用程序写入其.db 文件的时刻。所以我决定在我的测试应用程序中尝试以下内容:

static void Main(string[] args)
{
    string path = "C:\\Program Files\\Company Name\\logfile.db";

    string strDirName = Path.GetDirectoryName(path);
    string strFileName = Path.GetFileName(path);

    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = strDirName;

    watcher.NotifyFilter = NotifyFilters.Attributes |
        NotifyFilters.CreationTime | NotifyFilters.FileName | NotifyFilters.LastAccess |
        NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;

    watcher.Filter = strFileName;   // "*.db";

    watcher.IncludeSubdirectories = false;

    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);
    watcher.Error += new ErrorEventHandler(OnError); 

    watcher.EnableRaisingEvents = true;

    Console.WriteLine("Starting the watch...");
    Console.WriteLine("Folder: " + watcher.Path);
    Console.WriteLine("File: " + watcher.Filter);

    while (true)
    {
        watcher.WaitForChanged(WatcherChangeTypes.All);
        Console.WriteLine("-next-");
    }
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
    Console.WriteLine("-\"" + e.FullPath + "\", type=" + e.ChangeType + ", time=" + DateTime.Now);
}

private static void OnRenamed(object source, RenamedEventArgs e)
{
    Console.WriteLine("-\"{0}\" renamed to \"{1}\"", e.OldFullPath, e.FullPath);
}

private static void OnError(object source, ErrorEventArgs e)
{
    Console.WriteLine("#error: \"" + e.ToString() + "\", time=" + DateTime.Now);
}

问题是它似乎没有看到对数据库的任何更改。

如果我通过在记事本中打开 .txt 文件对其进行测试,然后通过一些更改保存它,它可以正常工作。但不是我需要的应用程序。

这是我知道它不起作用的原因:

  • 相关应用程序已在运行。

  • 我在它旁边启动我的应用程序。它没有显示错误或异常。所以我知道我的watcher.WaitForChanged 函数已经启动了。

  • 我等待在相关应用程序中注册硬件事件。

  • 我的测试应用没有发现任何变化。

  • 然后我复制 logfile.db 文件,同时应用程序和我的测试应用程序仍在运行,然后在我的笔记本电脑中使用 Paradox DB 查看器打开它。它会显示数据库中的新条目。

那么为什么FileSystemWatcher 没有发现logfile.db 文件被更改?

PS。我在 64 位版本的 Windows 7 Pro 上完成所有这些操作。

【问题讨论】:

  • 这可能与您有关:stackoverflow.com/questions/3540801/…
  • 文件的 LastWrite 是否发生变化?
  • @SamAxe:嗯。有趣的。我也找到了thisthis。我需要检查一下。我不确定建议的解决方案是什么?那么我是否必须在计时器上刷新磁盘,还是什么?
  • 目录条目保证只有在句柄关闭时才会更新。 FileSystemWatcher 查找目录条目更改。
  • @RaymondChen:那么在这种情况下,我还有什么其他选择来跟踪变化? (我不想在重复计时器上读取/轮询该数据库文件。)

标签: c# .net file-watcher bde paradox


【解决方案1】:

BDE 是一个奇怪且令人沮丧的软件。尽管FileSystemWatcher 没有看到任何变化,我并不感到惊讶,但复制logfile.db 确实显示了变化。

BDE 执行写缓存,默认情况下是打开的。要关闭它,请尝试以下任一方法:

  1. 使用 BDE 管理员小程序修改 IDAPI32.CNFIDAPI32.CFG 文件,将 LOCAL SHARE 设置为 TRUE。

或者,

  1. 为运行 BDE 的机器修改注册表:[HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database 引擎\设置\系统\初始化] 本地共享 = TRUE

【讨论】:

  • 是 1 和 2 的 AND 还是 OR 选项?我想我不知道 BDE 管理小程序是什么。我宁愿尝试在注册表中进行。虽然我真的很想在不对目标应用程序/环境进行任何修改的情况下解决它。
  • 感谢您的澄清。我明天试试,然后报告。不想在这么晚的时候弄乱那个硬件:)
  • 克里斯,忘记更新这篇文章了。我检查了 BDE 的安装,并且注册表中的 LOCAL SHARE 值已经设置为 TRUE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多