0
votes

I have an old native application written in Borland Delphi:

enter image description here

The application interfaces with the special hardware and creates/stores its data in a BDE/Borland Paradox Database in a .db file. I am not the author of this application and the company who created it is long gone.

I need to add some custom functionality to this application and namely, to be able to read the database when a certain hardware-related event occurs. I found an old C library that allows me to read the paradox .db file. So that part is covered.

What I am trying to accomplish now is to find a way to track the moment when this application writes into its .db file. So I decided to try the following in my test app:

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);
}

The problem is that it doesn't seem to see any changes to the database.

If I test it with a .txt file by opening it in a Notepad and then saving it with some changes, it works fine. But not with the app I need it to.

Here's how I know it's not working:

  • The application in question is already running.

  • I start my app next to it. It shows no errors or exceptions. So I know that my watcher.WaitForChanged function had started.

  • I wait for the hardware event to be registered in the application in question.

  • My test app doesn't see any changes.

  • I then copy the logfile.db file, while both the application and my test app are still running, and then open it in my laptop with Paradox DB viewer. And it shows the new entry in the database.

So why is FileSystemWatcher not catching that logfile.db file being changed?

PS. I do all this on a 64-bit version of Windows 7 Pro.

1
This may be relevant to you: stackoverflow.com/questions/3540801/…Sam Axe
does the LastWrite change on the file?TheGeneral
@SamAxe: Hmm. Interesting. I found this and this as well. I'll need to check that. I'm not sure though what is the proposed solution though? Do I have to flush the disk on a timer then, or what?c00000fd
Directory entries are guaranteed updated only when the handle is closed. The FileSystemWatcher looks for directory entry changes.Raymond Chen
@RaymondChen: So what's my other options to track the change in this case then? (I'd hate to just read/poll that database file on a repeating timer.)c00000fd

1 Answers

0
votes

The BDE is a strange and frustrating piece of software to work with. I'm not surprised that although FileSystemWatcher doesn't see any changes, copying logfile.db does show the changes.

The BDE performs write caching, and it's turned on by default. To turn it off, try either one of these methods:

  1. Use the BDE Administrator applet to modify the IDAPI32.CNF or IDAPI32.CFG file, setting LOCAL SHARE to TRUE.

Or,

  1. Modify the registry for the machine running the BDE: [HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT] LOCAL SHARE = TRUE