Documentation() OnRun() MyFileWatcher := MyFileWatcher.FileSystemWatcher(); MyFileWatcher.Path := 'C:\WatchThis'; MyFileWatcher.EnableRaisingEvents := TRUE; MESSAGE('Ready to test'); LOCAL TriggerThis(inputMsg : Text) MESSAGE(inputMsg); IF(GUIALLOWED) THEN MESSAGE('GUI allowed') ELSE MESSAGE('GUI not allowed') MyFileWatcher::Changed(sender : Variant;e : DotNet "System.IO.FileSystemEventArgs") TriggerThis(e.FullPath); MyFileWatcher::Created(sender : Variant;e : DotNet "System.IO.FileSystemEventArgs") TriggerThis(e.FullPath); MyFileWatcher::Deleted(sender : Variant;e : DotNet "System.IO.FileSystemEventArgs") TriggerThis(e.FullPath); MyFileWatcher::Error(sender : Variant;e : DotNet "System.IO.ErrorEventArgs") TriggerThis(e.ToString()); MyFileWatcher::Renamed(sender : Variant;e : DotNet "System.IO.RenamedEventArgs") TriggerThis(e.FullPath); MyFileWatcher::Disposed(sender : Variant;e : DotNet "System.EventArgs") TriggerThis(e.ToString());
Answers
what does not work in this situation?
The client and server does not keep a "pipe open" for communication when a object exit, it is sort of a simple webpage - you render the content and the next action is performed when somebody clicks something or the page refreshes.
So your codeunit will exit with a 'Ready to test' and nothing happens after that. All variables including your file watcher dotnet is freed when the codeunit exits.
Event messages like the "Ready to test" is buffered until the object exists, another dialog is opened (i.e. confirm) or a few other events happens (you can try that by calling message, delaying for 30 seconds and then calling message again. You'll find that the delay is done before showing any of the messages).
A way to make your code work (just as a simple draft pseudo code would be):
1. start a background job which will never exit where the file system triggers are fired and recorded to a table. You need to make this one call itself.
2. create a page which auto-refreshes at some interval (use the ping-pong control add-in), reads the table and shows the messages accordingly.
I not 100% sure, but a better implementation might be to define the triggers which record events to a table in a single-instance codeunit which you then declare from your page. Such a codeunit will keep its global variables on the service tier (until that one is restartet) if i remember it correctly...
In nav 2009 I had a colleague doing the C/AL part, so I don't know how i achieved this. But in nav 2009 we had a codeunit that listened for COM events (making the .net assembly com visible). This codeunit would listen for events and create orders or quotes based on events raised by a webservice. And this is what I'm trying to port to nav 2013 / 2016.
I know that I can create orders using nav's soap services. But i would like to change context to those orders once they are created. (Could this perhaps be done with triggers of some sort) ... I am very new to NAV and C/AL ... But learning fast
If its not possible to have a codeunit running, that has implemented a .net assembly with events, as long as a nav client is running. Then one of @lynge 's option seems to be the best approach
Thanks again
Søren
forum.mibuso.com/discussion/67448/net-event-handling-server-client-callback-error-when-opening-page-41-42