A few weeks ago a customer asked us for a replacement for a Notepad integration. They were using it for a long time with the Classic Client, but since they recently upgraded to the Role Tailored Client, they asked us if it was possible to integrate Notepad (or something like that) with the RTC.
So we decided to develop a Rich Text Editor for the RTC. The first release looks like this screen:
Challenge
One of the challenges of writing a Control Add-in is the deployment. If the Add-in isn’t deployed correctly, you will see an error on the page like this:
The correct deployment consists of the following steps:
- Copy the assembly to the Add-in folder of the Role Tailored Client
- Register the Add-in in Microsoft Dynamics NAV:
- Find the public key token of the Add-in assembly
- Add the name and public key token to table 2000000069 Client Add-in
For more detailed information on this see this article on MSDN: http://msdn.microsoft.com/en-us/library/dd983804.aspx
These steps involve a lot of manual to-do’s:
- Copy the assembly to all clients
- Find the public key token with some command line tool
- Manually enter the name and token into the Client Add-in table
Because I didn’t want to explain our customer they had to copy a dll to a certain folder on every single workstation that was using NAV, and nor wanted to travel to their office or trying to do it remote, I decided to come up with a solution for automatic deployment, including the assembly file.
Automatic deployment
The solution for automatic deployment consist of two Codeunits. One is a helper Codeunit with generic functions to deploy the Control Add-in if needed. The other Codeunit contains the detailed information of the Control Add-in itself.
Helper Codeunit
The first two functions of the helper Codeunit are self explaining:
In the function ClientAddInAvailable there is a call to the function AssemblyExists. This function contains a lot of .Net code. Basically it performs the following steps:
- Loop through all available assemblies in the Add-in folder
- For each assembly, check the public key token
- If the public key token is correct, determine if it is a valid Control Add-in
- If it is a valid Control Add-in search for the name of the Control Add-in
- If all of the above is correct, then the assembly is available
If the assembly is not available, we must create it in the Add-in folder. The function CreateAssembly accepts three parameters:
FileName: the filename of the assembly.
Folder: a subfolder to be created in the Add-in folder. Leave this empty to put the assembly directly into the Add-in folder.
Data: this is a BigText variable that contains the complete assembly in Base64 encoding.
On Windows systems with User Account Control enabled, the user might not have access to the Add-in folder. Only a process that is running as Administrator has access to this folder by default. The function IsElevated checks if the process has permissions. If not, it starts a separate elevated process. Of course the user must be warned before:
When the elevated command is run, the user get a screen like this:
After this, the Page continues to load including the just-in-time deployed Control Add-in!
Add-in Codeunit
The Codeunit with detailed information about the Add-in (in this example the Rich Text Editor), including the Base64 encoded data:
The Page only needs to run this Add-in Codeunit from the OnInit trigger:
Base64 encoding of the assembly
A little more about the Base 64 encoding.
First I have to say that an alternative to the Base64 encoding could be to place a copy of the assembly on the Dynamics NAV server and to use the DOWNLOAD command. However, that involves more setup because you have to make sure that the file is on the server, that it is the correct one, etc. The solution with the Base64 encoding gives you the opportunity to completely embed the dll into a Codeunit. In that case only the fob needs to be imported. Which is exactly the normal deployment we are used to!
But, you might ask: how do you get the Base64 encoding into this Codeunit? Well, I made a small application for that. This app reads the information of a Control Add-in assembly and creates the Add-in Codeunit.
After selecting an assembly, the information is displayed. Fill in an ID and name for the Add-in Codeunit to be created, include the ID of the Helper Codeunit and click Create.
The tool including the Helper Codeunit can be downloaded here: RTCAddInHelper NAV 2009 R2
Important 1: The zip contains the file Microsoft.Dynamics.Framework.UI.Extensibility.dll. Extract this file together with the executable to the same folder.
Important 2: This is a version for NAV 2009 R2. I will have a version for NAV 2013 available on short term.
Enjoy!
HI AJK,
when compile the codeunit “RTC Add-in Helper”, I recive the error message ‘Ambigous function call, no matching method found.’ on line:
AddInName := FORMAT(PropertyInfo.GetValue(Attribute, Null))
Is there a solution for this?
Tanks.
Hi,
Remove the Null parameter, that should do the trick.
By the way, I got this error in NAV 2013, not in NAV 2009. Are you using NAV 2013 with this solution? I’m preparing an update for NAV 2013, it should be available in one or two weeks.
Kind regards,
Arend-Jan
Hi,
Any update when the 2013 update would be ready? I’m eager to test it.
Kind regards
Thomas De Pauw
Hi Thomas,
I expect to have it ready by next week. It will include the possibility to embed dependency files, like referenced dll’s and config files.
But first I want to finish another application that I already developed: a NAV 2013 icon browser.
Kind regards,
Arend-Jan
Hi,
sorry for the delay of my answer.
I used your solution only in NAV 2009, build #33210.
On the same PC I also installed a demo version of NAV 2013.
Kind regards,
Vincenzo Piccirillo
Hello,
This addin (rich text editor)looks interesting.
Can you tell me how I could get this addin ?
Thanks.
Christophe
Hi,
When I want to check if an assembly is available the navision client crashes. I debuged a bit to see where the crash occurs. It is in the function ‘ValidateAssembly’ on the String.Format(). You can see the error report from windows here: http://pastebin.com/va39TPfQ.
The main error is:
Type: System.IndexOutOfRangeException
Message: Index was outside the bounds of the array.
I do need to mention that I’m using NAV 2013. But it seems strange that that would be the cause of this problem.
For now i just wanted to use this code to check if the add-in is available. for the actual deployment I’m waiting for the 2013 version. As I also need to distributed some config and language files.
I hope you can help
Thank in advance
Thomas
I managed to fix this problem by replacing
FOR i := 0 TO bytes.Length – 1 DO
PublicKey += String.Format(‘{0:x2}’,bytes.GetValue(i));
with:
PublicKey := LDnt_BitConverter.ToString(bytes);
PublicKey := DELCHR(PublicKey , ‘=’,’-‘);
PublicKey := LOWERCASE(PublicKey);
You will need to add a locale variable for the bitconverter and the lenght of PublicKey needs to be more then 20 (35 in my case) because of the “-” that are added by the covertor.
The version of mscorlib is 2.0.0.0 , x86
Greets
Thomas
We have starte also to develop a Add-In to Insert RTF Text in NAV to BLOB Field.
But we got some problems.
How did you fix the Problem to Print the Text in NAV2009 or is this then only possible in NAV2013?
Did you take a WPF RTF or Windows Forms.RTF?
Greets
Guido
Hi,
Good work !
Any update on the NAV 2013 version?
Regards,
Mike
Still waiting for the update on NAV 2013 version. Are there still some problems to solve?
Regards,
Seppo