Part 4: Create a Jenkins pipeline to deploy Desktop Apps as MSIX: Packaging with VB6RegistryTool

Published Feb 14 2022 06:39 AM 2,761 Views
Microsoft

 

In this forth part, it is described how to setup Jenkins pipeline to package a Java GUI application to MSIX through the VB6RegistryTool.

 

Despite of the tool name, VB6RegistryTool can be used to package any kind of Desktop application.

 

Parts:

  1. Setup the Jenkins environment: install Jenkins and the required tools.
  2. Packaging a Visual Studio solution: for applications that use Visual Studio IDE, like Windows Forms and WPF.
  3. Packaging a solution developed outside Visual Studio: for applications developed outside VS, i.e., in others IDEs like Eclipse or Visual Studio Code, for Java GUI application.
  4. Packaging using the VB6RegistryTool: despite of the name, the tool can be used by any technology.

 

Setup environment

 

Install VB6RegistryTool

The post How MSIX is great for simplify deployment for Visual Basic 6.0 applications explains how to download and use the VB6RegistryTool.

 

As I don't have Microsoft Store enabled on my Windows Server 2019 Jenkins server, I will download and install the tool from GitHub:

 

p4vb601.png

 

 

Download the zip file:

 

p4vb602.png

 

 

Extract it to C:\Program Files (x86)\VB6VirtualRegistry:

 

p4vb603.png

 

 

Add the VB6VirtualRegistry to the PATH environment:

 

p4vb605.png

 

 

Open a command prompt, navigate to the VB6VirtualRegistry folder, and run vb6virtualregistry.exe to make sure that the app is working:

 

p4vb604.png

 

 

 

Create the MSIX project structure

To package this project to MSIX, it will be necessary to create a folder with the following structure:

 

p4msix01.png

 

 

The Assets folder contains the application images like default tile and logo images. You can easily generate the images for you application through the PWA Builder Image Generator.

 

Navigate to the PWA Builder Image Generator page, click on Choose File and select a picture of your preference that will be used to show the application icons on start menu:

 

p4msix02.png

 

 

Scroll-down to the Platforms section, keep selected only Windows operating system and click Generate:

 

p4msix03.png

 

 

The images outcome will be generated in a zip file. Download the zip file and extract the images inside your Assets folder:

 

p4msix04.png

 

 

The next step is to add our Java Desktop application to our package folder VFS\ProgramFilesX86\MyApp.

 

The post Create a Jenkins pipeline to deploy MSIX Desktop Apps - Part 3: Packaging solutions outside VS explains how the Java GUI application was developed.

The Java GUI executable file is available on GitHub.

Actually, the application and its dependencies can be published in any folder inside the package. But for demonstration purpose, I am using *VFS\ProgramFilesX86* to explain that it is possible to use the special folder called VFS, acronym for Virtual File System, that contains the corresponding folders for the Windows' well-known folders (System32 - SystemX86, Program Files - ProgramFilesX64, Program Files (x86) - ProgramFilesX86, etc). This is great for applications that expects files in the original path outside the package.

 

Add the myapp.exe to the following folder structure:

 

p4msix05.png

 

 

The last file available in the application package folder is the AppxManifest.xml that is the application manifest that contains the elements and attributes that the MSIX application needs.

 

Here is the application manifest content:

 

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" 
         xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" 
         xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" 
         xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" 
         xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" 
         IgnorableNamespaces="uap uap10 rescap com">
 
  <Identity Name="MyJavaGUI" Publisher="CN=Vb6VirtualRegistry" Version="1.0.0.0" ProcessorArchitecture="x86" />
  
  <Properties>
    <DisplayName>My Java GUI</DisplayName>
    <PublisherDisplayName>AppConsult</PublisherDisplayName>
    <Description>My Java GUI</Description>
    <Logo>Assets\StoreLogo.png</Logo>
    <uap10:PackageIntegrity>
      <uap10:Content Enforcement="on" />
    </uap10:PackageIntegrity>
  </Properties>
  
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.1" />
  </Dependencies>
  <Applications>

    <Application Id="App" Executable="VFS\ProgramFilesX86\MyApp\myapp.exe" 
                          EntryPoint="Windows.FullTrustApplication">
        
      <uap:VisualElements BackgroundColor="transparent" DisplayName="VB6 Sample" 
                          Square150x150Logo="Assets\VBSix-Square150x150Logo.png" 
                          Square44x44Logo="Assets\VBSix-Square44x44Logo.png"
                          Description="VB6 Sample">
          
        <uap:DefaultTile  Wide310x150Logo="Assets\VBSix-Wide310x150Logo.png" 
                          Square310x310Logo="Assets\VBSix-Square310x310Logo.png" 
                          Square71x71Logo="Assets\VBSix-Square71x71Logo.png"/>
      </uap:VisualElements>
      
    </Application>
     </Applications>
  
<Capabilities>
  <rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

 

You can find more details about the package manifest at How to create a basic package manifest for Windows 8.

 

 

Packaging the folder using VB6VirtualRegistry

