If you follow my activities, like the articles I publish on this blog orthe recent book I've published about MSIX, you'll know that one of the reasons why I like MSIX from a developer perspective is that it makes really easy to enable a CI/CD pipeline for Windows desktop applications. Thanks tothe Windows Application Packaging Project, we can easily automate the creation of a MSIX package simply by adding it to our solution and running a build. And thanks to features likeApp Installer, we can easily deploy the generated MSIX package to a website and support automatic updates without changing the code or having to setup your own service.
However, in many cases you may already have an installer definition created with a 3rd party tool. Popular authoring tools, likeAdvanced Installer,InstallShieldorWix, are able to generate a MSIX package out from an installer project, making easier to reuse the work you may already have done to generate MSI installers in the past. Additionally, thanks to these tools, you have the opportunity to use the same project to generate at the same time a MSI and a MSIX, helping you to support customers who might not have migrated yet to Windows 10 and who are unable to useMSIX Core(for example, because it's a consumer application).
What about enabling a CI/CD pipeline in this scenario? In this blog post we're going to see an example on how to achieve this task with Advanced Installer. Why did I choose this product? Well, other than because it's a really good software, the Advanced Installer team has created a task for Azure DevOps which is able to build an Advanced Installer project stored on the repository. And, most of all, the task is able to download the most recent version of Advanced Installer and install it on the machine without requiring any user intervention. This means that we are not forced to create a self-hosted agent where to manually install the tool, but we can leverage the built-in agents provided by Azure DevOps.
Let's start!
The Advanced Installer project
As a starting point, I will use a simple Windows Forms application calledMyEmployees,which I have used also in other posts. However, the main difference is that, this time, the solution doesn't have a Windows Application Packaging Project. We're going to use Advanced Installer to create a MSIX package, together with a MSI. In a real scenario probably you already have the setup created with Advanced Installer but, to understand better how it works, let's create a new one.
First you need todownload and installthe latest Advanced Installer version. It's a paid product, but it offers a 30 days trial and also a free tier. Once you have launched it, you will find in theTemplatessection one calledVisual Studio Application, which is able to connect directly to a Visual Studio solution, like in our case.
First you will be asked the name and the publisher of your application, followed by the distribution type. For the moment chooseMSI setup file. We're going to add the MSIX definition later. In the next step you will be asked where to save the project, using a file with .aip extension. You will need to add this file in a folder of your project, since we'll need to commit it to our repository, in order to use the Azure DevOps task. In my case, I've created a folder calledProjectsinside the solution. The project output folder will be automatically changed to point to the same location, but I suggest you to choose a different one, outside the repository. This folder, in fact, will contain the various artifacts (like the generated MSI or MSIX package) and we don't want to include them in the source code.
As next step, you must choose the Visual Studio solution which contains your project. In my case, I've chosen theMyEmployees.slnfile. Advanced Installer will analyze the solution and it will ask you which configurations you want to import. Feel free to choose the ones that make sense for your project. In my case, for example, I want to distribute only the 64 bit version, built in Release mode:
In the next step you will be asked to select which files, among the ones that are created as build output, belong to the application and must be included in the installer. The section will be split in two categories:
Output files, which are the files created in the bin folder as part of the build process.
Reference files, which are the files that are referenced by your projects (for example, 3rd party libraries).
In my case, I'm going to include all the output files, plus the reference files coming from NuGet, like JSON.net or System.Data.SQLite. I don't need to include the references related to the .NET Framework, since they are already installed on the machine.
In the next step, you will need to select the main executable of your application. Advanced Installer should be able to automatically detect it, especially if it's a scenario like mine where the application is composed by a single executable. This information will be used to configure the shortcuts on the desktop and/or the Start Menu.
All the other steps are optional and apply mostly to the MSI setup: you can choose if you want to launch the application after having it installed; you can customize the UI of the installer; you can choose the languages you support; you can add a license agreement that will be displayed during the setup. After you have finished the wizard, Advanced Installer will bring you to the main UI of the application, where you can further customize the project. The tool offers tons of options: you can add support to services or custom actions, you can customize the manifest for the MSIX version, etc.
We're going to keep it simple, so we won't add any special configuration. However, there's a setting that is very important. Move to theFiles and Folderssection, which displays what and where the installer will copy on the user's machine. You will see a folder calledApplication folder, which is the location where the files which compose the application will be copied. However, you might see that not all the files are properly included.
Additionally, you will notice that if you update the source code of your application and you produce a new build, it won't be automatically picked up. To solve this problem we need to setup a sync between the Visual Studio project and the Advanced Installer project, so that during the CI pipeline we can produce a MSI / MSIX which reflects the most recent version.
To achieve this goal we must enable the sync feature. Right click on theApplication Folderin the tree and chooseProperties. Then move to theSynchronizetab and click onSynchronize content with folder from disk. As source folder, you must specify the output of the build in the bin folder of your Visual Studio project. For example, since in my case I'm compiling the application in Release mode, I'm picking up theMyEmployees\bin\Releasefolder. Once you press Ok, you will be asked if you want to remove the files which are already included. PressYes. You will notice now that all the files are correctly included:
Additionally, they're kept in sync with the folder. This means that, whenever you're going to launch a new Visual Studio build, the updated executable and DLLs will be copied over to the Advanced Installer project.
Test the MSI generation
Before working on the Azure DevOps side, let's see if the MSI is created successfully. Move to theBuildssection, where you will find a definition calledDefaultBuild. Right click on it and chooseBuild. If everything goes well, you will find in the Project Output folder you have set during the wizard the MSI. If you try to install it you will get some warnings because the file isn't signed with a valid certificate. Advanced Installer supports signing as part of the build process, but for the moment we're going to keep it unsigned. We'll perform the signing directly on Azure DevOps.
Create a MSIX package
Now that we have a project up & running, generating a MSIX package is really simple. We just need to move to theBuildssection and chooseMSIX / APPX Build. A new build definition will be created, calledBuild_MSIX_APPX.
From the page you will be able to set different options related to MSIX packaging, like the minimum Windows 10 version you want to target or the generation of an App Installer file as part of the process. If you want to try it, just right click on this build definition and choose Build. At the end of the process, you will get in the project output folder a MSIX package. However, in this case you will be completely blocked from installing it, since we haven't signed it. And, as you know, unsigned MSIX packages can't be installed. But don't worry, we're going to do this as well on Azure DevOps.
Putting everything under source control
Now our project should look like this:
The MyEmployees folder contains the Windows Forms project, while the Projects one includes the Advanced Installer setup we have just created. This is the folder you need to make sure to include in your repository on GitHub, Azure Repos or whatever source control provider you prefer. We need to keep the Advanced Installer project together with the source code of the project.
Setup the pipeline
Now that we have everything we need, we can start working on the pipeline. However, first, we need to install the task by Advanced Installer on our Azure DevOps account.This is the one you need, calledAdvanced Installer Build. The company provides also a task calledAdvanced Installer Tool Installer,which takes care of installing Advanced Installer on the hosted agent. However, it isn't really needed because the Build task can do it as well.
Once you have installed it, you can move to thePipelinessection of your Azure DevOps project and create a new pipeline. As usual, first you will have to choose the repository where your code is hosted, followed by the starting template. In my case it's a Windows Forms application, so I chose the.NET Desktopone, which looks like this:
# .NET Desktop# Build and run tests for .NET Desktop or Windows classic desktop solutions.# Add steps that publish symbols, save build artifacts, and more:# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-nettrigger:-masterpool: vmImage:'windows-latest'variables: solution:'**/*.sln' buildPlatform:'Any CPU' buildConfiguration:'Release'steps:- task:NuGetToolInstaller@1- task:NuGetCommand@2 inputs: restoreSolution:'$(solution)'- task:VSBuild@1 inputs: solution:'$(solution)' platform:'$(buildPlatform)' configuration:'$(buildConfiguration)'- task:VSTest@2 inputs: platform:'$(buildPlatform)' configuration:'$(buildConfiguration)'
It's a good starting point, since it already takes care of restoring the NuGet packages and building the code. The next step is to add the Advanced Installer tasks, so that the code can be converted into an installer. We're going to add two tasks: one to generate a MSI and one to generate a MSIX.
aiPathis the path, starting from the root of the repository, which contains the Advanced Installer project.
aipBuildis the name of the build definition we want to run. In this case we're creating the MSI first, so we use theDefaultBuilddefinition.
TheaipPackageNameparameter is optional. However, in my case, I prefer to add a reference to the build number in the file name generated by the tool, so that it's easier for me to understand the version number. As such, I have added the variable$(Build.BuildNumber)as suffix to the file name.
aipOutputFolderspecifies where you want to copy the generated packages. In this case I use a folder called MSI, which is created under the default folder where artifacts are picked up. This way, it will be easier for me to publish the generated MSI as build artifact.
TheadvinstLicenseparameter deserves a special mention. As anticipated in the beginning of the post, Advanced Installer is a paid product. As such, if you're building a project's type which isn't covered by the free license, you will need to provide your license key. Since YAML files are typically included in the repository, it isn't a good idea to store it in clear. As such, I have used theVariablespanel to create a variable calledAILicensewith the key and then I've referenced it in the YAML using the$(AILicense)keyword.
Now that you have seen how to configure the task, it will be very easy to add a new one to generate the MSIX package:
We change just the name of the build definition to run, the name of the package (this time the extension will be .msix and not .msi) and the output folder. To keep things clean, in fact, I create the MSIX package in a different folder, called MSIX.
Now the last step is to publish the build artifacts, by adding a publish task:
That's it! Now save the pipeline, which will automatically trigger a new build. Azure DevOps will first compile the Windows Forms application and then it will execute the Advanced Installer task twice, one for the MSI and one for the MSIX. The first task will take longer, because it will take care also of downloading the tool on the hosted agent. The second task, instead, will reuse the same one.
At the end of the process, if you explore the artifacts you should see something like this:
Create a release pipeline
Now that you have created a CI pipeline, it's time to create a CD pipeline to automate the deployment of these packages. Move to theReleasessection on Azure DevOps and press the button to create a new pipeline. You will be prompted with a series of templates. We're going to start from an empty job, so click on the related link.
Let's start from the one to deploy the MSI, so let's call it Deploy MSI. But first, click on Add an artifact in the Artifacts section and choose the one produced by the CI pipeline you have just created.
Now you can click on the link under the task name to start adding tasks. The first step is to sign the installer, to avoid the warnings by Windows that are displayed when you tried to install an untrusted installer. The easiest way to achieve this goal is to use an extension created by Stefan Kert called Code Signing. If you haven't already installed it on your Azure DevOps account,go on and install it.
Then click on the + symbol nearAgent job, look for theCode Signingtask and add it. You'll need to have a .pfx file with the certificate that you're going to use to sign the installer. You can acquire one from a public certificate authority or get it from your internal one if the installer is meant for enterprise deployment; alternatively, if you're just doing some tests, you can generatea self-signed certificate.
Here are the field to configure:
Secure Fileis the path to the file which contains your certificate. The task uses theSecure Filesfeature from Azure DevOps, which means that we can safely upload it by clicking on the Settings button near the field. The file will be available only to be used in this pipeline; no one will be able to download it and reuse it, blocking malicious actors that could be interested in stealing our identity.
Secure File Passwordis the password you have used to protect your certificate. Since it's better to not store the password in clear, I have setup a variable called$(PfxPassword)in theVariablestab.
File(s) to signis the path of the file to sign. In this case, we just set it to**/*.msi. We generically sign every file with .msi extension in the artifacts folder.
That's it. The next step is... well, it's up to you 😃 Now that the installer has been signed, you can add a task to deploy it in the place which makes more sense for you. For example, you can deploy it to a storage or a FTP, where the file will be linked by a web page. In my scenario, I'm using Azure Storage to store the file in a blob, so I'm using the task calledAzure File Copy.
Once you've completed the task, you can click onPipelineand go back to setup the MSIX package deployment. In theStagessection click onAddand chooseNew stage. Also in this case choose to create an empty job and give it a meaningful name, likeDeploy MSIX.
This is how your pipeline should look like:
Click on the link under the new stage to start adding tasks. Also in this case the required one is the Code Signing tasks, which you need to sign the MSIX package. The configuration is exactly the same as we did for the MSI, as long as you're using the same certificate. The only difference is that the File(s) to sign field must be changed to **/*.msix, as in the following image:
Pay attention that, in order for the signing to complete successful, the subject of the certificate must match the publisher declared in the manifest. You can check this in Advanced Installer. Move to the Package Information tab under the Universal Windows section and look for Publisher section:
The value that must match the subject of your certificate is the one in theIDfield.
Now you're ready for the deployment. Also in this case you can choose the task which fits best your scenario. For example, you can deploy the MSIX package to Azure Storage and leverage the App Installer technology to handle the installation and automatic updates. If you want to generate an App Installer file as part of the build process, you can leverage again Advanced Installer. Move to theBuildssection of your project and, in the MSIX build definition, look for the section titledAppInstaller. There you will be able to provide all the relevant information, like the URL where you're going to deploy the package, the frequency check for automatic updates, etc.
Remember that some options might be disabled, based on the Windows 10 version you're targeting in theTarget Platformssection. For example, theShow Promptoption is supported starting from Windows 10 1903, so if you're targeting a lower version the option will be disabled.
Remember to commit the updated .ai file to your repository every time you make any change to the Advanced Installer project. This way, you will trigger a new build and a new generation of the MSI and MSIX installers. As last step, if you truly want to enable a full CI/CD experience, remember to click, in the Release pipeline, on the lighting symbol in theArtifactssection and set toEnabledthe Continuous Deployment Trigger.
This way, Azure DevOps will automatically trigger the Release pipeline every time the build pipeline completes successfully.
Wrapping up
In this blog post we have seen how, with Advanced Installer, we can enable a CI/CD pipeline on Azure DevOps that automatically generates both a MSI and a MSIX package out from the code of our application. This way, we can keep supporting customers who aren't using Windows 10 yet but, at the same time, provide a much better deployment experience for the ones who already doing it. Hopefully, over time, you will be able to stop creating a MSI and focus only on MSIX 😃
There are many great 3rd party tools on the market that can help you in the process of creating installers and packages for your applications. Advanced Installer is one of them and one thing I have appreciated is the availability of an Azure DevOps task, which allows me to use one of the built-in hosted agents, without forcing me to maintain a dedicated agent with the required tools.
You can find the sample used in this project, together with the full pipeline definition, onGitHub.
I already have a msi package. I want to convert it to MSIX package using CI/CD. I have architect version of Advanced Installer. How can I achieve this?
In my case I need to deploy ".MSI" package web application in Azure Devops Web app server in this scenario how can i deploy release pipeline. Please help me on this.
In my build release package I have below file system, when I deployed this package into azure web app server and browse it leads me into 'Server Error in '/' Application. page
'
****.msi
***.wixpdb
setup.exe
Thanks
Chethan
Share
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Social_Sharing\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:ModernWorkAppConsult\",\"message:1142985\"],\"name\":\"BlogMessagePage\",\"props\":{},\"url\":\"https://techcommunity.microsoft.com/blog/modernworkappconsult/building-installers-for-your-windows-applications-with-advanced-installer-and-az/1142985\"}}})":{"__typename":"ComponentRenderResult","html":""}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCoverImage\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCoverImage-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeTitle\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTimeToRead\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1744145527415"}],"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1744145527415"}],"message({\"id\":\"message:3864463\"})":{"__ref":"BlogReplyMessage:message:3864463"},"message({\"id\":\"message:2515337\"})":{"__ref":"BlogReplyMessage:message:2515337"},"cachedText({\"lastModified\":\"1744145527415\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1744145527415"}]},"CachedAsset:pages-1743764478338":{"__typename":"CachedAsset","id":"pages-1743764478338","value":[{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743764478338,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","entityType":"CATEGORY","displayId":"microsoft365","nodeType":"category","depth":3,"title":"Microsoft 365","shortTitle":"Microsoft 365","parent":{"__ref":"Category:category:products-services"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","entityType":"CATEGORY","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","entityType":"CATEGORY","shortTitle":"Products"},"Blog:board:ModernWorkAppConsult":{"__typename":"Blog","id":"board:ModernWorkAppConsult","entityType":"BLOG","displayId":"ModernWorkAppConsult","nodeType":"board","depth":4,"conversationStyle":"BLOG","title":"Modern Work App Consult Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:microsoft365"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:microsoft365"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"shortTitle":"Modern Work App Consult Blog","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/","tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"PRESET_ONLY"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":6,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:44595":{"__typename":"User","id":"user:44595","uid":44595,"login":"Matteo Pagani","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS00NDU5NS02MzA4OGkwNTU0MkU2NzQwODM2NTE0"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":117,"biography":null,"topicsCount":39,"kudosReceivedCount":132,"kudosGivenCount":1,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2017-03-19T04:38:14.936-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":1},"BlogTopicMessage:message:1142985":{"__typename":"BlogTopicMessage","uid":1142985,"subject":"Building installers for your Windows applications with Advanced Installer and Azure DevOps","id":"message:1142985","revisionNum":1,"repliesCount":2,"author":{"__ref":"User:user:44595"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"conversation":{"__ref":"Conversation:conversation:1142985"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:1142985"},"teaser":"
Learn how you can use Advanced Installer and Azure DevOps to enable CI/CD for your Windows applications
","body":"
If you follow my activities, like the articles I publish on this blog orthe recent book I've published about MSIX, you'll know that one of the reasons why I like MSIX from a developer perspective is that it makes really easy to enable a CI/CD pipeline for Windows desktop applications. Thanks tothe Windows Application Packaging Project, we can easily automate the creation of a MSIX package simply by adding it to our solution and running a build. And thanks to features likeApp Installer, we can easily deploy the generated MSIX package to a website and support automatic updates without changing the code or having to setup your own service.
\n
\n
However, in many cases you may already have an installer definition created with a 3rd party tool. Popular authoring tools, likeAdvanced Installer,InstallShieldorWix, are able to generate a MSIX package out from an installer project, making easier to reuse the work you may already have done to generate MSI installers in the past. Additionally, thanks to these tools, you have the opportunity to use the same project to generate at the same time a MSI and a MSIX, helping you to support customers who might not have migrated yet to Windows 10 and who are unable to useMSIX Core(for example, because it's a consumer application).
\n
\n
What about enabling a CI/CD pipeline in this scenario? In this blog post we're going to see an example on how to achieve this task with Advanced Installer. Why did I choose this product? Well, other than because it's a really good software, the Advanced Installer team has created a task for Azure DevOps which is able to build an Advanced Installer project stored on the repository. And, most of all, the task is able to download the most recent version of Advanced Installer and install it on the machine without requiring any user intervention. This means that we are not forced to create a self-hosted agent where to manually install the tool, but we can leverage the built-in agents provided by Azure DevOps.
\n
\n
Let's start!
\n
\n
The Advanced Installer project
\n
As a starting point, I will use a simple Windows Forms application calledMyEmployees,which I have used also in other posts. However, the main difference is that, this time, the solution doesn't have a Windows Application Packaging Project. We're going to use Advanced Installer to create a MSIX package, together with a MSI. In a real scenario probably you already have the setup created with Advanced Installer but, to understand better how it works, let's create a new one.
\n
\n
First you need todownload and installthe latest Advanced Installer version. It's a paid product, but it offers a 30 days trial and also a free tier. Once you have launched it, you will find in theTemplatessection one calledVisual Studio Application, which is able to connect directly to a Visual Studio solution, like in our case.
\n
\n
\n
\n
First you will be asked the name and the publisher of your application, followed by the distribution type. For the moment chooseMSI setup file. We're going to add the MSIX definition later. In the next step you will be asked where to save the project, using a file with .aip extension. You will need to add this file in a folder of your project, since we'll need to commit it to our repository, in order to use the Azure DevOps task. In my case, I've created a folder calledProjectsinside the solution. The project output folder will be automatically changed to point to the same location, but I suggest you to choose a different one, outside the repository. This folder, in fact, will contain the various artifacts (like the generated MSI or MSIX package) and we don't want to include them in the source code.
\n
\n
As next step, you must choose the Visual Studio solution which contains your project. In my case, I've chosen theMyEmployees.slnfile. Advanced Installer will analyze the solution and it will ask you which configurations you want to import. Feel free to choose the ones that make sense for your project. In my case, for example, I want to distribute only the 64 bit version, built in Release mode:
\n
\n
\n
\n
In the next step you will be asked to select which files, among the ones that are created as build output, belong to the application and must be included in the installer. The section will be split in two categories:
\n
\n
\n
Output files, which are the files created in the bin folder as part of the build process.
\n
Reference files, which are the files that are referenced by your projects (for example, 3rd party libraries).
\n
\n
In my case, I'm going to include all the output files, plus the reference files coming from NuGet, like JSON.net or System.Data.SQLite. I don't need to include the references related to the .NET Framework, since they are already installed on the machine.
\n
\n
\n
\n
In the next step, you will need to select the main executable of your application. Advanced Installer should be able to automatically detect it, especially if it's a scenario like mine where the application is composed by a single executable. This information will be used to configure the shortcuts on the desktop and/or the Start Menu.
\n
\n
\n
\n
All the other steps are optional and apply mostly to the MSI setup: you can choose if you want to launch the application after having it installed; you can customize the UI of the installer; you can choose the languages you support; you can add a license agreement that will be displayed during the setup. After you have finished the wizard, Advanced Installer will bring you to the main UI of the application, where you can further customize the project. The tool offers tons of options: you can add support to services or custom actions, you can customize the manifest for the MSIX version, etc.
\n
\n
We're going to keep it simple, so we won't add any special configuration. However, there's a setting that is very important. Move to theFiles and Folderssection, which displays what and where the installer will copy on the user's machine. You will see a folder calledApplication folder, which is the location where the files which compose the application will be copied. However, you might see that not all the files are properly included.
\n
\n
\n
\n
Additionally, you will notice that if you update the source code of your application and you produce a new build, it won't be automatically picked up. To solve this problem we need to setup a sync between the Visual Studio project and the Advanced Installer project, so that during the CI pipeline we can produce a MSI / MSIX which reflects the most recent version.
\n
\n
To achieve this goal we must enable the sync feature. Right click on theApplication Folderin the tree and chooseProperties. Then move to theSynchronizetab and click onSynchronize content with folder from disk. As source folder, you must specify the output of the build in the bin folder of your Visual Studio project. For example, since in my case I'm compiling the application in Release mode, I'm picking up theMyEmployees\\bin\\Releasefolder. Once you press Ok, you will be asked if you want to remove the files which are already included. PressYes. You will notice now that all the files are correctly included:
\n
\n
\n
\n
Additionally, they're kept in sync with the folder. This means that, whenever you're going to launch a new Visual Studio build, the updated executable and DLLs will be copied over to the Advanced Installer project.
\n
\n
Test the MSI generation
\n
Before working on the Azure DevOps side, let's see if the MSI is created successfully. Move to theBuildssection, where you will find a definition calledDefaultBuild. Right click on it and chooseBuild. If everything goes well, you will find in the Project Output folder you have set during the wizard the MSI. If you try to install it you will get some warnings because the file isn't signed with a valid certificate. Advanced Installer supports signing as part of the build process, but for the moment we're going to keep it unsigned. We'll perform the signing directly on Azure DevOps.
\n
\n
Create a MSIX package
\n
Now that we have a project up & running, generating a MSIX package is really simple. We just need to move to theBuildssection and chooseMSIX / APPX Build. A new build definition will be created, calledBuild_MSIX_APPX.
\n
\n
\n
\n
From the page you will be able to set different options related to MSIX packaging, like the minimum Windows 10 version you want to target or the generation of an App Installer file as part of the process. If you want to try it, just right click on this build definition and choose Build. At the end of the process, you will get in the project output folder a MSIX package. However, in this case you will be completely blocked from installing it, since we haven't signed it. And, as you know, unsigned MSIX packages can't be installed. But don't worry, we're going to do this as well on Azure DevOps.
\n
\n
Putting everything under source control
\n
Now our project should look like this:
\n
\n
\n
\n
The MyEmployees folder contains the Windows Forms project, while the Projects one includes the Advanced Installer setup we have just created. This is the folder you need to make sure to include in your repository on GitHub, Azure Repos or whatever source control provider you prefer. We need to keep the Advanced Installer project together with the source code of the project.
\n
\n
Setup the pipeline
\n
Now that we have everything we need, we can start working on the pipeline. However, first, we need to install the task by Advanced Installer on our Azure DevOps account.This is the one you need, calledAdvanced Installer Build. The company provides also a task calledAdvanced Installer Tool Installer,which takes care of installing Advanced Installer on the hosted agent. However, it isn't really needed because the Build task can do it as well.
\n
Once you have installed it, you can move to thePipelinessection of your Azure DevOps project and create a new pipeline. As usual, first you will have to choose the repository where your code is hosted, followed by the starting template. In my case it's a Windows Forms application, so I chose the.NET Desktopone, which looks like this:
\n
\n
# .NET Desktop\n# Build and run tests for .NET Desktop or Windows classic desktop solutions.\n# Add steps that publish symbols, save build artifacts, and more:\n# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net\n\ntrigger:\n-master\n\npool:\n vmImage:'windows-latest'\n\nvariables:\n solution:'**/*.sln'\n buildPlatform:'Any CPU'\n buildConfiguration:'Release'\n\nsteps:\n- task:NuGetToolInstaller@1\n\n- task:NuGetCommand@2\n inputs:\n restoreSolution:'$(solution)'\n\n- task:VSBuild@1\n inputs:\n solution:'$(solution)'\n platform:'$(buildPlatform)'\n configuration:'$(buildConfiguration)'\n\n- task:VSTest@2\n inputs:\n platform:'$(buildPlatform)'\n configuration:'$(buildConfiguration)'\n
\n
It's a good starting point, since it already takes care of restoring the NuGet packages and building the code. The next step is to add the Advanced Installer tasks, so that the code can be converted into an installer. We're going to add two tasks: one to generate a MSI and one to generate a MSIX.
aiPathis the path, starting from the root of the repository, which contains the Advanced Installer project.
\n
aipBuildis the name of the build definition we want to run. In this case we're creating the MSI first, so we use theDefaultBuilddefinition.
\n
TheaipPackageNameparameter is optional. However, in my case, I prefer to add a reference to the build number in the file name generated by the tool, so that it's easier for me to understand the version number. As such, I have added the variable$(Build.BuildNumber)as suffix to the file name.
\n
aipOutputFolderspecifies where you want to copy the generated packages. In this case I use a folder called MSI, which is created under the default folder where artifacts are picked up. This way, it will be easier for me to publish the generated MSI as build artifact.
\n
\n
TheadvinstLicenseparameter deserves a special mention. As anticipated in the beginning of the post, Advanced Installer is a paid product. As such, if you're building a project's type which isn't covered by the free license, you will need to provide your license key. Since YAML files are typically included in the repository, it isn't a good idea to store it in clear. As such, I have used theVariablespanel to create a variable calledAILicensewith the key and then I've referenced it in the YAML using the$(AILicense)keyword.
\n
\n
Now that you have seen how to configure the task, it will be very easy to add a new one to generate the MSIX package:
We change just the name of the build definition to run, the name of the package (this time the extension will be .msix and not .msi) and the output folder. To keep things clean, in fact, I create the MSIX package in a different folder, called MSIX.
\n
Now the last step is to publish the build artifacts, by adding a publish task:
That's it! Now save the pipeline, which will automatically trigger a new build. Azure DevOps will first compile the Windows Forms application and then it will execute the Advanced Installer task twice, one for the MSI and one for the MSIX. The first task will take longer, because it will take care also of downloading the tool on the hosted agent. The second task, instead, will reuse the same one.
\n
At the end of the process, if you explore the artifacts you should see something like this:
\n
\n
\n
\n
Create a release pipeline
\n
Now that you have created a CI pipeline, it's time to create a CD pipeline to automate the deployment of these packages. Move to theReleasessection on Azure DevOps and press the button to create a new pipeline. You will be prompted with a series of templates. We're going to start from an empty job, so click on the related link.
\n
\n
Let's start from the one to deploy the MSI, so let's call it Deploy MSI. But first, click on Add an artifact in the Artifacts section and choose the one produced by the CI pipeline you have just created.
\n
\n
\n
\n
Now you can click on the link under the task name to start adding tasks. The first step is to sign the installer, to avoid the warnings by Windows that are displayed when you tried to install an untrusted installer. The easiest way to achieve this goal is to use an extension created by Stefan Kert called Code Signing. If you haven't already installed it on your Azure DevOps account,go on and install it.
\n
\n
Then click on the + symbol nearAgent job, look for theCode Signingtask and add it. You'll need to have a .pfx file with the certificate that you're going to use to sign the installer. You can acquire one from a public certificate authority or get it from your internal one if the installer is meant for enterprise deployment; alternatively, if you're just doing some tests, you can generatea self-signed certificate.
\n
Here are the field to configure:
\n
\n
\n
Secure Fileis the path to the file which contains your certificate. The task uses theSecure Filesfeature from Azure DevOps, which means that we can safely upload it by clicking on the Settings button near the field. The file will be available only to be used in this pipeline; no one will be able to download it and reuse it, blocking malicious actors that could be interested in stealing our identity.
\n
Secure File Passwordis the password you have used to protect your certificate. Since it's better to not store the password in clear, I have setup a variable called$(PfxPassword)in theVariablestab.
\n
File(s) to signis the path of the file to sign. In this case, we just set it to**/*.msi. We generically sign every file with .msi extension in the artifacts folder.
\n
\n
\n
\n
\n
That's it. The next step is... well, it's up to you 😃 Now that the installer has been signed, you can add a task to deploy it in the place which makes more sense for you. For example, you can deploy it to a storage or a FTP, where the file will be linked by a web page. In my scenario, I'm using Azure Storage to store the file in a blob, so I'm using the task calledAzure File Copy.
\n
\n
Once you've completed the task, you can click onPipelineand go back to setup the MSIX package deployment. In theStagessection click onAddand chooseNew stage. Also in this case choose to create an empty job and give it a meaningful name, likeDeploy MSIX.
\n
\n
This is how your pipeline should look like:
\n
\n
\n
\n
Click on the link under the new stage to start adding tasks. Also in this case the required one is the Code Signing tasks, which you need to sign the MSIX package. The configuration is exactly the same as we did for the MSI, as long as you're using the same certificate. The only difference is that the File(s) to sign field must be changed to **/*.msix, as in the following image:
\n
\n
\n
\n
Pay attention that, in order for the signing to complete successful, the subject of the certificate must match the publisher declared in the manifest. You can check this in Advanced Installer. Move to the Package Information tab under the Universal Windows section and look for Publisher section:
\n
\n
\n
The value that must match the subject of your certificate is the one in theIDfield.
\n
\n
Now you're ready for the deployment. Also in this case you can choose the task which fits best your scenario. For example, you can deploy the MSIX package to Azure Storage and leverage the App Installer technology to handle the installation and automatic updates. If you want to generate an App Installer file as part of the build process, you can leverage again Advanced Installer. Move to theBuildssection of your project and, in the MSIX build definition, look for the section titledAppInstaller. There you will be able to provide all the relevant information, like the URL where you're going to deploy the package, the frequency check for automatic updates, etc.
\n
\n
\n
\n
Remember that some options might be disabled, based on the Windows 10 version you're targeting in theTarget Platformssection. For example, theShow Promptoption is supported starting from Windows 10 1903, so if you're targeting a lower version the option will be disabled.
\n
\n
Remember to commit the updated .ai file to your repository every time you make any change to the Advanced Installer project. This way, you will trigger a new build and a new generation of the MSI and MSIX installers. As last step, if you truly want to enable a full CI/CD experience, remember to click, in the Release pipeline, on the lighting symbol in theArtifactssection and set toEnabledthe Continuous Deployment Trigger.
\n
\n
\n
\n
This way, Azure DevOps will automatically trigger the Release pipeline every time the build pipeline completes successfully.
\n
\n
Wrapping up
\n
In this blog post we have seen how, with Advanced Installer, we can enable a CI/CD pipeline on Azure DevOps that automatically generates both a MSI and a MSIX package out from the code of our application. This way, we can keep supporting customers who aren't using Windows 10 yet but, at the same time, provide a much better deployment experience for the ones who already doing it. Hopefully, over time, you will be able to stop creating a MSI and focus only on MSIX 😃
\n
There are many great 3rd party tools on the market that can help you in the process of creating installers and packages for your applications. Advanced Installer is one of them and one thing I have appreciated is the availability of an Azure DevOps task, which allows me to use one of the built-in hosted agents, without forcing me to maintain a dedicated agent with the required tools.
\n
\n
You can find the sample used in this project, together with the full pipeline definition, onGitHub.
\n
\n
Happy packaging!
\n
","body@stringLength":"37702","rawBody":"
If you follow my activities, like the articles I publish on this blog orthe recent book I've published about MSIX, you'll know that one of the reasons why I like MSIX from a developer perspective is that it makes really easy to enable a CI/CD pipeline for Windows desktop applications. Thanks tothe Windows Application Packaging Project, we can easily automate the creation of a MSIX package simply by adding it to our solution and running a build. And thanks to features likeApp Installer, we can easily deploy the generated MSIX package to a website and support automatic updates without changing the code or having to setup your own service.
\n
\n
However, in many cases you may already have an installer definition created with a 3rd party tool. Popular authoring tools, likeAdvanced Installer,InstallShieldorWix, are able to generate a MSIX package out from an installer project, making easier to reuse the work you may already have done to generate MSI installers in the past. Additionally, thanks to these tools, you have the opportunity to use the same project to generate at the same time a MSI and a MSIX, helping you to support customers who might not have migrated yet to Windows 10 and who are unable to useMSIX Core(for example, because it's a consumer application).
\n
\n
What about enabling a CI/CD pipeline in this scenario? In this blog post we're going to see an example on how to achieve this task with Advanced Installer. Why did I choose this product? Well, other than because it's a really good software, the Advanced Installer team has created a task for Azure DevOps which is able to build an Advanced Installer project stored on the repository. And, most of all, the task is able to download the most recent version of Advanced Installer and install it on the machine without requiring any user intervention. This means that we are not forced to create a self-hosted agent where to manually install the tool, but we can leverage the built-in agents provided by Azure DevOps.
\n
\n
Let's start!
\n
\n
The Advanced Installer project
\n
As a starting point, I will use a simple Windows Forms application calledMyEmployees,which I have used also in other posts. However, the main difference is that, this time, the solution doesn't have a Windows Application Packaging Project. We're going to use Advanced Installer to create a MSIX package, together with a MSI. In a real scenario probably you already have the setup created with Advanced Installer but, to understand better how it works, let's create a new one.
\n
\n
First you need todownload and installthe latest Advanced Installer version. It's a paid product, but it offers a 30 days trial and also a free tier. Once you have launched it, you will find in theTemplatessection one calledVisual Studio Application, which is able to connect directly to a Visual Studio solution, like in our case.
\n
\n
\n
\n
First you will be asked the name and the publisher of your application, followed by the distribution type. For the moment chooseMSI setup file. We're going to add the MSIX definition later. In the next step you will be asked where to save the project, using a file with .aip extension. You will need to add this file in a folder of your project, since we'll need to commit it to our repository, in order to use the Azure DevOps task. In my case, I've created a folder calledProjectsinside the solution. The project output folder will be automatically changed to point to the same location, but I suggest you to choose a different one, outside the repository. This folder, in fact, will contain the various artifacts (like the generated MSI or MSIX package) and we don't want to include them in the source code.
\n
\n
As next step, you must choose the Visual Studio solution which contains your project. In my case, I've chosen theMyEmployees.slnfile. Advanced Installer will analyze the solution and it will ask you which configurations you want to import. Feel free to choose the ones that make sense for your project. In my case, for example, I want to distribute only the 64 bit version, built in Release mode:
\n
\n
\n
\n
In the next step you will be asked to select which files, among the ones that are created as build output, belong to the application and must be included in the installer. The section will be split in two categories:
\n
\n
\n
Output files, which are the files created in the bin folder as part of the build process.
\n
Reference files, which are the files that are referenced by your projects (for example, 3rd party libraries).
\n
\n
In my case, I'm going to include all the output files, plus the reference files coming from NuGet, like JSON.net or System.Data.SQLite. I don't need to include the references related to the .NET Framework, since they are already installed on the machine.
\n
\n
\n
\n
In the next step, you will need to select the main executable of your application. Advanced Installer should be able to automatically detect it, especially if it's a scenario like mine where the application is composed by a single executable. This information will be used to configure the shortcuts on the desktop and/or the Start Menu.
\n
\n
\n
\n
All the other steps are optional and apply mostly to the MSI setup: you can choose if you want to launch the application after having it installed; you can customize the UI of the installer; you can choose the languages you support; you can add a license agreement that will be displayed during the setup. After you have finished the wizard, Advanced Installer will bring you to the main UI of the application, where you can further customize the project. The tool offers tons of options: you can add support to services or custom actions, you can customize the manifest for the MSIX version, etc.
\n
\n
We're going to keep it simple, so we won't add any special configuration. However, there's a setting that is very important. Move to theFiles and Folderssection, which displays what and where the installer will copy on the user's machine. You will see a folder calledApplication folder, which is the location where the files which compose the application will be copied. However, you might see that not all the files are properly included.
\n
\n
\n
\n
Additionally, you will notice that if you update the source code of your application and you produce a new build, it won't be automatically picked up. To solve this problem we need to setup a sync between the Visual Studio project and the Advanced Installer project, so that during the CI pipeline we can produce a MSI / MSIX which reflects the most recent version.
\n
\n
To achieve this goal we must enable the sync feature. Right click on theApplication Folderin the tree and chooseProperties. Then move to theSynchronizetab and click onSynchronize content with folder from disk. As source folder, you must specify the output of the build in the bin folder of your Visual Studio project. For example, since in my case I'm compiling the application in Release mode, I'm picking up theMyEmployees\\bin\\Releasefolder. Once you press Ok, you will be asked if you want to remove the files which are already included. PressYes. You will notice now that all the files are correctly included:
\n
\n
\n
\n
Additionally, they're kept in sync with the folder. This means that, whenever you're going to launch a new Visual Studio build, the updated executable and DLLs will be copied over to the Advanced Installer project.
\n
\n
Test the MSI generation
\n
Before working on the Azure DevOps side, let's see if the MSI is created successfully. Move to theBuildssection, where you will find a definition calledDefaultBuild. Right click on it and chooseBuild. If everything goes well, you will find in the Project Output folder you have set during the wizard the MSI. If you try to install it you will get some warnings because the file isn't signed with a valid certificate. Advanced Installer supports signing as part of the build process, but for the moment we're going to keep it unsigned. We'll perform the signing directly on Azure DevOps.
\n
\n
Create a MSIX package
\n
Now that we have a project up & running, generating a MSIX package is really simple. We just need to move to theBuildssection and chooseMSIX / APPX Build. A new build definition will be created, calledBuild_MSIX_APPX.
\n
\n
\n
\n
From the page you will be able to set different options related to MSIX packaging, like the minimum Windows 10 version you want to target or the generation of an App Installer file as part of the process. If you want to try it, just right click on this build definition and choose Build. At the end of the process, you will get in the project output folder a MSIX package. However, in this case you will be completely blocked from installing it, since we haven't signed it. And, as you know, unsigned MSIX packages can't be installed. But don't worry, we're going to do this as well on Azure DevOps.
\n
\n
Putting everything under source control
\n
Now our project should look like this:
\n
\n
\n
\n
The MyEmployees folder contains the Windows Forms project, while the Projects one includes the Advanced Installer setup we have just created. This is the folder you need to make sure to include in your repository on GitHub, Azure Repos or whatever source control provider you prefer. We need to keep the Advanced Installer project together with the source code of the project.
\n
\n
Setup the pipeline
\n
Now that we have everything we need, we can start working on the pipeline. However, first, we need to install the task by Advanced Installer on our Azure DevOps account.This is the one you need, calledAdvanced Installer Build. The company provides also a task calledAdvanced Installer Tool Installer,which takes care of installing Advanced Installer on the hosted agent. However, it isn't really needed because the Build task can do it as well.
\n
Once you have installed it, you can move to thePipelinessection of your Azure DevOps project and create a new pipeline. As usual, first you will have to choose the repository where your code is hosted, followed by the starting template. In my case it's a Windows Forms application, so I chose the.NET Desktopone, which looks like this:
\n
\n
# .NET Desktop\n# Build and run tests for .NET Desktop or Windows classic desktop solutions.\n# Add steps that publish symbols, save build artifacts, and more:\n# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net\n\ntrigger:\n-master\n\npool:\n vmImage:'windows-latest'\n\nvariables:\n solution:'**/*.sln'\n buildPlatform:'Any CPU'\n buildConfiguration:'Release'\n\nsteps:\n- task:NuGetToolInstaller@1\n\n- task:NuGetCommand@2\n inputs:\n restoreSolution:'$(solution)'\n\n- task:VSBuild@1\n inputs:\n solution:'$(solution)'\n platform:'$(buildPlatform)'\n configuration:'$(buildConfiguration)'\n\n- task:VSTest@2\n inputs:\n platform:'$(buildPlatform)'\n configuration:'$(buildConfiguration)'\n
\n
It's a good starting point, since it already takes care of restoring the NuGet packages and building the code. The next step is to add the Advanced Installer tasks, so that the code can be converted into an installer. We're going to add two tasks: one to generate a MSI and one to generate a MSIX.
aiPathis the path, starting from the root of the repository, which contains the Advanced Installer project.
\n
aipBuildis the name of the build definition we want to run. In this case we're creating the MSI first, so we use theDefaultBuilddefinition.
\n
TheaipPackageNameparameter is optional. However, in my case, I prefer to add a reference to the build number in the file name generated by the tool, so that it's easier for me to understand the version number. As such, I have added the variable$(Build.BuildNumber)as suffix to the file name.
\n
aipOutputFolderspecifies where you want to copy the generated packages. In this case I use a folder called MSI, which is created under the default folder where artifacts are picked up. This way, it will be easier for me to publish the generated MSI as build artifact.
\n
\n
TheadvinstLicenseparameter deserves a special mention. As anticipated in the beginning of the post, Advanced Installer is a paid product. As such, if you're building a project's type which isn't covered by the free license, you will need to provide your license key. Since YAML files are typically included in the repository, it isn't a good idea to store it in clear. As such, I have used theVariablespanel to create a variable calledAILicensewith the key and then I've referenced it in the YAML using the$(AILicense)keyword.
\n
\n
Now that you have seen how to configure the task, it will be very easy to add a new one to generate the MSIX package:
We change just the name of the build definition to run, the name of the package (this time the extension will be .msix and not .msi) and the output folder. To keep things clean, in fact, I create the MSIX package in a different folder, called MSIX.
\n
Now the last step is to publish the build artifacts, by adding a publish task:
That's it! Now save the pipeline, which will automatically trigger a new build. Azure DevOps will first compile the Windows Forms application and then it will execute the Advanced Installer task twice, one for the MSI and one for the MSIX. The first task will take longer, because it will take care also of downloading the tool on the hosted agent. The second task, instead, will reuse the same one.
\n
At the end of the process, if you explore the artifacts you should see something like this:
\n
\n
\n
\n
Create a release pipeline
\n
Now that you have created a CI pipeline, it's time to create a CD pipeline to automate the deployment of these packages. Move to theReleasessection on Azure DevOps and press the button to create a new pipeline. You will be prompted with a series of templates. We're going to start from an empty job, so click on the related link.
\n
\n
Let's start from the one to deploy the MSI, so let's call it Deploy MSI. But first, click on Add an artifact in the Artifacts section and choose the one produced by the CI pipeline you have just created.
\n
\n
\n
\n
Now you can click on the link under the task name to start adding tasks. The first step is to sign the installer, to avoid the warnings by Windows that are displayed when you tried to install an untrusted installer. The easiest way to achieve this goal is to use an extension created by Stefan Kert called Code Signing. If you haven't already installed it on your Azure DevOps account,go on and install it.
\n
\n
Then click on the + symbol nearAgent job, look for theCode Signingtask and add it. You'll need to have a .pfx file with the certificate that you're going to use to sign the installer. You can acquire one from a public certificate authority or get it from your internal one if the installer is meant for enterprise deployment; alternatively, if you're just doing some tests, you can generatea self-signed certificate.
\n
Here are the field to configure:
\n
\n
\n
Secure Fileis the path to the file which contains your certificate. The task uses theSecure Filesfeature from Azure DevOps, which means that we can safely upload it by clicking on the Settings button near the field. The file will be available only to be used in this pipeline; no one will be able to download it and reuse it, blocking malicious actors that could be interested in stealing our identity.
\n
Secure File Passwordis the password you have used to protect your certificate. Since it's better to not store the password in clear, I have setup a variable called$(PfxPassword)in theVariablestab.
\n
File(s) to signis the path of the file to sign. In this case, we just set it to**/*.msi. We generically sign every file with .msi extension in the artifacts folder.
\n
\n
\n
\n
\n
That's it. The next step is... well, it's up to you 😃 Now that the installer has been signed, you can add a task to deploy it in the place which makes more sense for you. For example, you can deploy it to a storage or a FTP, where the file will be linked by a web page. In my scenario, I'm using Azure Storage to store the file in a blob, so I'm using the task calledAzure File Copy.
\n
\n
Once you've completed the task, you can click onPipelineand go back to setup the MSIX package deployment. In theStagessection click onAddand chooseNew stage. Also in this case choose to create an empty job and give it a meaningful name, likeDeploy MSIX.
\n
\n
This is how your pipeline should look like:
\n
\n
\n
\n
Click on the link under the new stage to start adding tasks. Also in this case the required one is the Code Signing tasks, which you need to sign the MSIX package. The configuration is exactly the same as we did for the MSI, as long as you're using the same certificate. The only difference is that the File(s) to sign field must be changed to **/*.msix, as in the following image:
\n
\n
\n
\n
Pay attention that, in order for the signing to complete successful, the subject of the certificate must match the publisher declared in the manifest. You can check this in Advanced Installer. Move to the Package Information tab under the Universal Windows section and look for Publisher section:
\n
\n
\n
The value that must match the subject of your certificate is the one in theIDfield.
\n
\n
Now you're ready for the deployment. Also in this case you can choose the task which fits best your scenario. For example, you can deploy the MSIX package to Azure Storage and leverage the App Installer technology to handle the installation and automatic updates. If you want to generate an App Installer file as part of the build process, you can leverage again Advanced Installer. Move to theBuildssection of your project and, in the MSIX build definition, look for the section titledAppInstaller. There you will be able to provide all the relevant information, like the URL where you're going to deploy the package, the frequency check for automatic updates, etc.
\n
\n
\n
\n
Remember that some options might be disabled, based on the Windows 10 version you're targeting in theTarget Platformssection. For example, theShow Promptoption is supported starting from Windows 10 1903, so if you're targeting a lower version the option will be disabled.
\n
\n
Remember to commit the updated .ai file to your repository every time you make any change to the Advanced Installer project. This way, you will trigger a new build and a new generation of the MSI and MSIX installers. As last step, if you truly want to enable a full CI/CD experience, remember to click, in the Release pipeline, on the lighting symbol in theArtifactssection and set toEnabledthe Continuous Deployment Trigger.
\n
\n
\n
\n
This way, Azure DevOps will automatically trigger the Release pipeline every time the build pipeline completes successfully.
\n
\n
Wrapping up
\n
In this blog post we have seen how, with Advanced Installer, we can enable a CI/CD pipeline on Azure DevOps that automatically generates both a MSI and a MSIX package out from the code of our application. This way, we can keep supporting customers who aren't using Windows 10 yet but, at the same time, provide a much better deployment experience for the ones who already doing it. Hopefully, over time, you will be able to stop creating a MSI and focus only on MSIX 😃
\n
There are many great 3rd party tools on the market that can help you in the process of creating installers and packages for your applications. Advanced Installer is one of them and one thing I have appreciated is the availability of an Azure DevOps task, which allows me to use one of the built-in hosted agents, without forcing me to maintain a dedicated agent with the required tools.
\n
\n
You can find the sample used in this project, together with the full pipeline definition, onGitHub.
Learn how you can use Advanced Installer and Azure DevOps to enable CI/CD for your Windows applications
","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:1142985_1"},"latestVersion":{"__typename":"FriendlyVersion","major":"1","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":41093},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzg2NDQ2MywzODY0NDYz","node":{"__ref":"BlogReplyMessage:message:3864463"}},{"__typename":"MessageEdge","cursor":"MjUuMXwyLjF8aXwxMHwxMzI6MHxpbnQsMzg2NDQ2MywyNTE1MzM3","node":{"__ref":"BlogReplyMessage:message:2515337"}}],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":1}},"Conversation:conversation:1142985":{"__typename":"Conversation","id":"conversation:1142985","solved":false,"topic":{"__ref":"BlogTopicMessage:message:1142985"},"lastPostingActivityTime":"2023-07-03T10:12:59.125-07:00","lastPostTime":"2023-07-03T10:12:59.125-07:00","unreadReplyCount":2,"isSubscribed":false},"ModerationData:moderation_data:1142985":{"__typename":"ModerationData","id":"moderation_data:1142985","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwMGlENjA0RDgzRTBCRTBDOTg4?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwMGlENjA0RDgzRTBCRTBDOTg4?revision=1","title":"VisualStudioApplication.png","associationType":"BODY","width":1280,"height":1040,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwMWlEMzU1RUY4MEFEOUM4OTJG?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwMWlEMzU1RUY4MEFEOUM4OTJG?revision=1","title":"BuildConfiguration.png","associationType":"BODY","width":503,"height":433,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwMmlEREJCNjA5OEY3MkIxRjlC?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwMmlEREJCNjA5OEY3MkIxRjlC?revision=1","title":"DetectedFiles.png","associationType":"BODY","width":666,"height":568,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwM2k3RDA1N0I4NzQwNjIwMzND?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwM2k3RDA1N0I4NzQwNjIwMzND?revision=1","title":"Shortcuts.png","associationType":"BODY","width":666,"height":568,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwNGk5QUJFM0E3NEZBMkJERTgy?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwNGk5QUJFM0E3NEZBMkJERTgy?revision=1","title":"FilesAndFolders.png","associationType":"BODY","width":1353,"height":963,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwNWk1MjFGM0M4ODRERkZCNkEz?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwNWk1MjFGM0M4ODRERkZCNkEz?revision=1","title":"SyncEnabled.png","associationType":"BODY","width":1506,"height":963,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwOGlEMUNGODBCQ0M4RENEOThG?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwOGlEMUNGODBCQ0M4RENEOThG?revision=1","title":"MSIXSettings.png","associationType":"BODY","width":1506,"height":963,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwOWkyMzk2NUMyNUYyOUJGNDRF?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMwOWkyMzk2NUMyNUYyOUJGNDRF?revision=1","title":"ProjectFiles.png","associationType":"BODY","width":386,"height":101,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxMGk0RTgxMEQxMjgyODExQ0Y1?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxMGk0RTgxMEQxMjgyODExQ0Y1?revision=1","title":"Artifacts.png","associationType":"BODY","width":996,"height":363,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxMWk2NDNGQTFEQzMyN0E0MUVG?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxMWk2NDNGQTFEQzMyN0E0MUVG?revision=1","title":"ArtifactsConfiguration.png","associationType":"BODY","width":1280,"height":968,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxMmk1NDAyQ0MyMTgyQUIxQzFC?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxMmk1NDAyQ0MyMTgyQUIxQzFC?revision=1","title":"CodeSigning.png","associationType":"BODY","width":460,"height":754,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxM2k5Qjk1QjAzNTVEQzNCNDVD?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxM2k5Qjk1QjAzNTVEQzNCNDVD?revision=1","title":"ReleasePipeline.png","associationType":"BODY","width":675,"height":523,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxNWkzOUVCOUU3RENEMTY5MTYw?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxNWkzOUVCOUU3RENEMTY5MTYw?revision=1","title":"CodeSigningMSIX.png","associationType":"BODY","width":466,"height":757,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxNmkwODA3NzRGREQyRUIxRkFB?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxNmkwODA3NzRGREQyRUIxRkFB?revision=1","title":"Publisher.png","associationType":"BODY","width":1506,"height":963,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxN2lGOTRCNjcwN0E5NDRDNTAy?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxN2lGOTRCNjcwN0E5NDRDNTAy?revision=1","title":"AppInstaller.png","associationType":"BODY","width":1336,"height":762,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxOGlCOEEzMDczRDA4MzUwMUMw?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0xMTQyOTg1LTE2ODMxOGlCOEEzMDczRDA4MzUwMUMw?revision=1","title":"ContinuousDeployment.png","associationType":"BODY","width":995,"height":622,"altText":null},"Revision:revision:1142985_1":{"__typename":"Revision","id":"revision:1142985_1","lastEditTime":"2020-01-31T06:43:55.041-08:00"},"CachedAsset:theme:customTheme1-1743778046796":{"__typename":"CachedAsset","id":"theme:customTheme1-1743778046796","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1744145527415","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1744145527415","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1744145527415","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1744145526982":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1744145526982","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[{"id":"custom.widget.Social_Sharing","className":null,"props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":true,"title":"Share","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1743764287651":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1743764287651","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"planner","params":{"categoryId":"Planner"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoft-endpoint-manager"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-q-l-server","params":{"categoryId":"SQL-Server"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"SMB"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1744145527415","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-1743764513938":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-1743764513938","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display:block;\n box-shadow:none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size:14px;\n }\n}","texts":null,"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1a5zb_1 {\n a.custom_widget_community_banner_top-bar_1a5zb_2.custom_widget_community_banner_btn_1a5zb_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display:block;\n box-shadow:none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size:0.875rem;\n }\n}","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1a5zb_1","top-bar":"custom_widget_community_banner_top-bar_1a5zb_2","btn":"custom_widget_community_banner_btn_1a5zb_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-1743764513938":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-1743764513938","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search."},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.Social_Sharing-en-1743764513938":{"__typename":"CachedAsset","id":"component:custom.widget.Social_Sharing-en-1743764513938","value":{"component":{"id":"custom.widget.Social_Sharing","template":{"id":"Social_Sharing","markupLanguage":"HANDLEBARS","style":".social-share {\n .sharing-options {\n position: relative;\n margin: 0;\n padding: 0;\n line-height: 10px;\n display: flex;\n justify-content: left;\n gap: 5px;\n list-style-type: none;\n li {\n text-align: left;\n a {\n min-width: 30px;\n min-height: 30px;\n display: block;\n padding: 1px;\n .social-share-linkedin {\n img {\n background-color: rgb(0, 119, 181);\n }\n }\n .social-share-facebook {\n img {\n background-color: rgb(59, 89, 152);\n }\n }\n .social-share-x {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .social-share-rss {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .social-share-reddit {\n img {\n background-color: rgb(255, 69, 0);\n }\n }\n .social-share-email {\n img {\n background-color: rgb(132, 132, 132);\n }\n }\n }\n a {\n img {\n height: 2rem;\n }\n }\n }\n }\n}\n","texts":null,"defaults":{"config":{"applicablePages":[],"description":"Adds buttons to share to various social media websites","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Social_Sharing","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Adds buttons to share to various social media websites","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_Social_Sharing_social-share_c7xxz_1 {\n .custom_widget_Social_Sharing_sharing-options_c7xxz_2 {\n position: relative;\n margin: 0;\n padding: 0;\n line-height: 0.625rem;\n display: flex;\n justify-content: left;\n gap: 0.3125rem;\n list-style-type: none;\n li {\n text-align: left;\n a {\n min-width: 1.875rem;\n min-height: 1.875rem;\n display: block;\n padding: 0.0625rem;\n .custom_widget_Social_Sharing_social-share-linkedin_c7xxz_18 {\n img {\n background-color: rgb(0, 119, 181);\n }\n }\n .custom_widget_Social_Sharing_social-share-facebook_c7xxz_23 {\n img {\n background-color: rgb(59, 89, 152);\n }\n }\n .custom_widget_Social_Sharing_social-share-x_c7xxz_28 {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-rss_c7xxz_33 {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-reddit_c7xxz_38 {\n img {\n background-color: rgb(255, 69, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-email_c7xxz_43 {\n img {\n background-color: rgb(132, 132, 132);\n }\n }\n }\n a {\n img {\n height: 2rem;\n }\n }\n }\n }\n}\n","tokens":{"social-share":"custom_widget_Social_Sharing_social-share_c7xxz_1","sharing-options":"custom_widget_Social_Sharing_sharing-options_c7xxz_2","social-share-linkedin":"custom_widget_Social_Sharing_social-share-linkedin_c7xxz_18","social-share-facebook":"custom_widget_Social_Sharing_social-share-facebook_c7xxz_23","social-share-x":"custom_widget_Social_Sharing_social-share-x_c7xxz_28","social-share-rss":"custom_widget_Social_Sharing_social-share-rss_c7xxz_33","social-share-reddit":"custom_widget_Social_Sharing_social-share-reddit_c7xxz_38","social-share-email":"custom_widget_Social_Sharing_social-share-email_c7xxz_43"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-1743764513938":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-1743764513938","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_f95yq_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_f95yq_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_f95yq_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_f95yq_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_f95yq_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_f95yq_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_f95yq_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_f95yq_78.custom_widget_MicrosoftFooter_f-bare_f95yq_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_f95yq_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_f95yq_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_f95yq_78.custom_widget_MicrosoftFooter_f-bare_f95yq_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_f95yq_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_f95yq_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_f95yq_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_f95yq_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_f95yq_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_f95yq_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_f95yq_58","c-list":"custom_widget_MicrosoftFooter_c-list_f95yq_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_f95yq_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_f95yq_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1744145527415","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1744145527415","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Planner":{"__typename":"Category","id":"category:Planner","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:SQL-Server":{"__typename":"Category","id":"category:SQL-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:SMB":{"__typename":"Category","id":"category:SMB","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-endpoint-manager":{"__typename":"Category","id":"category:microsoft-endpoint-manager","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:1142985:1":{"__typename":"QueryVariables","id":"TopicReplyList:message:1142985:1","value":{"id":"message:1142985","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1744145527415","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Small and Medium Businesses","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","microsoft-learn":"Microsoft Learn","s-q-l-server":"SQL Server","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Planner","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune and Configuration Manager","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","outlook":"Outlook","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1744145527415","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1744145527415","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1744145527415","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1744145527415","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1744145527415","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1744145527415","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1744145527415","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1744145527415","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"Rank:rank:37":{"__typename":"Rank","id":"rank:37","position":18,"name":"Copper Contributor","color":"333333","icon":null,"rankStyle":"TEXT"},"User:user:1922738":{"__typename":"User","id":"user:1922738","uid":1922738,"login":"Rohan1405","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2023-07-03T10:11:08.482-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-3.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:1922738"},"ModerationData:moderation_data:3864463":{"__typename":"ModerationData","id":"moderation_data:3864463","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:3864463":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:1922738"},"id":"message:3864463","revisionNum":1,"uid":3864463,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:1142985"},"conversation":{"__ref":"Conversation:conversation:1142985"},"subject":"Re: Building installers for your Windows applications with Advanced Installer and Azure DevOps","moderationData":{"__ref":"ModerationData:moderation_data:3864463"},"body":"
I already have a msi package. I want to convert it to MSIX package using CI/CD. I have architect version of Advanced Installer. How can I achieve this?
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"153","kudosSumWeight":0,"repliesCount":0,"postTime":"2023-07-03T10:12:59.125-07:00","lastPublishTime":"2023-07-03T10:12:59.125-07:00","metrics":{"__typename":"MessageMetrics","views":5072},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:1142985/message:3864463","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"User:user:1095605":{"__typename":"User","id":"user:1095605","uid":1095605,"login":"Chethan_Venkat","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2021-07-04T23:53:56.637-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-12.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"entityType":"USER","eventPath":"community:gxcuf89792/user:1095605"},"ModerationData:moderation_data:2515337":{"__typename":"ModerationData","id":"moderation_data:2515337","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"BlogReplyMessage:message:2515337":{"__typename":"BlogReplyMessage","author":{"__ref":"User:user:1095605"},"id":"message:2515337","revisionNum":1,"uid":2515337,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"parent":{"__ref":"BlogTopicMessage:message:1142985"},"conversation":{"__ref":"Conversation:conversation:1142985"},"subject":"Re: Building installers for your Windows applications with Advanced Installer and Azure DevOps","moderationData":{"__ref":"ModerationData:moderation_data:2515337"},"body":"
Hi,
The article was very detail and infromative!!!
I am new to
In my case I need to deploy \".MSI\" package web application in Azure Devops Web app server in this scenario how can i deploy release pipeline. Please help me on this.
In my build release package I have below file system, when I deployed this package into azure web app server and browse it leads me into 'Server Error in '/' Application. page
'
****.msi
***.wixpdb
setup.exe
Thanks
Chethan
","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"218","kudosSumWeight":0,"repliesCount":0,"postTime":"2021-07-05T01:10:54.248-07:00","lastPublishTime":"2021-07-05T01:10:54.248-07:00","metrics":{"__typename":"MessageMetrics","views":16782},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"BLOG_REPLY","eventPath":"category:microsoft365/category:products-services/category:communities/community:gxcuf89792board:ModernWorkAppConsult/message:1142985/message:2515337","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1744145527415","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1744145527415","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1744145527415","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1744145527415","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1744145527415","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1744145527415","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1744145527415","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1744145527415","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1744145527415","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1744145527415","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1744145527415","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1744145527415","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1744145527415","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1744145527415","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1744145527415","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1744145527415","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1744145527415","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1744145527415","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1744145527415","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1744145527415":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1744145527415","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"modernworkappconsult","messageSubject":"building-installers-for-your-windows-applications-with-advanced-installer-and-az","messageId":"1142985"},"buildId":"HEhyUrv5OXNBIbfCLaOrw","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.1.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/external/components/ExternalComponent.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","../shared/client/components/common/List/UnstyledList/UnstyledList.tsx","./components/messages/MessageView/MessageView.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Amodernworkappconsult&entity.id=message%3A1142985","strategy":"afterInteractive"}]}