West Wind Internet and Client Tools 6.21 is here
West Wind Client Tools 6.21 is here which is mainly a maintenance release. However there are also a couple of new and improved features:
- wwDotnetBridge now supports Event Handling for .NET Objects
- New .NET Runtime Loader for wwDotnetBridge
- Support for >16mb Http Uploads
If you are a registered user you should have gotten an update notification. Otherwise you can download the latest shareware version from here:
Pre-6.x registered versions can be upgraded to the latest versions here:
- Upgrade Internet and Client Tools
- [Upgrade from West Wind Internet Protocols)(https://store.west-wind.com/product/wwclient60_up)
Event Handling for wwDotnetBridge
This is a cool feature that opens up additional features of .NET to FoxPro. You can now use wwDotnetBridge to handle .NET events in an asynchronous manner. Similar to the behavior of async method calls that was introduces a few releases back you can now handle events in .NET and get called back, without having to register the .NET component and implement a COM interface.
This was previously not possible or at the very least required that you created a COM object and interface that mapped the .NET type and was registered. With this new functionality you can now use only wwDotnetBridge without any sort of special registration or even having to implement a FoxPro interface. You can simply create a proxy object that can handle select events that you choose to handle. Other events are simply ignored.
So what can you do with this? Here are a few example ideas:
- Use the FileSystemWatcher on a folder and be notified of file updates
- Use SMTPClient natively and get notified on SMTPClient events
- Use WebClient and get notified of Web Events
Basically most components that use events can now be used with wwDotnetBridge!
This feature was landed in the OSS version of wwDotnetBridge by a contributor, Edward Brey, who did most of the work for the event handling. Thanks Ed!
An Example
The following is an example using the .NET FileSystemWatcher object which allows you to monitor any file changes and updates in a given folder and optionally all of its subfolders.
The following monitors all changes in my c:\temp
folder and all its subfolders which includes my actual Windows Temp folder - meaning it's a busy folder, lots of stuff gets written to temp files in Windows, so this generates a lot of traffic.
CLEAR
LOCAL loBridge as wwDotNetBridge
loBridge = GetwwDotnetBridge()
*** Create .NET File Watcher
loFW = loBridge.CreateInstance("System.IO.FileSystemWatcher","C:\temp")
loFw.EnableRaisingEvents = .T.
loFw.IncludeSubDirectories = .T.
*** Create Handler instance that maps events we want to capture
loFwHandler = CREATEOBJECT("FwEventHandler")
loSubscription = loBridge.SubscribeToEvents(loFw, loFwHandler)
DOEVENTS
lcFile = "c:\temp\test.txt"
DELETE FILE ( lcFile )
STRTOFILE("DDD",lcFile)
STRTOFILE("FFF",lcFile)
* Your app can continue running here
WAIT WINDOW
loSubscription.Unsubscribe()
RETURN
*** Handler object implementation that maps the
*** event signatures for the events we want to handle
DEFINE CLASS FwEventHandler as Custom
FUNCTION OnCreated(sender,ev)
? "FILE CREATED: "
? ev.FullPath
ENDFUNC
FUNCTION OnChanged(sender,ev)
? "FILE CHANGE: "
? ev.FullPath
ENDFUNC
FUNCTION OnDeleted(sender, ev)
? "FILE DELETED: "
? ev.FullPath
ENDFUNC
FUNCTION OnRenamed(sender, ev)
LOCAL lcOldPath, lcPath
? "FILE RENAMED: "
loBridge = GetwwDotnetBridge()
lcOldPath = loBridge.GetProperty(ev,"OldFullPath")
lcPath = loBridge.GetProperty(ev,"FullPath")
? lcOldPath + " -> " + lcPath
ENDFUNC
ENDDEFINE
How does it work?
The event handling is based on a simple callback mechanism that uses a FoxPro event handler that is passed into .NET to be called back whenever an event occurs. The behavior is similar to the way the BINDEVENT()
works in FoxPro with a slightly more explicit process.
Allows you to capture events on a source object, by passing in a callback handler that maps the events of the target object with corresponding methods on the handler.
To handle events:
Create an Event Handler Object
Create aCustom
class that implements methods that match the events of the .NET object that fires events with aOn<EventName>
prefix. Each 'asdd' method's parameters should match the parameters of the .NET event delegate. You only need to implement the methods you want to listen to - other events are ignored.Create an Event Subscription
CallloBridge.SubscribeToEvents()
which binds a .NET event source object to a FoxPro event handler.Continue running your Application
Events are handled asynchronously in .NET and run in the background. Your application continues running and as events fire in .NET, theOn<Event>
methods are fired on the Event Handler object in FoxPro.Unsubscribe from the Event Subscription
When you no longer want to listen to events, callloSubscription.UnSubscribe()
. Make sure you do this before you exit FoxPro or you may crash VFP on shutdown.
The key here is that you have to make sure that the .NET object that you want to handle events on as well the event handler stay alive because they essentially run in the background waiting for events to fire. This means storing these references on permanent objects like your main application's form or the FoxPro _screen or global variables.
Events are not as prominent in .NET as they used to be back in the high flying days of UI frameworks. Few operational components fire events, but many of the core system IO services have events you can handle. Progress events and completion are common.
Now we have the tools to use these event in the same easy fashion as all other .NET access with wwDotnetBridge.
New wwDotnetBridge .NET Runtime Loader
In this release the .NET runtime loader used for wwDotnetBridge has been updated to use the latest loader specific for .NET 4.0 and later. In past years we weren't able to use the new loader because the older versions still loaded .NET 2.0, but with the switch to 4.5 recently we can now take advantage of the new loader.
There are a couple of advantages here. The new loader is the officially recommended approach and provides a cleaner path to runtime loading, and more importantly it provides more error information. Previously the error information available from CLR loading was very cryptic as the runtime did not report the underlying error only a generic load failure error. The new version reports the underlying error information which is now passed to wwDotnetBridge.
This feature was also landed by Edward Brey in the OSS version of wwDotnetBridge.
Greater than 16meg wwHttp Uploads
The wwHttp class works with strings to handle buffering of data that is sent to a server and as such there are issues with FoxPro's 16mb string size limit. As it turns out there are a few ways to work with strings larger than 16mb in FoxPro but one has to be very careful that strings are copied and not mutated. The latest versions of Web Connection and Client Tools handle larger than 16mb strings in a few new places by carefully avoiding mutating string functions and as a result can now handle larger strings.
Internally wwHttp can now use a file stream to write out the post data to a temporary file and then pick up the data to send to the server in chunks. This basically is parallel behavior to the core string based POST
behavior used before and it has to be explicitly enabled using a new lUseLargePostBuffer
property:
lcUrl = "https://someurl/download"
loHttp = CREATEOBJECT("wwHttp")
loHttp.lUseLargePostBuffer = .T. && enable >16mb uploads
oHttp.AddPostKey("upload","c:\sailbig.jpg",.T.,"image/png")
lcResponse = oHttp.HttpGet(lcUrl)
Release Summary
Besides the marquee features, there are just a few small tweaks and bug fixes to the core libraries.
To see all that's changed in recent versions:
Enjoy...
+++ Rick ---
Hi Rick,
I've downloaded wwDotNetBridge yesterday from github. It looks like it was a few months old.
Do I need to download it now from other place? I only need that library.
Also, I'm trying to resolve the issue with Newtonsoft.Json.dll Right now I can not figure out where should I add the reference to my solution from. I probably deleted it from GAC in attempt to fix the issue and now even though I added the package to my solution, I can not figure out where the reference should come from.
Those versions are different. They have a few differences in terms of support features and the open source version doesn't have some of the support features that are provided in the commercial version.
If you only need the wwDotnetBridge interface then the open source version from GitHub should be all you need.
+++ Rick ---