Now that we have all the files needed (application manifest file, assets, and applications files ), we can use the following command to package the entire folder to MSIX:

 

p4run01.png

 

 

Notice that the MSIX file was successfully created:

 

p4run02.png

 

 

The next step is to create the Jenkins pipeline.

 

2. Jenkins Pipeline

Pipeline is a series of tasks required to build, test, and deploy an application.

Create a new job

In the Jenkins Dashboard, click on the New Item option:

 

p3pipeline01.png

 

 

Provide the name Manual MSIX Packaging for the job, select the Pipeline type of job and click on OK to proceed.

 

p4pipeline01.png

 

 

In the pipeline configuration page, check the GitHub Project to specify that this is a GitHub project and provide a GitHub URL:

 

p2pipeline03.png

 

 

Scroll down under the Pipeline section and change the definition to Pipeline script from SCM:

 

p2pipeline04.png

 

 

Provide the Repository URL as well. Because this is a public project, we can skip the credentials:

 

p2pipeline05.png

 

 

Scroll-down to the Branches to build section, change the branch name to */main, the Jenkins script path to Jenkinsfile03 and click on Save:

 

p4pipeline02.png

 

 

Those actions were needed as we want to use the Jenkins pipeline file available in the main branch of the following repo:

 

p4pipeline03.png

 

 

 

Jenkins Pipeline File

In the previous section it was demonstrated how to setup the Jenkins pipeline to use a Jenkins script file available on our GitHub repository.

Follows the Jenkinsfile03 content:

 

pipeline {
  
  agent any

  tools {
        maven "Maven 3.8"
        jdk "JDK 11"
  }
 
  stages {
      stage('Initialize'){
            steps{
              
              echo "PATH = ${M2_HOME}\\bin:${PATH}"
              echo "M2_HOME = C:\\Program Files (x86)\\apache-maven"
                
            }
      }
      stage('Build') {
            steps {
                dir("\\03_VB6RegistryTool\\demo") {
                bat 'mvn clean package'
                }
            }
            post{
              always {
                bat 'copy 03_VB6RegistryTool\\demo\\target\\myapp.exe 03_VB6RegistryTool\\msix_files\\VFS\\ProgramFilesX86\\MyApp /y'
              }
            }
      }
      stage('Update manifest version') {
            steps {
                  powershell '''
                    $manifest = "03_VB6RegistryTool\\msix_files\\appxmanifest.xml"     
                    [xml]$xmlDoc = Get-Content $manifest
                    $version = $xmlDoc.Package.Identity.Version
                    $trimmedVersion = $version -replace '.[0-9]+$', '.'
                    $xmlDoc.Package.Identity.Version = $trimmedVersion + ${env:BUILD_NUMBER}
                    $xmlDoc.Save($manifest)
                  '''
            }
      }
      stage('Build MSIX package') {
        steps {
                  bat '''
                    "C:\\Program Files (x86)\\VB6VirtualRegistry\\Vb6VirtualRegistry.exe" %-- pack "C:\\Users\\luisdem\\AppData\\Local\\Jenkins\\.jenkins\\workspace\\Manual MSIX Packaging\\03_VB6RegistryTool\\msix_files" "C:\\Users\\luisdem\\AppData\\Local\\Jenkins\\.jenkins\\workspace\\Manual MSIX Packaging\\03_VB6RegistryTool\\myjava_%BUILD_NUMBER%.msix"
                    '''
            }
            post{
                  always {
                    archiveArtifacts artifacts: '**/*.msix', followSymlinks: false
                   }
            }
      }
  }
}

 

For now, the VB6RegistryTool is not recognizing the relative path for the params. That is why I set the full path in the packaging step. I will work in a fix for it.

 

The pipeline directive is the complete script from beginning to end.

 

The agent directive instructs Jenkins to allocate an executor and workspace for the entire Pipeline. In our case, we are justing saying it can run on any agent. For example, it could be specified that it could run in a Docker container or run on a specific node.

 

The environment directive specifies a sequence of key-value pairs which will be defined as environment variables for all steps, or stage-specific steps, depending on where the environment directive is located within the Pipeline.

 

In our case, it is defined the variables MSBUILD that contains the MSBUILD path, the CONFIG with the value Release and PLATFORM with the value x86. Those variables will be used in the command line used to build our application.

 

The stages block contains on or more stage block, and each stage is going to have one or more steps. In our case, we have two stages that are used to build the Java application and later to package to MSIX.

 

The post section defines the additional step needed to keep the msix file artifact available in our build, as workspace is a temporary directory.

 

You can find more details about the Jenkins pipeline syntax in the post Getting started with Pipeline.

 

Click on Build Now to start the build:

 

p4pipeline04.png

 

 

The job starts by checking out the source code to next restore and build our solution as defined in the Jenkinsfile03.

 

p4pipeline05.png

 

 

After the build is done, the build icon will be green and the msix artifact will be available:

 

p4pipeline06.png

 

 

 

Co-Authors
Version history
Last update:
‎Feb 14 2022 06:42 AM
Updated by: