Meet the compiler’s little friend ALTOOL.EXE

With Business Central 2024 Wave 1, the compiler has gained a sidekick. In this video, I take a look at the new addition, check it out:

https://youtu.be/a-yqAB5r16w

With Business Central version 24 (2024 wave 1), we received AL compiler version 13 — and with it came a new companion tool. The compiler has always been the superhero of AL development, but now it has a proper sidekick: ALTool.exe. In this post, we’ll explore what ALTool.exe is, where to find it, and what it can do for you.

Where Is the Compiler (and Its Sidekick)?

Before we can find the sidekick, we need to find the compiler itself. Visual Studio Code doesn’t install extensions in a global system location — instead, it places them under the current user’s profile. On Windows, the path looks like this:

C:\Users\{YourUsername}\.vscode\extensions\

Inside that extensions folder, you’ll see all the extensions installed on your machine. The AL Language extension lives in a folder named something like:

ms-dynamics-smb.al-13.0.{build}

The 13 here corresponds to compiler version 13, which ships with BC version 24. Inside that folder, you’ll find a bin directory with subdirectories for Windows, Mac, and Linux. Navigating into the Windows folder reveals a collection of DLLs and a few executables.

The Five Executables

There are five executable files in the compiler’s bin\win32 directory:

  • alc.exe — The AL compiler itself
  • aldoc.exe — The documentation generation tool (there’s a separate video on the channel covering this one)
  • ALTool.exe — The new sidekick
  • And a couple of other supporting executables

An interesting side note: all three main executables (alc.exe, aldoc.exe, and ALTool.exe) are roughly the same size — about 151,000 bytes each. That doesn’t mean they have equal functionality; the exe files are essentially just entry points (bootloaders). The real functionality lives in their corresponding DLL files.

Under the Hood: ALTool’s Dependencies

If you peek at ALTool’s runtime configuration file (ALTool.runtimeconfig.json), you’ll see it runs on .NET 8.0. The .deps.json file reveals its dependencies, which include:

  • Command line parsing libraries
  • AL Nav Code Analysis
  • System.Text.Json
  • System.Diagnostics.FileVersionInfo
  • .NET Core runtime libraries

This makes sense — the tool needs to parse command-line arguments, read AL app packages, and work with JSON manifests.

ALTool’s Three Commands

Running ALTool.exe without any arguments (or with the help verb) shows us five options, including version and help, plus three functional commands:

1. GetPackageManifest

This command extracts the manifest from an .app file. Note that the command is case-sensitive:

ALTool.exe GetPackageManifest "C:\path\to\your\app.app"

You pass it the path to any .app file and it returns the manifest content. This is particularly useful because it also works on runtime packages — so even if you receive a runtime app from someone, you can extract its manifest, including details like telemetry keys and other metadata.

For context, here’s what a typical app.json manifest looks like in a project:

{
  "id": "f02b9892-4c88-4903-bc7a-bfc4dea694e1",
  "name": "Video10",
  "publisher": "Default publisher",
  "version": "1.0.0.0",
  "brief": "",
  "description": "",
  "privacyStatement": "",
  "EULA": "",
  "help": "",
  "url": "",
  "logo": "",
  "dependencies": [
    {
      "id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
      "publisher": "Microsoft",
      "name": "System Application",
      "version": "16.0.0.0"
    },
    {
      "id": "437dbf0e-84ff-417a-965d-ed2bb9650972",
      "publisher": "Microsoft",
      "name": "Base Application",
      "version": "16.0.0.0"
    }
  ],
  "screenshots": [],
  "platform": "16.0.0.0",
  "idRanges": [
    {
      "from": 50100,
      "to": 50149
    }
  ],
  "contextSensitiveHelpUrl": "https://Video10.com/help/",
  "showMyCode": true,
  "runtime": "5.0"
}

The GetPackageManifest command extracts this kind of information directly from a compiled .app file — no need to have the source project on hand.

2. CreateSimplePackage

This command converts an app file into a simplified package:

ALTool.exe CreateSimplePackage "C:\path\to\input.app" "C:\path\to\output.app"

It requires two arguments: the path to the input app file and the path for the output. The resulting simplified package, when opened with a tool like 7-Zip, contains only a manifest and symbols.json — nothing else. Essentially, it strips away the actual code and produces a minimal symbols-only package.

3. GetLatestSupportedRuntimeVersion

This command maps a Business Central platform version number to the corresponding runtime version:

ALTool.exe GetLatestSupportedRuntimeVersion 24.0
# Returns: 13.0

ALTool.exe GetLatestSupportedRuntimeVersion 15.0
# Returns: 4.0

If you’ve ever struggled with the BC version number arithmetic, this is the tool for you. The general rule has been to subtract 11 from the BC version to get the compiler/runtime version (e.g., BC 24 minus 11 equals compiler 13, BC 17 minus 11 equals compiler 6, and NAV/BC 18 minus 18 is version 0). But rather than doing mental math, you can now just ask ALTool directly.

Note that it doesn’t support very old versions — asking for platform versions below 15.0 returns “unknown.”

Why Does ALTool.exe Exist?

The backstory is straightforward. While Microsoft was working on the AL compiler on GitHub, they migrated from .NET Framework to .NET Core. During this transition, certain utility functions needed to be recreated, and they needed a sensible place to put them. Rather than bloating the compiler itself with peripheral tasks, they created ALTool as a dedicated sidekick for these ancillary operations.

Think of it like any good superhero story: you don’t send the main hero to fetch coffee. You delegate the supporting tasks to the sidekick.

A Note on File Locations

One slightly annoying aspect of ALTool (and the compiler executables in general) is that they change location every time the VS Code extension updates. Since extensions are installed in version-specific folders, every update creates a new folder path. This makes it difficult to reference these tools from scripts or CI/CD pipelines in a stable way.

A practical suggestion would be to create a symbolic link or file shortcut to the current version’s location, giving consumers a static path that doesn’t change with every extension update. This would be especially helpful for automated build processes that need to call these tools directly.

Example AL Code for Context

For reference, the demo project used in the video included a simple page extension and a table definition — the kind of typical AL objects you’d find in any BC extension:

pageextension 50100 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage();
    begin
        Message('App published: Hello world');
    end;
}
table 50100 "Awesome AZ demo"
{
    Caption = 'Awesome AZ demo';
    DataClassification = ToBeClassified;
    
    fields
    {
        field(1; "Key Field"; Code[20])
        {
            Caption = 'Key Field';
            DataClassification = SystemMetadata;
        }
        field(10; Name; Text[100])
        {
            Caption = 'Name';
            DataClassification = SystemMetadata;
        }
    }
    keys
    {
        key(PK; "Key Field")
        {
            Clustered = true;
        }
    }
}

Once compiled into an .app file, these are the kind of packages you can feed into ALTool’s GetPackageManifest and CreateSimplePackage commands.

Summary

ALTool.exe is a lightweight but useful companion to the AL compiler, introduced with compiler version 13 (BC 24). It currently provides three commands:

  1. GetPackageManifest — Extract manifest information from any .app file, including runtime packages
  2. CreateSimplePackage — Strip an app file down to just its manifest and symbols
  3. GetLatestSupportedRuntimeVersion — Map platform versions to runtime versions without mental arithmetic

This is likely just the beginning. As Microsoft continues to develop the AL toolchain, expect more utility functions to land in ALTool.exe — keeping the compiler lean while giving developers useful ancillary capabilities through its trusty sidekick.