Playing around with the DynamicsNAV:// protocol handler

If you have been using the Dotnet ClickOnce technology to roll out your Dynamics NAV / 365 Business Central Windows Clients, you know it have some limitations (click here to read all about the limitations).

But if you start pulling the ClickOnce technology apart, you will find that the client files are in fact present on your harddrive, but in a obscure directory – which can be hard to locate (actually you can just start the client and go to task manager. Right click the running program and select to open the directory).

What if someone could make a small program or script that would locate all installed ClickOnce Dynamics NAV / 365 Business Central Windows Client, present you with a list to choose from and the simply start the selected client with the appropriate parameters?

Maybe we can event register this small program or script as the protocol handler for the DynamicsNAV:// protocol?

Well, here is my first attempt of a PowerShell script I call NAVBCProtocolHandlerHelper.ps1 :-):

# Version: 2019-08-06

$SearchPath = "C:\Users\$($env:UserName)\AppData\Local\Apps\2.0\"

$WindowsClientFileName = "Microsoft.Dynamics.Nav.Client.exe"
$ClientUserSettingsFileName = "ClientUserSettings.config"

if(($args[0] -eq "?") -or ($args[0] -eq "-?") -or ($args[0] -eq "-h") -or ($args[0] -eq "-help")) {
  Write-Host "#######################################################################" -ForegroundColor Cyan
  Write-Host "# Microsoft Dynamics NAV/365 Business Central Protocol Handler Helper #" -ForegroundColor Cyan
  Write-Host "#######################################################################" -ForegroundColor Cyan
  Write-Host "#             Copyright 2019, Gert Lynge, www.dabbler.dk              #" -ForegroundColor Cyan
  Write-Host "#######################################################################" -ForegroundColor Cyan
  Write-Host "# This script is free to use, modify and distribute as long as these  #" -ForegroundColor Cyan
  Write-Host "# lines are kept intact. NO WARRANTY! Use at your own risk!           #" -ForegroundColor Cyan
  Write-Host "#######################################################################" -ForegroundColor Cyan
  Write-Host ""
  Write-Host "Examples:" -ForegroundColor Cyan
  Write-Host ""
  Write-Host "Install NAV/365BC Protocol Handler:" -ForegroundColor Cyan
  Write-Host "$($MyInvocation.MyCommand.Definition) -InstallProtocolHandler"
  Write-Host "Be warned: This will override any existing DynamicsNAV:// protocol handler" -ForegroundColor Red
  Write-Host ""
  Write-Host "Remove NAV/365BC Protocol Handler:" -ForegroundColor Cyan
  Write-Host "$($MyInvocation.MyCommand.Definition) -RemoveProtocolHandler"
  Write-Host "Be warned: This will remove any DynamicsNAV:// protocol handler installed" -ForegroundColor Red
  Write-Host ""
  Write-Host "Show list of NAV/365BC ClickOnce Windows Clients and let you select one to start:" -ForegroundColor Cyan
  Write-Host "$($MyInvocation.MyCommand.Definition)"
  Write-Host ""
  Write-Host "Show this help page:" -ForegroundColor Cyan
  Write-Host "$($MyInvocation.MyCommand.Definition) -help"
  exit
}
elseif(($args[0] -eq "InstallProtocolHandler") -or ($args[0] -eq "-InstallProtocolHandler")) {
  $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
  if(-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Throw "Installing the DynamicsNAV:// Protocol handler requires this script to be run as Administrator"
  }

  New-PSDrive -Name HKCR -PSProvider Registry -Root "HKEY_CLASSES_ROOT" -ErrorAction SilentlyContinue | Out-Null
  New-Item -Path "HKCR:\DynamicsNAV" -Force | Out-Null
  New-ItemProperty -Path "HKCR:\DynamicsNAV" -Name "(Default)" -Value "Dynamics NAV Protocol" -Force | Out-Null
  New-ItemProperty -Path "HKCR:\DynamicsNAV" -Name "URL Protocol" -Force | Out-Null

  New-Item -Path "HKCR:\DynamicsNAV\DefaultIcon" -Force | Out-Null
  New-ItemProperty -Path "HKCR:\DynamicsNAV\DefaultIcon" -Name "(Default)" | Out-Null

  New-Item -Path "HKCR:\DynamicsNAV\Shell" -Force | Out-Null
  New-ItemProperty -Path "HKCR:\DynamicsNAV\Shell" -Name "(Default)" | Out-Null

  New-Item -Path "HKCR:\DynamicsNAV\Shell\Open" -Force | Out-Null
  New-ItemProperty -Path "HKCR:\DynamicsNAV\Shell\Open" -Name "(Default)" | Out-Null

  New-Item -Path "HKCR:\DynamicsNAV\Shell\Open\Command" -Force | Out-Null
  New-ItemProperty -Path "HKCR:\DynamicsNAV\Shell\Open\Command" -Name "(Default)" -Value "PowerShell.exe -WindowStyle Hidden -File ""$($MyInvocation.MyCommand.Definition)"" ""%1""" | Out-Null

  Write-Host "Protocol Handler DynamicsNAV:// installed" -ForegroundColor Green
  exit
}
elseif(($args[0] -eq "RemoveProtocolHandler") -or ($args[0] -eq "-RemoveProtocolHandler")) {
  $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
  if(-not $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Throw "Removing the DynamicsNAV:// Protocol handler requires this script to be run as Administrator"
  }

  New-PSDrive -Name HKCR -PSProvider Registry -Root "HKEY_CLASSES_ROOT" -ErrorAction SilentlyContinue | Out-Null
  Remove-Item -Path "HKCR:\DYNAMICSNAV" -Recurse -Force | Out-Null

  Write-Host "Protocol Handler DynamicsNAV:// removed" -ForegroundColor Green
  exit
}


