Install App installer and WinUI BLM on Windows 10 LTSC

To install WinUI packages on Windows 10 LTCS, Winget App Installer and the Berryworld Software certificate need to be installed. 

Error when you don’t have App Installer: 

“Windows can’t open this type of file .msix” 

To install the WinGet App Installer 

Complete internet document used (for reference):

[Guide] How to install Winget on LTSC (IoT) without the Windows Store 

My motivation for writing this is because I’ve spent many hours troubleshooting errors that came with installing Winget due to Microsoft’s lack of instructions for their own Enterprise distributions. I built this step-by-step guide by digging through GitHub Issues and the excellent MyDigitalLife forums. 

Make sure to refer to the GitHub repo for an updated guide! I won’t be maintaining this post. 

⚠ Manual installation does not receive auto updates, but is the only option without installing Windows Store on LTSC ⚠ 

Installing Dependencies 

  • Open an elevated (administrator) PowerShell prompt and keep it open throughout this guide. 

VC++ v14 Desktop Framework Package 

  1. Download the correct VC++ v14 Desktop Framework Package for your architecture. 
  1. Install with: Add-AppxPackage -Path “PATH TO FILE” 

Microsoft.UI.Xaml.2.7 

Winget v1.2.10271 introduced a new dependency for Microsoft.UI.Xaml.2.7 which you have to install manually. The solution to install this on LTSC is not pretty, but it works. 

  1. Download the Nuget package manually by clicking “Download package” on the right hand side under the “About” section. 
  1. Change the file extension from .nuget to .zip and open it with any archiving program. 
  1. Within the archive navigate to tools\AppX\[YOUR ARCHITECTURE]\Release and extract Microsoft.UI.XAML.2.7.appx. 
  1. Install with: Add-AppxPackage -Path “PATH TO FILE” 

#1861 

Installing Winget 

0. Make sure all dependencies are installed before doing this! 

  1. From the latest release download the .msixbundle install- and .xml license file: https://github.com/microsoft/winget-cli/releases 
  1. Install with: Add-AppxProvisionedPackage -Online -PackagePath “PATH TO MSIXBUNDLE” -LicensePath “PATH TO XML” -Verbose 
  1. Wait for the install to finish and you’re done. You may need to restart the terminal, or reboot your pc. 
  1. Verify that the installation succeeded by running winget in PowerShell. If no errors occur then you’re done! 

Make sure to refer to the GitHub repo for an updated guide! I won’t be maintaining this post. 

Create a certificate for package signing AND deploy a MSIX package

I wanted my application to be available via a MSIX installer. This new MSIX installer supports all type of Windows applications including Win32, WPF, WinForm and UWP.

I struggled a few days to get the certificate right so that is why I published this article. This article goes through the process of creating a certificate and adding this to the app installer package.

First you need to add a new project to your solution. The solution type is called Windows Application Packaging Project. This is done by right clicking the solution and go to Add > New Project…

Determine the subject of your packaged app
To use a certificate to sign your app package, the “Subject” in the certificate must match the “Publisher” section in your app’s manifest.

For example, the “Identity” section in your app’s AppxManifest.xml file should look something like this:

<Identity
    Name="12345678-1234-1234-1234-1234567890ab"
    Publisher="CN=Contoso Software, O=Contoso Corporation, C=US"
    Version="1.0.2.0" />

The “Publisher”, in this case, is “CN=Contoso Software, O=Contoso Corporation, C=US” which needs to be used for creating your certificate.

Then run the following commands in an elevated PowerShell prompt:

  1. PS C:\WINDOWS\system32> New-SelfSignedCertificate -Type Custom -Subject “CN=Contoso Software, O=Contoso Corporation, C=US” -KeyUsage DigitalSignature -FriendlyName “Certificate for Installing MSIX/Appx from Contoso Software” -CertStoreLocation “Cert:\CurrentUser\My” -TextExtension @(“2.5.29.37={text}1.3.6.1.5.5.7.3.3”, “2.5.29.19={text}”)

    PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

    Thumbprint Subject
    ———- ——-
    2B046FBC587DD867989D6165570B4C144F557FCE CN=Contoso Software, O=Contoso Corporation, C=US
  2. PS C:\WINDOWS\system32>Set-Location Cert:\CurrentUser\My
  3. PS Cert:\CurrentUser\My> $password = ConvertTo-SecureString -String mypassword -Force -AsPlainText
  4. PS Cert:\CurrentUser\My> Export-PfxCertificate -cert “2B046FBC587DD867989D6165570B4C144F557FCE” -FilePath c:\Contoso.Software.pfx -Password $password

    Directory: C:\

    Mode LastWriteTime Length Name
    —- ————- —— —-
    -a—- 7-9-2020 08:42 2756 Contoso.Software.pfx

Then add the certificate to the package installer in Visual Studio:

Next publish the app:

Import the certificate if it is not already installed

Start Manage computer certificates to import the certificate to the computer(s) to which you wish the app to deploy

If it is not present in Thrusted People, import the certificate

Next publish the app

And double click the PackagingProject.appinstaller from the installer folder

Registering / installing a Windows service part 2

In this article I want to describe an easy way to add an easy installer to a Windows Service project.

Steps are: – Add the installer for the service
– Configure the service parameters
– Add parameters to start up of the program


Add the installer for the service can be done when you open the service.cs. This will show a gray screen with two links:

Right click this screen and select Add installer in the pop up menu. This will add a ProjectInstaller.cs file with a ProjectInstaller class inside.

Open the Projectinstaller file. This will show two components.

Change settings for the two components according to your needs.

Last step is to add the installer to the program start up. For this we need to change the Program.cs.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            //Install service
            if (args[0].Trim().ToLower() == "/i")
            {
                System.Configuration.Install.ManagedInstallerClass.InstallHelper(
        new string[] { "/i", Assembly.GetExecutingAssembly().Location });
            }

            //Uninstall service                 
            else if (args[0].Trim().ToLower() == "/u")
            {
                System.Configuration.Install.ManagedInstallerClass.InstallHelper(
        new string[] { "/u", Assembly.GetExecutingAssembly().Location });
            }
        }
        else
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
            new ServiceMonitor()
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
}