On-Premise Extensions & Customer Licenses

On my task list for one of my customers was a nicely isolated module that I could make into an extension.

I’m a huge fan of making many small extensions rather than trying to put all of one customers modifications in one project.

In this case it is a side-by-side project with C/Side so I have created my own app file for the packages. I’ll see if I can blog somewhat about that later.

Extensions are not just for AppSource

Some people seem to think that on-premise we can just as well continue to use C/Side and even though I am a huge C/Side fan I have to disagree.

On-Premise extensions have a lot of value, especially because extensions enforce discipline.

The Caveat

The biggest challenge that I face when programming bespoke Extensions On-Premise is the deployment. Microsoft has made the testing of the license very strickt. In fact, it is more strickt than the runtime check which in my opinion is a bug. Microsoft however has a different opinion. Business Central in fall with the new license model solves it because then, there is no more license.

Temporary Tables

Everyone who has attended my Programming Master Class (800 of you) knows that using Temporary Tables as containers of code are one of the most powerful assets for clean code and reducing code cloning.

The Table behaves as a class with methods and properties and actually replaces the need for Code Units completely. Well, almost.

Using these tables in C/Side is free. It has always been free. End Users only have to pay for tables in their licenses if they write data to the database.

When you ship an extension with a table object that is outside of the customers license you’ll get an error message. The publishing process does not check your code for actual inserts and it probably could not even do that if they wanted to.

In C/Side end-users can import objects with a fob file that are outside of their license.

PowerShell to the Rescue

I’ve created a small PowerShell script that temporarily changes the license at the End-User and later switches it back. There is a lot of clean up to do but for me it was a huge time saver.

My plan is to somehow make this PowerShell script run directly from Visual Studio Code and launch the Windows Client instead of the Web Client.

Please not that I don’t dislike the Web Client but we have some pages in our solution that not yet render perfectly and have to be replaced first with another solution (probably Angular w. DevExpress).

Here is the script.

Don’t expect rocket science. I try to keep my PowerShell understandable.

Set-ExecutionPolicy unrestricted

import-module "C:\Program Files (x86)\Microsoft Dynamics NAV\110\RoleTailored Client\NavModelTools.ps1"
import-module "C:\Program Files\Microsoft Dynamics NAV\110\Service\NavAdminTool.ps1"

$ServiceTier = "2018DEV"
$Version = ""
$xVersion = ""
$AppFolder = "\\DynamicsNAV\Extensions\Performance\Version\"
$AppSource = "\\DynamicsNAV\Extensions\Performance\Source\"
$AppFile = "Mark Brummel_Performance_" + $Version + ".app"
$AppName = "Performance"

#Get-NAVAppInfo -ServerInstance $ServiceTier

Move-Item -Path $AppSource$AppFile -Destination $AppFolder$AppFile -Force -ErrorAction Ignore

Import-NAVServerLicense -LicenseFile "\\License\Development.flf" -ServerInstance $ServiceTier
Restart-NAVServerInstance -ServerInstance $ServiceTier

Uninstall-NAVApp -ServerInstance $ServiceTier -Name $AppName -Version $xVersion
Unpublish-NAVApp -ServerInstance $ServiceTier -Name $AppName
Publish-NAVApp -ServerInstance $ServiceTier -Path "$AppFolder$AppFile" -SkipVerification
Install-NAVApp -ServerInstance $ServiceTier -Name $AppName -Version $Version

Import-NAVServerLicense -LicenseFile "\\License\Customer.flf" -ServerInstance $ServiceTier
Restart-NAVServerInstance -ServerInstance $ServiceTier

#Sync-NAVApp -ServerInstance $ServiceTier -Name $AppName -Mode Clean -Force
#Sync-NAVApp -ServerInstance $ServiceTier -Name $AppName -Mode Add

The bottom two commands are commented out. I use them when I make schema changes to avoid having to create upgrade codeunits during the development process.

The Version and xVersion are because I like to keep some old versions of the .app file while I do the development. The UnInstall and UnPublish is not required if you increase the build number with each build

A tip to Microsoft would be to implement some of the old C/Side code into the Extensions module that only deleted data/colums for those tables/columns that were really changed.

Comment List