$WindowsClients = New-Object System.Data.DataTable
$WindowsClients.Columns.Add("Product","System.String") | Out-Null
$WindowsClients.Columns.Add("Server","System.String") | Out-Null
$WindowsClients.Columns.Add("Port","System.String") | Out-Null
$WindowsClients.Columns.Add("Instance","System.String") | Out-Null
$WindowsClients.Columns.Add("Tenant","System.String") | Out-Null
$WindowsClients.Columns.Add("Authentication","System.String") | Out-Null
$WindowsClients.Columns.Add("Version","System.Version") | Out-Null
$WindowsClients.Columns.Add("Path","System.String") | Out-Null

foreach($File in Get-ChildItem -Path "$SearchPath$WindowsClientFileName" -Recurse | Select-Object FullName) {
  $Path = (Split-Path -Path $File.FullName -Parent)

  if(Test-Path "$Path\$ClientUserSettingsFileName" -PathType Leaf) {
    [xml]$XmlDocument = Get-Content -Path "$Path\$ClientUserSettingsFileName"
    $ChildNodes = $XmlDocument.configuration.appSettings.ChildNodes

    $WindowsClient = $WindowsClients.NewRow()
    $WindowsClient.Path = $Path
    $WindowsClient.Version = [System.Version][System.Diagnostics.FileVersionInfo]::GetVersionInfo($File.FullName).FileVersion
    $WindowsClient.Server = ($ChildNodes | Where-Object {($_.key -eq "Server")}).value
    $WindowsClient.Port = ($ChildNodes | Where-Object {($_.key -eq "ClientServicesPort")}).value
    $WindowsClient.Instance = ($ChildNodes | Where-Object {($_.key -eq "ServerInstance")}).value
    $WindowsClient.Tenant = ($ChildNodes | Where-Object {($_.key -eq "TenantId")}).value
    $WindowsClient.Authentication = ($ChildNodes | Where-Object {($_.key -eq "ClientServicesCredentialType")}).value
    $WindowsClient.Product = ($ChildNodes | Where-Object {($_.key -eq "ProductName")}).value
    $WindowsClients.Rows.Add($WindowsClient)
  }
}
$WindowsClients = $WindowsClients | Group-Object -Property Server,ClientServicesPort,ServerInstance,TenantId | `
                  foreach { $_.Group | Sort-Object @{Expression="Version";Descending="$True"} | Select-Object -First 1 }

$Picked = $WindowsClients | Out-GridView -PassThru -Title "Select which Microsoft Dynamics NAV/365 Business Central ClickOnce Windows Client to run"

if(-not $Picked) {
  exit
}

$Command = "$($Picked.Path)\$WindowsClientFileName"
if($args[0]) {
  & "$Command" "-protocolhandler" $args[0]
}
else {
  & "$Command"
}

Please run NAVBCProtocolHandlerHelper.ps1 from a powershell CLI with the -help parameter and read the possibilities. It has five ways of running:

  1. Show the help:
    NAVBCProtocolHandlerHelper.ps1 -help
  2. Install itself as the DynamicsNAV:// protocol handler (OVERWRITING the existing one):
    NAVBCProtocolHandlerHelper.ps1 -InstallProtocolHandler
  3. Remove ANY DynamicsNAV:// protocol handler (also ones the script did not install itself):
    NAVBCProtocolHandlerHelper.ps1 -RemoveProtocolHandler
  4. Show list of installed ClickOnce Windows Clients for Dynamics NAV/365 Business Central and lets you choose one. The chosen one is started:
    NAVBCProtocolHandlerHelper.ps1
  5. Started through the DynamicsNAV:// protocol.
    A list of installed ClickOnce Windows Clients for Dynamics NAV/365 Business Central will be shown. When you chose one, it is started and the URL is passed as a parameter to it (just like if it was called directly from the protocol handler):
    DynamicsNAV://<your parameters>

This is still work in progress and can be improved in many ways. Feel free to send me your comments and wishes.

You can use and modify this free of charge as long as you keep the blocks shown in the help intact.
This is completely without any warranty of any kind – so use at your own risk!
Parameters and functionalities are subject to changes as this is work in progress.

Leave a Reply

Your email address will not be published. Required fields are marked *

* Copy This Password *

* Type Or Paste Password Here *

512 Spam Comments Blocked so far by Spam Free Wordpress