Page 40 - MSDN Magazine, June 2019
P. 40

Figure 7 A Release Pipeline Task That Modifies the Uris in the .appinstaller File
- powershell: | [Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq")
$fileShare = "\\filesharestorageccount.file.core.windows.net\myfileshare\" $localFilePath =
"$(System.DefaultWorkingDirectory)\_MsixDesktopApp\drop\MsixDesktopApp. appinstaller"
$doc = [System.Xml.Linq.XDocument]::Load("$localFilePath") $doc.Root.Attribute("Uri").Value = [string]::Format('{0}{1}', $fileShare,
'MsixDesktopApp.appinstaller') $xName =
[System.Xml.Linq.XName]"{http://schemas.microsoft.com/appx/ appinstaller/2018}MainPackage"
$doc.Root.Element($xName).Attribute("Uri").Value = [string]::Format('{0}{1}', $fileShare, 'MsixDesktopApp.appx')
$doc.Save("$localFilePath")
displayName: 'Modify URIs in App Installer File'
You’d then distribute the .appinstaller file to your end users and let them double-click on this one instead of the .msix file to install the packaged app.
Continuous Deployment
The app installer file itself is an uncompiled XML file that can be edited after the build, if required. This makes it easy to use when you deploy your software to multiple environments and when you want to separate the build pipeline from the release process.
If you create a release pipeline in the Azure Portal using the “Empty job” template and use the recently set up build pipeline as the source of the artifact to be deployed, as shown in Figure 6, you can then add the PowerShell task in Figure 7 to the release stage in order to dynamically change the values of the two Uri attributes in the .appinstaller file to reflect the location to which the app is published.
In the task in Figure 7, the URI is set to the UNC path of an Azure file share. Because this is where the OS will look for the MSIX package when you install and update the app, I’ve also added another com- mand-line script to the release pipeline that first maps the file share in the cloud to the local Z:\ drive on the build agent before it uses the xcopy command to copy the .appinstaller and .msix files there:
- script: |
net use Z: \\filesharestorageccount.file.core.windows.net\myfileshare
/u:AZURE\filesharestorageccount 3PTYC+ociHIwNgCnyg7zsWoKBxRmkEc4Aew4FMzbpUl/ dydo/3HVnl71XPe0uWxQcLddEUuq0fN8Ltcpc0LYeg==
xcopy $(System.DefaultWorkingDirectory)\_MsixDesktopApp\drop Z:\ /Y displayName: 'Publish App Installer File and MSIX package'
If you host your own on-premises Azure DevOps Server, you may of course publish the files to your own internal network share. Web Installs If you choose to publish to a Web server, you can tell MSBuild to generate a versioned .appinstaller file and an HTML page that contains a download link and some information about the pack-
aged app by supplying a few additional arguments in the YAML file:
- task: MSBuild@1 inputs:
solution: Msix/Msix.wapproj
platform: $(buildPlatform)
configuration: $(buildConfiguration) msbuildArguments: '/p:OutputPath=NonPackagedApp
/p:UapAppxPackageBuildMode=SideLoadOnly /p:AppxBundle=Never /p:GenerateAppInstallerFile=True /p:AppInstallerUri=http://yourwebsite.com/packages/ /p:AppInstallerCheckForUpdateFrequency=OnApplicationRun /p:AppInstallerUpdateFrequency=1 /p:AppxPackageDir=$(Build.ArtifactStagingDirectory)/'
displayName: 'Package the App'
Figure 8 The Build Artifacts Explorer in the Azure DevOps Portal
Figure 8 shows the contents of the staging directory on the build agent after running the previous command. It’s the same output you get from the wizard in Visual Studio if you choose to create packages for sideloading and check the “Enable automatic updates” checkbox. Using this approach, you can remove the manually created .appinstaller file at the possible expense of some flexibility regarding the configuration of the update behavior.
The generated HTML file includes a hyperlink prefixed with the browser-agnostic ms-appinstaller protocol activation scheme:
<a href="ms-appinstaller:?source= http://yourwebsite.com/packages/Msix_x86.appinstaller ">Install App</a>
If you set up a release pipeline that publishes the contents of the drop folder to your intranet or any other Web site, and the Web server supports byte-range requests and is configured properly, your end users can use this link to directly install the app without downloading the MSIX package first.
Wrapping Up
In this article you’ve seen how easy it is to package a .NET desk- top application as an MSIX using Visual Studio. You also saw how to set up CI and CD pipelines in Azure Pipelines and how to configure automatic updates. MSIX is the modern way to deploy applications on Windows. It’s built to be safe, secure and reliable, and lets you and your customers take advantage of the new app model and the modern APIs that have been introduced in Windows 10, regardless of whether you intend to upload your apps to the Microsoft Store or sideload them onto computers in your enterprise. As long as all of your users have moved to Windows 10, you should be able to leverage MSIX to package most Windows desktop apps that exist out there. n
Magnus Montin is a Microsoft MVP who works as a self-employed software developer and consultant in Stockholm, Sweden. He specializes in .NET and the Microsoft stack and has over a decade of hands-on experience. You can read his blog at blog.magnusmontin.net.
thanks to the following Microsoft technical expert for reviewing this article: Matteo Pagani
36 msdn magazine
DevOps


































































































   38   39   40   41   42