STAEDEAN Business Central Documentation

Initialize ANY

This manual only applies to the on-premises installation of ANY. Download the installation package and unzip the package. In this manual the installation of ANY APP is explained on the framework part. The installation of the ANY portal is explained in the following link: https://bcdocs.staedean.com/md/en-US/CONDYNANAV_250

To be able to install BC Anywhere for Microsoft Dynamics 365 BC, you must first take care of some installation requirements regarding the server. These are defined in the following link: https://bcdocs.staedean.com/md/en-US/CONDYNANAV_220

Note

Make sure to run the unpacking and installation process on the same machine with the same environment to prevent Windows security from blocking the executables

Using Windows Powershell for the installation

The below script can be used to execute the installation of the App in windows powershell. As mentioned in the disclaimer on the page https://bcdocs.staedean.com/md/en-US/sc_installation.md we do not provide support on this script. We expect that our partner has the knowledge on how to install an app/extension for in Microsoft Dynamics 365 BC.

# Set the variables before running the script
$serverInstance = 'BC150'
$AppsFolder = 'C:\users\<you>\desktop\NewApps'

#Optional: Create a list of the requested apps, this ensures that only the apps in the list are installed and not all the apps in the $AppsFolder
#When omitting this step, all the apps available in the directory will be installed
#Remove the # prefix from TIApps

#$TIApps = "TI-Common" #Mandatory for All TI Apps

#BIS (BIS is part of the underlayer in ANY framework)
#$TIApps += ",TI-BIS"

#ANY 
#$TIANYApps


# When running this script in a seperate session in ISE the user need to import the modules again
Import-Module "C:\Program Files\Microsoft Dynamics 365 Business Central\150\Service\Microsoft.Dynamics.Nav.Apps.Management.psd1"
Import-Module "C:\Program Files\Microsoft Dynamics 365 Business Central\150\Service\Microsoft.Dynamics.Nav.Management.psd1"




# The installation script publishes and installs the TI apps in the correct sequence
function Sort-AppFoldersByDependencies {
    Param(
        [Parameter(Mandatory=$true)]
        [string[]] $appFolders,
        [Parameter(Mandatory=$false)]
        [string] $baseFolder = "",
        [Parameter(Mandatory=$false)]
        [ref] $unknownDependencies
    )
    if ($baseFolder) {
        $baseFolder = $baseFolder.TrimEnd('\')+'\'
    }
    # Read all app.json objects, populate $apps
    $apps = $()
    $folders = @{}
    $appFolders | ForEach-Object {
        $appFolder = "$baseFolder$_"
        $appJsonFile = Join-Path $appFolder "app.json"
        if (-not (Test-Path -Path $appJsonFile)) {
            Write-Warning "$appFolder doesn't contain app.json"
        }
        else {
            $appJson = Get-Content -Path $appJsonFile | ConvertFrom-Json
            $alreadyAdded = $apps | Where-Object { $_.Id -eq $appJson.Id }
            if (-not ($alreadyAdded)) {
                $folders += @{ "$($appJson.Id)" = $appFolder }
                $apps += @($appJson)
            }
        }
    }
    # Populate SortedApps and UnresolvedDependencies
    $script:sortedApps = @()
    $script:unresolvedDependencies = $()

    function AddAnApp { Param($anApp)
        $alreadyAdded = $script:sortedApps | Where-Object { $_.Id -eq $anApp.Id }
        if (-not ($alreadyAdded)) {
            AddDependencies -anApp $anApp
            $script:sortedApps += $anApp
        }
    }
    function AddDependency { Param($dependency)
        $dependentApp = $apps | Where-Object { $_.Id -eq $dependency.AppId }
        if ($dependentApp) {
            AddAnApp -AnApp $dependentApp
        }
        else {
            if (-not ($script:unresolvedDependencies | Where-Object { $_ -and $_.AppId -eq $dependency.AppId })) {
                Write-Warning "Dependency $($dependency.appId):$($dependency.publisher.Replace('/',''))_$($dependency.name.Replace('/',''))_$($dependency.version)).app not found"
                $script:unresolvedDependencies += @($dependency)
            }
        }
    }
    function AddDependencies { Param($anApp)
        if (($anApp) -and ($anApp.Dependencies)) {
            $anApp.Dependencies | ForEach-Object { AddDependency -Dependency $_ }
        }
    }
    $apps | ForEach-Object { AddAnApp -AnApp $_ }
    $script:sortedApps | ForEach-Object {
        ($folders[$_.id]).SubString($baseFolder.Length)
    }
    if ($unknownDependencies) {
        $unknownDependencies.value = @($script:unresolvedDependencies | ForEach-Object { if ($_) { "$($_.appId):$($_.publisher.Replace('/',''))_$($_.name.Replace('/',''))_$($_.version).app" } })
    }
}
function GetAppFolders {
    Param(
        [Parameter(Mandatory = $true)]
        [string]$baseFolder,
        [Parameter(Mandatory = $false)]
        [string]$apps
    )
    $appFolders = ''
    $AllAppJsonFiles = Get-ChildItem -Path $baseFolder -Filter "app.json" -Recurse
    foreach ($AllAppJsonFile in $AllAppJsonFiles) {
        $a = Get-Content $AllAppJsonFile.fullname | ConvertFrom-Json
        if (($apps.Split(',') -contains ($a | Select-Object -expand name)) -or ($apps -eq '')) {
            Set-Location $baseFolder
            $relativePath = Get-Item $AllAppJsonFile.PSParentPath | Resolve-Path -Relative
            if ($appFolders) {
                $appFolders = $appFolders + ',' + $relativePath.Substring(2)
            }
            else {
                $appFolders = $relativePath.Substring(2)
            }
        }
    }
    return $appFolders.Replace('\', '/')
}
$appFolders = GetAppFolders -baseFolder $AppsFolder -apps $TIApps
$appFolders
Sort-AppFoldersByDependencies -appFolders $appFolders.Split(',') -baseFolder $buildArtifactFolder -WarningAction SilentlyContinue | ForEach-Object {
    Write-Host "Publishing $_"
    Get-ChildItem -Path (Join-Path $AppsFolder $_) -Filter "*.app" | ForEach-Object {
        Publish-NAVApp -Path $_.FullName -ServerInstance $serverInstance
        $name = (Get-Content (Join-Path (Split-Path $_.FullName) ('app.json')) | ConvertFrom-Json | Select-Object -expand name)
        $version = (Get-Content (Join-Path (Split-Path $_.FullName) ('app.json')) | ConvertFrom-Json | Select-Object -expand version)
        Sync-NAVApp -Name $name -ServerInstance $serverInstance -Version $version
        Install-NAVApp -Name $name -ServerInstance $serverInstance -Version $version
    }
}

End of script

Note

Register Codeunit 11158646 (ANY function list 2) for ANYHWERE. Register Codeunit 11070243 (BIS function list 2) for BIS.