And it sounded so promising… Using the FileSystemWatcher .NET class from a NAV 2013 page object to detect changes in a file system folder. I had it all figured out: using the right .NET assembly, responding to the FileSystemWatcher’s events and making sure the object runs on the RTC (as opposed to on the Service Tier).


In the OnOpenPage trigger, I instantiated the FileSystemWatcher, told it to monitor my desktop folder (Environment is another .NET Interop variable, also running on the client), and started the event raising mechanism.


The code above, which worked just fine in a Visual Studio console application, does not produce any results in NAV, i.e. does not trigger any of the events below.


Any ideas, anyone?

5 Responses to “DotNet Interop, RunOnClient and WithEvents”

  1. Jens M-P Says:

    Unfortunately, this is how NAV2013 currently works. The Client does not know about the Page until after the OnOpenPage trigger has been run so it cannot associate the dotnet object triggers with the page (it does not hook up the events correctly)

    So in the current codebase, as a work around, the user can place the initialization in a trigger that gets run after the OnOpenPage trigger - e.g. the OnAfterGetRecord() trigger like this:


    myVar := myVar.myVarType();

    But of course that requires a record :-(

    Another workaround is to use a client add-in, as that gets instantiated and hooked up to events by the client code.

    I know that the current behavior is not as desired. Unfortunately it is not trivial to change, so for us to consider a hotfix would require feedback indicating that this is indeed very important.

    Jens Møller-Pedersen [MSFT]
    Comment provided ‘as-is’ and does not promise anything on MS behalf

  2. jhoek Says:

    Thanks for your explanation, Jens - much appreciated!

    The pages of the solution that I made this proof-of-concept for do have source tables, so that shouldn’t be a problem (assuming that’s what you mean by “But of course that requires a record”).

    With this new knowledge in mind, I think I’ll give it another try, and post my findings here.

    Thanks again!

  3. jhoek Says:

    BTW, for those wondering why my FileSystemWatcher variable is a global, despite my frequent and religious pleas to use locals only: this is all about the lifetime of the variable.

    As a local, upon leaving the block of code in which it is defined, the variable would go out of scope and be destroyed. In our case, there would be nobody left to fire the events in response to file system changes; not what we want.

    We want the FileSystemWatcher to be around for the entire lifetime of the page, so that it, while the page is open, it can trigger the event code. That is of course why we need a global variable - its lifecycle is a long as the lifecycle of the page it lives in.

  4. jhoek Says:

    @Jens: The initialization of the FileSystemWatcher variable got moved to a separate function, that, judging from the page’s caption, is called successfully from the OnAfterGetRecord trigger.

    IF ISNULL(FileSystemWatcher) THEN BEGIN
    FileSystemWatcher := FileSystemWatcher.FileSystemWatcher();
    FileSystemWatcher.Path := Environment.GetFolderPath(EnvironmentSpecialFolder.Desktop);
    FileSystemWatcher.EnableRaisingEvents := TRUE;

    CurrPage.CAPTION := FileSystemWatcher.Path;

    However, still none of my events are being triggered… :(
    I must be doing something else wrong, eh?

  5. ChrisM Says:

    @Jens: I think it really would be good to have that. If not through a hotfix, at least in nav8 ;) With client add-ins there is similar “problem”: I love the new possibilities to access methods and properties of the add-in. Unfortunately they are only accessible in certain triggers (OnAfterGetRecord, but not OnInsertRecord), which makes it bit of a pain to use.

Leave a Reply

To prove you're a person (not a spam script), type the security text shown in the picture. Click here to regenerate some new text.
Click to hear an audio file of the anti-spam word