0

I learned about Control.ModifierKeys in this thread and this thread, and FileSystemWatcher here and a FileSystemWatcher-specific workaround here. However, when I combine the two, I'm running into a strange, but explainable, bug. At least, I have a hypothesis.

My form uses a FileSystemWatcher to detect changes to a file and run something whenever it triggers. However, the thing it runs is a bit distracting and time wasting, so I'm trying to get it to skip the run if the save is done by Ctrl+S, i.e. when the Control key is held down.

The code is something like this:

private void onFileChanged(object source, FileSystemEventArgs e)
{
    // The try/finally blocks prevent double raising of the changed event
    try
    {
        myFileWatcher.EnableRaisingEvents = false;
        if ((ModifierKeys & Keys.Control) != 0)
            MessageBox.Show("Control held down!");
        else
        {
            MessageBox.Show("Running stuff!");
        }
    }
    finally
    {
        myFileWatcher.EnableRaisingEvents = true;
    }
}

So that's all fine, noting that the two MessageBox.Show calls replace in-block code. Under normal use, it works. However, there is a very small time lag between the saving of the file and the triggering of onFileChanged. If the Ctrl key is released before onFileChanged triggers, i.e. if you tap Ctrl+S very quickly, very strange behavior results. For one, obviously, the Control key is not detected, but from here, even if you hold down Control after Ctrl+S until the popup shows, ModifierKeys will still be 0 and it will think Ctrl is not being held down. And then, if you hold down Ctrl while clicking the OK in the popup, all of a sudden ModifierKeys will keep firing the Control key even if you go File->Save in the file it's watching.

Is there a way to defeat this bug, or do I have to chalk it up as unfixable and tell my users to leave the Control key held down longer than they normally would in order to avoid this bug?

Community
  • 1
  • 1
Kevin T
  • 216
  • 1
  • 6
  • Do you mean the user edits the file in another application like notepad and presses Ctrl-S to save it? – ChrisWue Sep 19 '13 at 19:49
  • Yeah, that's exactly it. The application processes the file being watched and then runs a couple of processes that pop up windows and take a few seconds each to complete, so if you're editing and keep knee-jerking a Ctrl+S save to avoid losing work, you can imagine that would get annoying really quickly. – Kevin T Sep 19 '13 at 19:52
  • @KevinT don't really understand why you want to detect `Ctrl`, if you want to **determine** what kind of change is applied, you may want to look at the `e.ChangeType` in the `FileSystemEventHandler` – King King Sep 19 '13 at 19:57
  • When you're editing a file, you hit Ctrl+S pretty often, kind of as a way to save your changes and avoid losing your work. Reprocessing the file every time you do that is pretty counter-productive. The changetype won't help because I'm trying to detect if the file was saved via keyboard shortcut or saved via the File menu. – Kevin T Sep 19 '13 at 20:21
  • @KevinT What have you tried to detect the saving via `File menu`? BTW, I have to add that we have **1 more way** to save file, **I used this way frequently**, that's simply by ***closing the editor window first and click OK on the dialog appeared asking for saving changes to accept saving*** – King King Sep 19 '13 at 20:32
  • Why would I try to detect saving via File menu? I just want to block the run if it was saved by keyboard shortcut (it's also an option that the user can set). Closing Notepad and saving that way should go through too. – Kevin T Sep 19 '13 at 20:46

1 Answers1

0

I would try to set a global keyboard hook and record if Ctrl+S is still pressed or has been pressed within a certain time before the filewatcher event is fired.

Community
  • 1
  • 1
ChrisWue
  • 18,612
  • 4
  • 58
  • 83
  • I don't think it's going to work, as Stephen Toub's solution for checking for modifier keys falls back to ModifierKeys as shown in the comments: **Mladen 10 May 2006 1:04 PM #** great stuff! I'm wondering how would you check for a combination of CTRL+V or CTRL+ALT+k or similar? thanx. **Stephen Toub - MSFT 10 May 2006 5:41 PM #** System.Windows.Forms.Control.ModifierKeys should do the trick, telling you whether shift, alt, and/or control are pressed. – Kevin T Sep 19 '13 at 21:55
  • @KevinT `ModifierKeys` is useful but the point is **you have to know when you use it in your code**? using `global key hook` will catch the exact time the keys are pressed, perform some check and code accordingly. I doubt that the `global key hook` may be the internal implementation to update the `ModifierKeys` – King King Sep 19 '13 at 22:01
  • Hmm, if you insist, I'll take a look at it again tomorrow. I'm not entirely convinced that it'll work though. Of course, I could be wrong, as I'm still relatively new to C#. – Kevin T Sep 19 '13 at 22:28
  • Okay, I realize it's not exactly "tomorrow" anymore, but I finally got a chance to actually try it out and hack it around and it solves the problem! Thanks ChrisWue! – Kevin T Sep 25 '13 at 21:55