Hello everybody,
we need to receive events from a COM automation object.
The plan was to write a .NET wrapper that lives on a NAV 2009 page, calls our object, hands it tons of data from NAV and in turn receives events from it that it hands back to NAV through the OnControlAddIn event handler.
For testing purposes, I wrote a simple .NET program that throws events and a Control Add-In on an RTC page. This works like a charm: when the page is opened, my wrapper DLL starts the .NET DLL, I click some buttons, events trickle through to NAV, happiness ensues -- as long as
both the wrapper DLL and the wrapped DLL are strongly signed and in the RTC "Add-ins" directory. If one of these conditions is not met, NAV crashes with a file-not-found exception.
Unfortunately, our COM object is a historical C++ application, written in what is very much
un-managed code, so I'm afraid that signing it is out of the question. And since the
MSDN tells me that a "strongly named application or component cannot reference a weak-named component", I seem to be out of luck.
Soooo... any suggestions on how to open an old COM object from NAV 2009 in a manner that lets me receive events from it?
Edit: Just adding a few tags, because apparently "add-in" can never be found by the forum search: addin, add in
Answers
1) You need to use NAV 2009 SP1
2) You need to create the automation on NST, not on RTC (third parameter of Create must be default or false).
3) It means the automation must be installed on the NST layer.
MVP - Dynamics NAV
My BLOG
NAVERTICA a.s.
Addins run on RTC. Yes the dll for the addin needs to be in RTC and Service tier.
I think the link you provided mentions "Primary interop assemblies". Which means secondary assemblies do not?
Independent Consultant/Developer
blog: https://dynamicsuser.net/nav/b/ara3n
My apologies: yes, I am, of course, talking about the RTC -- on older versions of NAV, you could, after all, build automation objects WithEvents. And we have installed SP1; otherwise, as you said, ara3n, we wouldn't have Control Add-Ins.
Re gerdhuebner: Yes, that is my understanding as well.
You see, I'm clutching at straws here, and hoping that there is some way to either a) hand an event handle to a COM object, just like in the olden days, or b) wrap an unsigned non-.NET object in a strongly signed .NET assembly, or c) strongly sign our historical C++ COM object.
My research suggests that these are the only existing alternatives to actively polling our COM object every N seconds. It certainly doesn't look good, but I've already sunk so many hours into this mess that, by now, I'm willing to listen to even the wildest hacking propositions...
Independent Consultant/Developer
blog: https://dynamicsuser.net/nav/b/ara3n
- your requirement is to run a client side COM object in RTC
- the COM object uses events in the communication, but you alrady know that COM events are not supported in RTC client side COM objects
- you have discovered the Add-ins concept in RTC SP1 and want to utilize it, to overcome the lack in client side COM support
Now: Dependent on your szenario, this might event work.
Brief guideline
-> write an Add-in in a strongly signed library and register that in NAV (table Client Add-ins) and use it on a field on a page (Property ControlAddin)
-> Add a COM reference to your Add-in project. The COM library does not encessarily need to be strongly signed, but it must be registered with COM, of course.
-> You need to create a control in the CreateControl method of the Add-in, e.g. a Textbox; or is the COM object even a UI element?? If is is an UI element, then you want to create an instance of that and return it so it is shown in the Page? Great, do that!
-> In your Add-in class you not only create the COM object but also subscribe to the COM object's events. In the respective event handlers, formulate calls to the ControlAddIn event. (Basically you get the ControlAddIn event by implementing the IEventControlAddInDefinition interface in your Add-in class. If you use the StringControlAddInBase class, you have this already.) To the event you pass as a parameter as the message ID and text as data.
-> In C/AL code subscribe to the event and process the message id with the received data.
-> You can not call by method back into the Add-in, but you can update the data which the Add-in control is bound to and communicate this way.
You already might sense that using data binding might be a bad concept for sending commands to the Control Add-in. Instead I encurrage you to redesign / encapsulate your COM interface strategy from a method/event/property oriented call interface to a document based scheme:
The Add-in receives data through binding and can fire back data trough one event, where you can utilize message IDs to seperate between different event purposes. An Add-in can save data through binding. The data can be a single value, binary data or a whole XML document.
Christian Abeln
Program Manager Microsoft
Dynamics NAV
blogs.msdn.com/cabeln/
Once I converted my EXE (long story there) to a strongly signed DLL (tlbimp COMObject.tlb /out:COMObject.dll /keyfile:strongNameKey.snk) and copied this into the RTC's Add-In folder, I could receive events just fine. Humm. Apparently, registering a COM server in the RTC Add-In folder isn't enough -- it has to be a strongly signed DLL as well. That, or maybe it was just mulish.
Yeah, well, see: that might be a problem. Right now, I have a half-working automation object that is called from a CodeUnit and can show tons of data, but can't talk back to NAV, and a half-working Add-In Control that lives on a page and can talk back to NAV just fine, but doesn't really have any data to show. And concerning the data: This is another problem: we are handing our trusty PlanningBoard up to several MB of data of all types: resources, capacities, jobs, orders, settings... Right now, I can see only one way to initialize the PlanningBoard, and that is via a giant XML-file. I don't want to build a table for all that...
*sigh*
But anyway: thank you for getting the event side of things going, Christian.
- The first set of XML data that arrives at the Add-in contains some initial information and metadata which the control needs to issue further data requests based on user input.
- Then in reaction to OnControlAddIn triggers other XML data documents are sent to the Add-in through a bound xml page variable. The Add-in is intelligent enough to add / remove visual elemnts appropriately, instead of deleting and rebuilding the whole scene.
- And you don't necessarily need to create a complex table. XML data building and binding is all that is needed. The data can be collected by C/AL code and generated in several ways (COM object / XML Port).
A visualization that I have built with this approach is the TreeMap visualization for NAV, which is included in the VPC for NAV2009 SP1.
Christian Abeln
Program Manager Microsoft
Dynamics NAV
blogs.msdn.com/cabeln/
OK, so I'll just scrap our usual method based interface and convert it to a single call with some sort of XML monster structure. I'll hunt down that TreeMap VPC Demo thing and have a look at it. Well, I do have a couple of hours left to implement this whole mess before my vacation...
Thanks again for your help.
that is frustrating. Can i ask why this functionality is not supported ?