I’ve written a fair amount of code in my IT career and released a good number of Windows programs also, so a good tool to create Windows installer packages was always key. Each program would have a different set of needs, such as scripts, DLLs, security settings, etc., so one tool that could handle a complex set of requirements was necessary.
If you have the money or need tons of support, you can always go with InstallShield, the solid choice for many companies using Windows. We always used InstallShield in our early days as it came packaged with Visual Studio and Visual Foxpro.
However, it is not the only good software out there for creating Windows installers. In this article, I’m going to mention a couple of other free and paid (though much cheaper) utilities you can try out in your organization.
Nullsoft Scriptable Install System (NSIS)
If you love open source software, you may want to check out the Nullsoft Scriptable Install System (NSIS). NSIS is a professional system that you can use to create everything from very simple to very complex Windows installers. It’s small, yet has a large feature set, which makes it suitable for Internet distribution.
As you can tell by the name, NSIS is script-based, which allows you to create logic as complicated as you need to handle any situation. Luckily, for beginners, it also includes a bunch of plug-ins and pre-defined scripts to get you started.
Here is a short list of some of my favorite features of this MSI package creator:
- Ability to create Windows installers that can install, uninstall, set system settings, extract files, and more.
- NSIS has an overhead of only 34KB! It is by far the smallest Windows installer compared to InstallShield and Wise.
- One installer that is compatible with all major version of Windows from Windows 95 to Windows 10.
- Three compression methods (ZLib, BZip2, LZMA) to ensure the greatest compression for your installer packages.
- Script based installer is better than other programs that just generate a list of files and registry keys. Using the script language, you can perform many different installation tasks like upgrades, version checks, system reboots, modification of environment variables, access to Windows API and more.
- Create custom dialogs and interfaces to include user input, configuration options, and even a custom wizard interface.
- Extend the capabilities of NSIS with plug-ins that can communicate with the installer.
- Support for web installation and file patching across the Internet.
The program supports a tons of other features including installer self-verification using checksum, list and tree for component selection, silent mode for automated installations, full code editor for writing scripts, etc.
Advanced Installer
Advanced Installer also has a free version, but it also has several other versions that go up in price depending on how complex your installer needs to be. It’s updated very often and works extremely well.
If you’re looking for something more professional that also includes some options for support, then Advanced Installer is a good choice. If you want a feature breakdown between the five different versions they have, then check out the link. The free version actually has a lot of features and we were able to use that in our company for a long time because our installers were fairly simple.
One unique feature to Advanced Installer is Installer Analytics. It’s basically a set of tools to see how users install, use and uninstall your applications. You can easily see how large your user base is, load a survey when a user uninstalls the program, and get information about the user’s system and geographic location. All of this on a sleek and modern web interface that you can test yourself.
It also lets you easily repackage your applications into the new AppX format, which is required for the Universal Windows Platform. It doesn’t require any code changes and they have a free AppX converter tool. Those are just some of the unique features, but Advanced Installer pretty much covers all the bases. Check out the full list of features here for each edition.
Inno Setup
Inno Setup is an advanced Windows installer that is completely free and that has been around since 1997. It’s got a ton of features and works great for small businesses with moderately complex requirements.
Here is a list of some of the best features of Inno Setup:
- Supports all versions of Windows from Windows 2000 up to Windows 10
- Supports installation of 64-bit applications on 64-bit Windows
- Supports the creation of a single EXE file for easy file distribution
- Customizable setup types and full support for application uninstalls
- Creation of shortcuts, registry entries and INI files
- Supports silent installs and Pascal scripting engine for more advanced installs
- Third party extensions that enhance the features of Inno setup
Overall, this is a really good option since it’s completely free and very easy to use. It’s not going to be able to do what InstallShield or even Advanced Installer can do, but it covers pretty much all of the basics.
WIX Toolset
The WIX Toolset is a free set of tools for creating Windows installers that works with Visual Studio 2012 or higher. I mention it last because it requires the biggest learning curve. You can create some very complex installers with it, but you’ll be coding quite a bit and using a command line often.
WIX Toolset is based on the XML authoring model. If you don’t have Visual Studio, you can use the Wix tools or MSBuild. It supports building MSI, MSP, MSM, and MST installer files. It also supports a large number of Windows Installer features.
So those are some of the better known and stable programs you can use to create Windows installers. I’m sure there are many others out there, so feel free to let us know which one you use in the comments. Enjoy!
Related Posts
- The Best Free AI Courses to Boost Your Skills
- 6 Best Procreate Alternatives for Windows PC
- 5 Best Podcast Apps for Windows
- Best 10 Free PDF Editors for Windows
- 5 Best Audiobook Players for Windows
Quickly create an EXE installer for your program using the Inno Setup tool
MSI versus EXE installers
When distributing software for Windows, you have two main options for installers: MSI and EXE. An MSI installer is a
Windows Installer package that contains installation information and files. It uses the Windows Installer service. On
the other hand, an EXE installer is a self-extracting executable file containing the installation files and an
installation program. EXE installers are more customizable and do not depend on the built-in Windows Installer
technology.
This article will show how to create an EXE installer for a program using the Inno Setup tool.
Build your program
We will create a simple Hello World program using the Go programming language for this example.
With Go installed, we can build our program using the go build
command. For example, given the source code in
main.go
:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
We can build the program for Windows using:
GOOS=windows GOARCH=amd64 go build -o hello-world.exe main.go
Download and install Inno Setup
We will need to use a Windows machine to create an EXE installer.
Inno Setup is a free installer for Windows programs. You can download it from
the official website. Once you have downloaded the installer, run it and follow
the installation instructions.
Create an EXE installer
Launch the Inno Setup Compiler
application. The main window will appear, with a toolbar and a script editor.
On the Welcome modal, choose Create a new script file using the Script Wizard
and click OK
.
Follow the instructions on several subsequent screens.
On the Application Files
screen, add your program executable file and any other files, such as a README.
Continue following the instructions.
On the Compiler Settings
screen, select the file name for your installer.
Finally, click’ Finish’ after a couple more screens to generate the script.
Click Yes
to compile the script.
Click No
to save the script before compiling. If needed, it can be saved later.
The Inno Setup Compiler will create an EXE installer for your program and put it in the Documents/Output
folder.
You can try running the installer to make sure it works as expected.
Further reading
- In the past, we demonstrated how to code sign a Windows application
- Recently, we explained how to create a script-only macOS install package
Related Go articles
- How to measure Go test execution time and derive actionable insights
- Go benchmarks
Watch how to create an EXE installer
Note: If you want to comment on this article, please do so on the YouTube video.
It’s one thing to develop and test a Windows application; it’s quite another to bundle it up into a nice executable that installs correctly on all the different Windows versions that you need to support. I’d like to guide you through the process that I wish I had when I was creating my first installer.
Step 1 – Use your bare hands.
Start by taking your target directory (the one containing your compiled .exe
and a bunch of .dll
files) and plopping the whole thing onto a Windows machine. Then, manually install any prerequisites, like the particular version of the .NET framework that the app requires. It’s helpful to perform this step on an older platform that’s more likely to contain compatibility issues, e.g. Windows XP.
Now run the executable directly, and make sure it works. If there are problems, the machine may still be missing prerequisites. Double-check that the platform (x86 vs. x64) and .NET framework target of your build match up with the configuration of the machine you’re testing on. An installer won’t fix problems encountered here, so be sure to fix any issues before moving on.
Step 2 – Build it.
Next, we create an actual installer. Visual Studio lets us do this in two easy steps:
- Add a new “Visual Studio Installer/Setup Project” to your current solution.
- View the file system settings of the new project. Add a new Project Output to the Application Folder, and set it to be the Primary Output of your main project.
That alone is sufficient to build an MSI installer that will copy your project’s output onto the target machine. Other useful settings include adding shortcuts to the Start Menu/desktop, customizing registry settings, and configuring whether the installation applies to all users or not.
<p>Caveat: Visual Studio versions after 2010 seem to build MSIs that choke on Windows XP. No matter the configuration, my installer failed for me on XP with an “installation interrupted” message. The <a href=»http://stackoverflow.com/a/26039835″ style=»text-decoration: underline;»>unfortunate workaround</a> involves copying a dll from a Visual Studio 2010 installation over to the newer version’s directory.</p>
An alternative to Visual Studio is the highly configurable WiX Toolset. With WiX, you specify filenames, registry keys, and other installation information through XML. WiX’s candle
and light
tools then compile and link that information into an MSI file.
One difficulty I had was that WiX requires every file involved in the installation to be individually specified in the XML. It’s not possible to simply include the entire directory. This is by design. It is possible, however, to automatically generate the XML for a large number of files using another WiX tool called heat
.
Step 3 – Bundle it all together.
At this point, we have an MSI that installs our application. In order to have a seamless user experience, we need to bundle that installer along with all of its prerequisites. It’s not possible to add everything to a single MSI file, but with WiX we can write a bootstrapper that chains multiple installation packages together.
In Visual Studio, we can first install the “WiX Toolset” extension and then add a new project to our solution of type “Windows Installer XML/Bootstrapper Project”. Inside the new project, we need to add our chained packages to the auto-generated Bundle.wxs
file:
https://gist.github.com/benash/4ec9599c4f00e744f131
The easiest way to add installation items to our chain is to download the needed .msi
/.exe
files to our project and link to them statically. The downside of this approach is that the resulting bootstrapper may be enormous.
<p>Caveat: For some reason, Windows 7 requires .NET to be installed by enabling it as a “Windows feature”. Running a .NET MSI on Windows 7 will fail. To work around the issue, we can <a href=»http://stackoverflow.com/q/18126502″>enable the feature by using Wix to execute dism.exe</a>.</p>
Automatically downloading packages
The other option is to configure our bootstrapper to download and install its own packages. To do this, we need to define our own package group. WiX documents this element thoroughly, but here’s a summary of the information that we’ll need to add:
- the remote filename and download URL
- the hash and certificate details of the remote payload (This can be easily generated using the
heat
tool.) - when to install the package, e.g. for a 64-bit package, only if the machine is 64-bit
<p>If we need our bootstrapper to download and install .NET 4.0 or 4.5, we can save some work by using the <a href=»http://wixtoolset.org/documentation/manual/v3/customactions/wixnetfxextension.html» style=»text-decoration: underline;»>WixNetfxExtension</a>, which contains some predefined package groups. E.g. adding <code><PackageGroupRef Id="NetFx40Web"/></code> to our chain will bundle .NET 4.0.</p>
After some work, we might come up with this for .NET 2.0:
https://gist.github.com/benash/d5b49d71b0e264cfdcc2
В статье я хотел бы поделиться своим опытом написания инсталлятора для Windows с использованием инструмента Windows Installer XML Toolset (далее — Wix). К сожалению, несмотря на всю мощь данного инструмента, его использование сильно осложняется куцей документацией, старенькими кукбуками, вялыми ветками форумов и вытеснением .msi и .exe пакетов контейнеризацией. Однако, сегодня продолжают активно развиваться и создаваться программные продукты требующие развертывания на виндовой машине с использованием традицонных установочных пакетов.
Прежде, чем мы преступим к написанию инсталлятора нужно решить, что мы будем устанавливать. По большому счету, инструментарий Wix не ограничивает разработчика в технологиях на которых должен быть написан продукт, который будет развернут на машине пользователя. Главное условие, чтобы на машине пользователя была установлена соответствующая версия Windows с пакетами, необходимыми для запуска вашего продукта (кстати, wix позволяет в установочный пакет запихнуть в том числе и необходимые компоненты для настройки окружения, но об этом поговорим позже).
Для нашего инсталлятора предлагаю использовать дефолтный проект Blazor: с одной стороны нам не потребуется писать код устанавливаемого проекта, а с другой у нас будет достаточно высокий потенциал для костылизации, чтобы изучить возможности Wix toolset.
Теория
Прежде чем приступить к практической части предлагаю ускоренный ликбез по технологии Windows installer и wix toolset, что поможет читателю понять мотивы, которыми руководствуются команды разработчиков вставая на путь, вымощенный граблями.
Начнем с того, что Wix toolset – это набор инструментов, позволяющий создавать установочные пакеты Windows installer на основе .xml-описания, который включает в себя консольные утилиты, плагин для работы Visual Studio и Rider, несколько тем оформления инсталлятора (глобально они отличаются «глубиной» диалогов, определяющей свободу пользователя в процессе установки), а также средства создания бутстрапера (пожалуй, дословный перевод «установщик» в данном случае не особо применим).
Windows installer, в свою очередь, представляет собой подсистему Windows для развертывания программного обеспечения с использованием установочных пакетов .msi (Microsoft Installer). Не погружаясь в историю создания и эволюции данной подсистемы (кому интересно, можете поискать информацию о инсталляторе с кодовым названием Darwin) предлагаю сразу перейти к ее функционалу.
Так, ключевую ценность данной подсистемы представляет высокая гибкость процесса установки, обновления и удаления программ, что обеспечивается:
-
Возможностью отката на любом этапе установки включая апгрейд и удаление софта
-
Предоставлением доступа к работе с реестрами включая чтение и удаление записей
-
Гибкостью работы с правами доступа при установке софта
-
Обеспечением возможности кастомизации интерфейса установки, включая возможность добавления рекламы
-
Предоставлением доступа к ресурсам командной строки и возможности запуска скриптов на разных этапах работы инсталлятора
-
Наличием специализированного ПО, предоставляемого Microsoft для устранения проблем, возникших после запуска инсталляционного пакета с уязвимостью (например, если ошибка приводит к невозможности удаления установленного софта)
Сам инсталлятор представляет собой файл с расширением .msi внутри которого располагается реляционная база данных, описывающая логику установки программного обеспечения, а также хранит данные, необходимые для развертывания приложения. Для работы с инсталляционными пакетами вам потребуется установить Windows SDK. Основным инструментом для взаимодействия с файлами .msi является Orca – программа, позволяющая открывать, редактировать и создавать БД инсталляционных пакетов. Для ее установки вам потребуется перейти в директорию C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x86 после установки Windows SDK.
Давайте посмотрим на пример содержимого инсталляционного пакета, который мы с вами создадим с помощью WIX для проекта Blazor. Его содержимое выглядит так:
В приведенном примере инсталлятор содержит 35 таблиц. Это число не является фиксированным. Только Orca предлагает включение до 97 шаблонов таблиц, помимо которых можно создавать пользовательские.
Разберем по пунктам:
-
в колонке File хранится ID файла, который будет установлен в систему. Он выполняет роль первичного ключа для доступа и связывает сущности из таблицы MsiFileHash и Component
-
В Component_ лежит значение соответствующее полю KeyPath из таблицы Component, которое служит для реализации функционала, связанного с восстановлением и обновлением ПО средствами WindowsInstaller
-
В FileName хранится непосредственно имя файла
-
FileSize, Version и Language берутся из метаданных устанавливаемого файла
-
Atributes – свойства устанавливаемого файла, определяющие его доступность для пользователей, а также поведение при обновлении, восстановлении и удалении продукта. Подробнее можно ознакомиться по ссылке
-
Sequence определяет положение файла в инсталляторе и должен соответствовать его номеру в cabinet-файле.
Если, вы еще не сильно утомились сухой теорией, то давайте посмотрим еще на одну ключевую таблицу – Component:
В этой таблице описаны компоненты: .
-
В колонке Component лежит название компонента, которое должно быть уникальным. Оно может быть создано как разработчиком, так и средствами автоматизации. Главное, что с помощью этого значения компонент связывается с файлом, который будет в него завернут.
-
ComponentId – GUID, который должен быть сгенерирован для каждого компонента. Фактически это первичный ключ в таблице компонентов.
-
Колонка Directory_ связывает компонент с виртуальной директорией, которая будет ассоциирована с местом установки конкретного компонента.
Думаю, на этом кратенький рассказ о внутреннем устройстве базы данных пакета .msi можно закончить. Конечно, кроме файлов, компонентов и папок, база данных инсталлятора включает описание опций (feature), действий (action), UI и пр. При наличии интереса у читателей, готов подготовить более подробный обзор структуры .msi пакетов.
Практика
Для того, чтобы упростить разработку инсталляционных пакетов и облегчить дальнейшую поддержку были разработаны различные инструменты, позволяющие визуализировать и автоматизировать некоторые рутинные процессы. К таким продуктам, например, относятся InstallShield, InnoSetup (не позволяет создавать .msi-файлы — только .exe) и AdvancedInstaller. Несмотря на удобство использования, данные продукты являются платными (стоимость некоторых продуктов довольно кусачая за исключением Inno Setup — он бесплатный), не имеют открытых репозиториев или создают сложности при корпоративной разработке при мерже проектов. Поэтому наиболее очевидным выбором для большинства интерпрайз-проектов является использование The Windows Installer XML (WiX) toolset.
Для начала работы с этим инструментом вам необходимо произвести его установку. Перейдите по ссылке и скачайте и установите WiX Toolset build tools и WiX Toolset Visual Studio Extension (в соответствии с используемой вами версией Visual Studio). Также, есть расширение для Rider – его можно найти в маркете IDE.
После установки компонентов Wix предлагаю перейти в Visual Studio и приступить к созданию проекта Blazor для которого мы будем писать инсталлятор.
Создадим проект Blazor Wasm и опубликуем его
File -> New Project -> Blazor WebAssambly App. Назовем проект BlazorAppForInstaller.
На следующем шаге обязательно поставьте галочку ASP.NET Core hosted и выберите .Net 6.0.
После того как проект был создан опубликуем его:
Щелкнуть правой кнопкой мыши по BlazorAppForInstaller.Server -> Publish -> Target: Folder -> Finish.
Проект должен быть опубликован в указанную вами папку (в моем случае, это ~\BlazorAppForInstaller\Server\bin\Release\net6.0\publish\): содержимое этой директории мы и будем упаковывать в инсталлятор.
Создадим проект Wix InstallerForBlazorApp
Щелкнуть правой кнопкой мыши по названию решения Add -> New project
В поиске вбиваем Wix
В результатах поиска выбираем Setup Project for Wix v3 и нажимаем Next
В поле Project name вводим названием. В моем случае это InstallerForBlazorApp. Щелкаем по кнопке Create.
Настройка проекта
Для сборки инсталлятора необходимо описать компоненты (то есть файлы установки).
Если бы мы имели дело с простым проектом, состоящим из десятка файла, то вполне допустимо их описать вручную. Однако, когда речь заходит о суровой интерпрайз разработке или просто о больших проектах, включающих кучу файлов (особенно это касается веба) довольно сложно (а зачастую невозможно) становится следить за добавлением или удалением файлов. Именно поэтому, мы воспользуемся консольной утилитой Harvest Tool (heat.exe), который можно найти в директории ~/WiX Toolset v3.11\bin (по умолчанию, должна быть создана при установке в C:/Program Files (x86)). Подробно ознакомиться с возможностями Heat.exe можно в официальной документации https://wixtoolset.org/documentation/manual/v3/overview/heat.html
Я предлагаю сделать запуск heat.exe частью сборки проекта, чтобы сэкономить силы в процессе разработки – благо проекты Wix позволяют интегрировать генерацию описания непосредственно в файл проекта .wixproj.
Щелкаем правой кнопкой мыши по проекту инсталлятора -> Add Reference — открываем папку, в которую был установлен WiX, подкаталог bin, файл WixUtilExtension.dll
С использованием любого текстового редактора откройте файл InstallerForBlazorApp.wixproj и вставьте следующий кусок кода перед закрывающимся тегом </Project>
<Target Name="BeforeBuild">
<PropertyGroup>
<DefineConstants>
BasePath=..\..\BlazorAppForInstaller\BlazorAppForInstaller\Server\bin\Release\net6.0\publish;
</DefineConstants>
</PropertyGroup>
<!--This code generates the ComponentsGeneration.wxs
which describes the components to include into the installer.-->
<HeatDirectory
OutputFile="ComponentsGenerated.wxs"
DirectoryRefId="INSTALLFOLDER"
ComponentGroupName="PublishedComponents"
SuppressCom="true"
Directory="..\..\BlazorAppForInstaller\BlazorAppForInstaller\Server\bin\Release\net6.0\publ ish"
SuppressFragments="true"
SuppressRegistry="true"
SuppressRootDirectory="true"
AutoGenerateGuids="false"
GenerateGuidsNow="true"
ToolPath="$(WixToolPath)"
PreprocessorVariable="var.BasePath"
RunAsSeparateProcess="$(RunWixToolsOutOfProc)" />
</Target>
Как вы видите, код помещен внутрь тега <Target Name=”BeforeBuild”>
описывающий действия, которые должны быть выполнены непосредственно перед сборкой инсталлятора. К таким действиям относится объявление констант препроцессора, к которым можно будет обращаться до этапа сборки проекта. Так, переменная (да, это константа, но нейминг Wix периодически противоречит самому себе) BasePath используется для обозначения пути проекта, который будет упакован в инсталлятор. Настоятельно рекомендую использовать относительные пути настолько насколько это возможно.
Далее, с помощью тега <Heat> и его свойств мы вызываем утилиту Heat.exe и передаем ей необходимые аргументы:
-
OutputFile="ComponentsGenerated.wxs"
– путь до файла, в котором хранятся компоненты для установки -
DirectoryRefId="INSTALLFOLDER"
– ссылка на папку в которую будет произведена установка приложения (по сути это переменная в которую будет записан путь до директории установки) -
ComponentGroupName="PublishedComponents"
– наименование группы компонентов, которые были сгенерированы. Используется как алиас для множества компонентов и является абстракцией, существующей исключительно в рамках проект Wix. Когда инсталлятор будет скомпилирован, то в таблицах .msi файла вы не найдете сущности соответствующей группе компонентов -
AutoGenerateGuids="false"
иGenerateGuidsNow="true"
– настройка генерирации GUID для компонентов в момент вызова утилиты Heat. Такая конфигурация заставляет Heat создать для каждого компонента уникальный GUID в момент запуска таски, т.е. на этапе сборки проекта. Такой подход минимизирует количество ошибок, возникающих при компиляции проекта Wix. -
ToolPath="$(WixToolPath)"
– путь до директории с установленным Wix Toolset. Рекомендую использовать переменную окружения WixToolPath, которая создается при установке Wix. По большому счету, прописывать вручную путь придется только в том случае, если вы планируете использовать Wix toolset без установки через стандартный инсталлятор. -
PreprocessorVariable="var.BasePath"
– переменная препроцессора, которая используется в качестве части пути (указывает на директорию) до файла-компонента. Мы ее объявили внутри тега<DefineConstants>
-
RunAsSeparateProcess="$(RunWixToolsOutOfProc)"
– обязательно указывайте этот атрибут, если работаете в Visual Studio 2022 и собираете 64-битный проект. В противном случае Visual Studio будет закрываться при каждой попытке построить проект. Эту проблему обсуждали здесь -
SuppressRootDirectory="true"
– необходим для избежания дублирования родительских папок компонента. -
SuppressCom="true", SuppressFragments="true"
иSuppressRegistry="true"
– несмотря на то, что очень не велика вероятность, что в вашем проекте окажутся COM объекты, файлы реестров и фрагменты установщика лежащие в одной папке с основным проектом, рекомендуется дополнительно запретить включать такие файлы в процесс создания описания компонентов из-за высокой вероятности возникновения ошибок. Если же, у вас есть необходимость включения таких файлов в проект инсталлятора, рекомендуется добавить отдельное описание таких компонентов.
После внесенных изменений InstallerForBlazorApp.wixproj должен выглядеть так
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>6f99cf2a-a8d3-4f08-a4e1-cd86ea9c9785</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>InstallerForBlazorApp</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="ComponentsGenerated.wxs" />
<Compile Include="IISConfiguration.wxs" />
<Compile Include="Product.wxs" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUtilExtension">
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
<WixExtension Include="WixUIExtension">
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
<WixExtension Include="WixIIsExtension">
<HintPath>$(WixExtDir)\WixIIsExtension.dll</HintPath>
<Name>WixIIsExtension</Name>
</WixExtension>
</ItemGroup>
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
</Target>
<Target Name="BeforeBuild">
<PropertyGroup>
<DefineConstants>
BasePath=..\..\BlazorAppForInstaller\BlazorAppForInstaller\Server\bin\Release\net6.0\publish;
</DefineConstants>
</PropertyGroup>
<!--This code generates the ComponentsGeneration.wxs
which describes the components to include into the installer.-->
<HeatDirectory OutputFile="ComponentsGenerated.wxs" DirectoryRefId="INSTALLFOLDER" ComponentGroupName="PublishedComponents" SuppressCom="true" Directory="..\..\BlazorAppForInstaller\BlazorAppForInstaller\Server\bin\Release\net6.0\publish" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" AutoGenerateGuids="false" GenerateGuidsNow="true" ToolPath="$(WixToolPath)" PreprocessorVariable="var.BasePath" RunAsSeparateProcess="$(RunWixToolsOutOfProc)" />
</Target>
</Project>
После того, как вы внесете указанные изменения в файл .wixproj сохраните изменения и постройте проект. В результате, в корневой папке проекта инсталлятора должен появиться файл ComponentsGenerated.wxs.
В моем случае ComponentGenerated.wxs имеет следующее содержание
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="cmpA0863526952F7834E7C922F065E4C8A8" Guid="{4F47DA2F-E8FD-4B92-AE61-FFE9CA68BF7F}">
<File Id="filC04B02D0CCC2D5CCC1013B35DE86DB29" KeyPath="yes" Source="$(var.BasePath)\appsettings.Development.json" />
</Component>
<Component Id="cmpF82FCA80BBAF44D285C97F10993DEEE6" Guid="{EE55FE38-515B-444C-9496-6BA0FE9F8550}">
<File Id="fil840B80AC19861C7F9F04FBDCFAE331CE" KeyPath="yes" Source="$(var.BasePath)\appsettings.json" />
</Component>
<Component Id="cmp80A32365AE3ACFE27BDD385AE91DCE74" Guid="{2234C1AC-AB8D-460E-BBF1-F982BBE28426}">
<File Id="filA65D0C2EEDE361CBA6DAA5414A5885D6" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Client.dll" />
</Component>
<Component Id="cmpF69BDBE9F42451436A0B8C022F6D4636" Guid="{291B8DF2-FC5A-4C41-94A8-2100BC13DA52}">
<File Id="filEF7A1D8322B02801B5E1FF05C1E9C211" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Client.pdb" />
</Component>
<Component Id="cmpFD59DF07063AC308C40670A4B81A9B57" Guid="{73AF0D36-0704-4458-933B-F8A412BEAF16}">
<File Id="filEC516099676B2B686B154C6BDD632062" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Server.deps.json" />
</Component>
<Component Id="cmpECDF00A9B659260C50885BEEADBCABC0" Guid="{3F5F5E68-208A-4A84-85EC-4C8F3F003760}">
<File Id="filB052CB4639CA4C158F4D9FE686DB740A" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Server.dll" />
</Component>
<Component Id="cmpE351BCDC42EF493685CEF4080E08E51E" Guid="{84BD7DDE-6020-40F9-986B-983174E660F6}">
<File Id="fil04C3A476D538A356A55E0061D96C252E" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Server.exe" />
</Component>
<Component Id="cmp651C3999A00B5D89ACAE2D3A9BE7F91D" Guid="{C497D355-3BD7-45B6-AF99-71F10F687F19}">
<File Id="fil5845A2249FFDBB31724899C28857297E" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Server.pdb" />
</Component>
<Component Id="cmpBCBFD41B8B964007BA9BF340925C6493" Guid="{0AB26848-8B77-49A8-AB82-F6F490C9EB3A}">
<File Id="fil7883E94C175B382DAE68D2E730B7F18F" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Server.runtimeconfig.json" />
</Component>
<Component Id="cmp9A7CD58BE639399F7BDAA987492B6E65" Guid="{840E5F4F-940A-42F4-ABAB-756DA9EEA9A7}">
<File Id="filC2AF92E94531E79C884299478E78AB02" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Shared.dll" />
</Component>
<Component Id="cmpB818026BC106A80C4FD6E90BF8F06CDA" Guid="{6B873FB2-A32E-4AAD-8072-5B6A9B5671D7}">
<File Id="fil6E77B3E6819A87A3819FFDB52DC2AB74" KeyPath="yes" Source="$(var.BasePath)\BlazorAppForInstaller.Shared.pdb" />
</Component>
<Component Id="cmp2F0A313AE6306F9CE5E760AF214DC789" Guid="{9BCD7498-EBD2-460F-A033-6BD934E21DDB}">
<File Id="fil274A60BD8B17A2DA6C1EB35AEA850F12" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Authorization.dll" />
</Component>
<Component Id="cmp6D6CC90C40E2F632C9128346BA7F188F" Guid="{F0EBBBD6-25A4-4A14-A6A9-3B09FCF616B7}">
<File Id="filB3A561B406C5673062D93CEAB4C5FBA3" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Components.dll" />
</Component>
<Component Id="cmpA76C6CFFA9DCB201D0EEDB226B0B9E25" Guid="{EE7A5E70-7B9D-4E30-98B8-B39E077D585D}">
<File Id="fil509B74670E6E3BBFDDC3F98EFB8E8C1D" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Components.Forms.dll" />
</Component>
<Component Id="cmp17959BADF0C2D7B7AB4867F09DA031B8" Guid="{6A5C8273-F71E-43FC-8896-84DD02259470}">
<File Id="filBCB8CB727FBD0C042A3E896A50A0013A" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Components.Web.dll" />
</Component>
<Component Id="cmpDF4C205418A6D7FE6FEA71F3B8998FAC" Guid="{8AB6FEF4-5925-4C12-B9F4-2A82C8430CDF}">
<File Id="filC4C0674046FF1CB3C507EAB882BF2E34" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Components.WebAssembly.dll" />
</Component>
<Component Id="cmpDA8B0BBD16E996DE615D6861DBA6442F" Guid="{B1A2B290-F7A5-4BEA-98D6-FA1540E5AF7B}">
<File Id="fil05438E5B6FC074FE194163CB964F6591" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Components.WebAssembly.Server.dll" />
</Component>
<Component Id="cmp3D2A78302A6149F7464B0EDCD758BCCF" Guid="{D621ED15-E9E3-4BCE-A1F2-226AAF54F6D6}">
<File Id="fil448E35B6B4567F45DB8A9C0D588396AC" KeyPath="yes" Source="$(var.BasePath)\Microsoft.AspNetCore.Metadata.dll" />
</Component>
<Component Id="cmp8C674FD6A69988A60A77A4CEE0F53781" Guid="{F9FCFE30-E9F4-4434-A516-D49A5955838C}">
<File Id="fil72342637E9F74EE945317D4603CEBA2F" KeyPath="yes" Source="$(var.BasePath)\Microsoft.Extensions.Logging.Abstractions.dll" />
</Component>
<Component Id="cmpDB4717CBBFD23A9652DB5B136ABB5D75" Guid="{BF3D8181-57C3-4615-A65A-A356F9749FF0}">
<File Id="filD208251EAF74D3D9FCA9A0D020CF9631" KeyPath="yes" Source="$(var.BasePath)\Microsoft.JSInterop.dll" />
</Component>
<Component Id="cmpCF0F711637230B4D1AE41109C02C9142" Guid="{334AADF3-2C4A-43A3-AA3E-C3063F65C57E}">
<File Id="fil5E6F1BBD1CE0D66ADA7274CC42146536" KeyPath="yes" Source="$(var.BasePath)\Microsoft.JSInterop.WebAssembly.dll" />
</Component>
<Component Id="cmpF88B96E5973E0D28B511DC6371DB06E0" Guid="{0DAA8109-C0F5-47A0-8DC9-FCAAEB8CCC90}">
<File Id="filA72770FDC08B6447ABAA326398A3C786" KeyPath="yes" Source="$(var.BasePath)\System.IO.Pipelines.dll" />
</Component>
<Component Id="cmpB139B49DF4DF8F44C525B449EA8187F7" Guid="{DAD0B80D-AD5E-454B-82EF-1BC3456FB55A}">
<File Id="filE7A3E65CC622C2E3B9B57707B12C9645" KeyPath="yes" Source="$(var.BasePath)\web.config" />
</Component>
<Directory Id="dirFF7B98771B91AAE585FE52B7EFB34AF9" Name="BlazorDebugProxy">
<Component Id="cmp5B65C45828B950384B8C5C76AB9F6EF0" Guid="{6242E71D-EA64-4F79-A3AA-C661D442FD18}">
<File Id="fil0EF0F550322CD17C7C714E44E83269EA" KeyPath="yes" Source="$(var.BasePath)\BlazorDebugProxy\BrowserDebugHost.dll" />
</Component>
<Component Id="cmp5A9228A102598245A49CC73E4B42BFFD" Guid="{F6BA6C92-A950-4E24-8C85-448E2CA02DBE}">
<File Id="filD8595B9CBE5DD5D704F01D48491D318A" KeyPath="yes" Source="$(var.BasePath)\BlazorDebugProxy\BrowserDebugHost.runtimeconfig.json" />
</Component>
<Component Id="cmp0B11C97F8D96134C5A582DAA9D362721" Guid="{CB376EF4-2F26-4D88-A4FA-C8BF3B2C8D1D}">
<File Id="fil4E80FEBEAB64C6B7394572A11AEE0A1A" KeyPath="yes" Source="$(var.BasePath)\BlazorDebugProxy\BrowserDebugProxy.dll" />
</Component>
<Component Id="cmp22B9B089D6F03FEB02531ECB35C82F8E" Guid="{374B5BC6-6408-49D3-8127-8B5B104DA628}">
<File Id="fil6055CEB7DE0EF0D0757B75192036CECF" KeyPath="yes" Source="$(var.BasePath)\BlazorDebugProxy\Microsoft.CodeAnalysis.CSharp.dll" />
</Component>
<Component Id="cmp958171B03EC06C56FB11A52D468E5F57" Guid="{CCD5CB55-0760-46EE-9593-7479EE86EDF2}">
<File Id="filBE547A9559A6D9185621EABC8B529677" KeyPath="yes" Source="$(var.BasePath)\BlazorDebugProxy\Microsoft.CodeAnalysis.dll" />
</Component>
<Component Id="cmpB322B77CE8D40EBAD199D45D0E4F25F0" Guid="{D6CBA61F-4366-482A-B4CA-17E1A68792AD}">
<File Id="fil28DEDB3F6C20AB880B95B684491580B0" KeyPath="yes" Source="$(var.BasePath)\BlazorDebugProxy\Newtonsoft.Json.dll" />
</Component>
</Directory>
<Directory Id="dir3D83A529A2122889D4016E7D784625D5" Name="wwwroot">
<Component Id="cmp920020A0D51F9A626EB2143066649049" Guid="{65310CAD-54CE-4F8D-B0BD-0C8FFA12A329}">
<File Id="fil5625CD1F0A436AA0C9E8667328891D3A" KeyPath="yes" Source="$(var.BasePath)\wwwroot\BlazorAppForInstaller.Client.styles.css" />
</Component>
<Component Id="cmp6A573805E6F545A7F37C18527646950E" Guid="{67E7C809-BA29-46FC-8ABD-30692E02416D}">
<File Id="fil4340641EF92B44F5306114E3F1D36462" KeyPath="yes" Source="$(var.BasePath)\wwwroot\favicon.ico" />
</Component>
<Component Id="cmp0D2F1CB83AD7A688791EFF1B2407B5F1" Guid="{5C4C24DA-9BBB-4450-A57B-A5B764EF18C9}">
<File Id="filF5852E3A1C173CD4B7AA5BB8D1B19C16" KeyPath="yes" Source="$(var.BasePath)\wwwroot\icon-192.png" />
</Component>
<Component Id="cmp8D45D052C68877B0B807B3D45E104FF6" Guid="{6B02277E-69C6-4C6E-B7E0-6F03E23B7467}">
<File Id="fil658EB15BA5D7E0782137791A613E6C55" KeyPath="yes" Source="$(var.BasePath)\wwwroot\icon-512.png" />
</Component>
<Component Id="cmpD91242D38C41E4403B7679B93F1EEBB4" Guid="{1F0FB915-48FF-46AA-9594-8D5A8D143EA6}">
<File Id="filA9C65401D86C7CFD07B966A29B9D89E3" KeyPath="yes" Source="$(var.BasePath)\wwwroot\index.html" />
</Component>
<Component Id="cmpCB80CFC92D7C1BB2787B948E67B42B03" Guid="{ACD6D7A5-4812-4E23-B943-8D2D391B1CBE}">
<File Id="fil580253134E9F2BB1D7BA130533DE8F04" KeyPath="yes" Source="$(var.BasePath)\wwwroot\manifest.json" />
</Component>
<Component Id="cmpBCCB7ADB11BD8E995C2D17B5FDFD7CA8" Guid="{FEA4589A-C26E-4A79-BF72-FA2F9E890FAA}">
<File Id="filD26912E52648D14E5D4A954D5F256FA5" KeyPath="yes" Source="$(var.BasePath)\wwwroot\service-worker-assets.js" />
</Component>
<Component Id="cmp6300BF95DDDCF98EC047B2991C2BA653" Guid="{D22568BE-81DB-4AB3-902A-B996812E427A}">
<File Id="fil54651357683F72D9500F5998771EB4DD" KeyPath="yes" Source="$(var.BasePath)\wwwroot\service-worker.js" />
</Component>
<Directory Id="dirED733C34DE106D43E47F9049837C7E99" Name="css">
<Component Id="cmp087AEDA3ECF7BE8C1137AADA0E56E0A6" Guid="{E1B47808-2714-4CD6-9862-8D6ECC4BC085}">
<File Id="filD9477D05D41C78519460D2E399A53D86" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\app.css" />
</Component>
<Directory Id="dir578587A376B13655DF93D8D190D09E38" Name="bootstrap">
<Component Id="cmpEBA035EA7685839B21FA1B833C2D781C" Guid="{BD4B431E-4265-459E-85E2-B1FB800041F3}">
<File Id="fil9246F4C21320DCC254AAEC2B6CA201E8" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\bootstrap\bootstrap.min.css" />
</Component>
<Component Id="cmp87BF3E7D495DC9B53F7ED2A371F1FE92" Guid="{42C20875-5B4E-4020-B569-6F162FF7502E}">
<File Id="fil706E0FE7B70A4FE22131C3ECDCC2220D" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\bootstrap\bootstrap.min.css.map" />
</Component>
</Directory>
<Directory Id="dir4AA45E3B956024607D9673C62D4A5EC7" Name="open-iconic">
<Component Id="cmp2220CCF66448F1A862D1353191CE69F5" Guid="{F39CDA89-87A8-4358-9C64-A31535B9FD00}">
<File Id="fil69CA8DBC716DB349E38835E0E4376776" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\FONT-LICENSE" />
</Component>
<Component Id="cmp791F5746D6F2AC68E2E8A50343B869F7" Guid="{177623EB-7AC3-499E-9AFE-A801224F322D}">
<File Id="filAA56F33B7267915E17B9C07E35B9B3B1" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\ICON-LICENSE" />
</Component>
<Component Id="cmp3DA139ADE5BC562B564DECE23AFFD8D0" Guid="{18E7BE1D-0F79-49F7-882A-B33029F7D041}">
<File Id="fil0A55830EEB5C8115A1BC74E41C184141" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\README.md" />
</Component>
<Directory Id="dir71E214D0555C176F3B3EB73000355FD6" Name="font">
<Directory Id="dirD56BE8D7B4920E710730E8C5A7AA202D" Name="css">
<Component Id="cmp3F52B8D89D587889C8A65D69E74B5F51" Guid="{E1FA7A7E-636C-4A1F-B198-15C7DB660AB8}">
<File Id="fil94C1662E6A729DBD5920B971BE85A743" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\font\css\open-iconic-bootstrap.min.css" />
</Component>
</Directory>
<Directory Id="dirE412B34DB4EE4DFCC5824E0F7C902C7E" Name="fonts">
<Component Id="cmp102AA2B65E2F7CFDBE0F937F8D225168" Guid="{61583E56-78F9-4899-B414-16CF55BA7613}">
<File Id="fil164917E73009BFF1140888BA7311A83E" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\font\fonts\open-iconic.eot" />
</Component>
<Component Id="cmp022B66C05DEF11B72F5542F7A563B670" Guid="{13CE3EBF-5709-4E53-A16E-AD8D594269B6}">
<File Id="fil359A08138CF8104E01BEDDFBCF601539" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\font\fonts\open-iconic.otf" />
</Component>
<Component Id="cmp0F72C70E7993CC0B3E9FF70ED40066D9" Guid="{50A1B8A9-FC5F-4DBF-A5B9-23BF36B86461}">
<File Id="fil58F851EE53BB2984EF8AD39C75D6ED2B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\font\fonts\open-iconic.svg" />
</Component>
<Component Id="cmpFA0036474721DE0D4163E05499F39951" Guid="{48316E0E-AFCD-42C8-81DB-2BFA5B78098D}">
<File Id="filE8C22BD61F80DDEF89A090F2D3088910" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\font\fonts\open-iconic.ttf" />
</Component>
<Component Id="cmpB5AF9E63913432C07629EC20330320A3" Guid="{AA08AEF0-1074-4798-A594-3D2336A888D0}">
<File Id="fil6C6239428714D4469CE9DC4AC970572B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\css\open-iconic\font\fonts\open-iconic.woff" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Directory Id="dir2456A1A1C6D6186A96473C7CCDFCB992" Name="_framework">
<Component Id="cmp9D66267AB1CAF7A98DFC42947DC635D4" Guid="{5001E34B-2EE7-405B-AB2E-3796E0A80C0F}">
<File Id="filB44D114325A011114C21CBE4A300CB0A" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\blazor.boot.json" />
</Component>
<Component Id="cmpCD4F94EB73F3962B42308170454B4366" Guid="{94C7954D-AE32-4F74-B486-EDED35A5DCD9}">
<File Id="fil95D8DA1D1C8714B25ACFD17A854A6556" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\blazor.boot.json.br" />
</Component>
<Component Id="cmp6D7DA841FD268735AFB1026BA6AE24A3" Guid="{2693A4A8-6008-41AD-A7F7-1BA66EBF6C79}">
<File Id="filE6753DF182773CBE5CB34EFF14F104A1" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\blazor.boot.json.gz" />
</Component>
<Component Id="cmp08111D788677D8B8150650EE58FB5962" Guid="{CEDA9984-84D1-451F-ABDE-626A8C59F7C5}">
<File Id="fil91C23D13B8DAFF05EBEB8392CE68B52A" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\blazor.webassembly.js" />
</Component>
<Component Id="cmp5A46DA40AED3B5E10AF9751BA0029C2C" Guid="{2D3F6029-21F3-4303-87BF-57533CA6DD32}">
<File Id="fil8B39D85752BD54316DA226C75F3327CD" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\blazor.webassembly.js.br" />
</Component>
<Component Id="cmp6A6C2351815759B4DB8982A7741D0ABA" Guid="{9DFD3F7F-C3B3-467F-B20A-BC93AB02E79F}">
<File Id="fil19B6F698DFFF12083A98F5D787FD0C27" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\blazor.webassembly.js.gz" />
</Component>
<Component Id="cmp82623C6CA3D1FE2B38C69748720D46CB" Guid="{F1498C70-7946-48C6-B0B5-D0D9AAE667F9}">
<File Id="fil08BC13C8E449CA8F8A63459958299CC2" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Client.dll" />
</Component>
<Component Id="cmp2EAADFED8A771ED40D36F4261011FC42" Guid="{CBB22CE6-A9AB-4AAA-8C7A-8DF7E75097C5}">
<File Id="fil8BFAA357E90079ABABE1BCF4BA473A95" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Client.dll.br" />
</Component>
<Component Id="cmp0C35E5441CB1AEE868B0841FC2B3727D" Guid="{88347808-0D45-4D45-8481-38208053A58F}">
<File Id="filA93D1C70A69655AA4C51B3783DEF7929" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Client.dll.gz" />
</Component>
<Component Id="cmpF7B971FD5EDDB748109439252E62DBB2" Guid="{27F9F764-1382-4933-9E5A-5DD08B7D16C0}">
<File Id="filEBF0235031F25983E7C1A9288636FA06" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Client.pdb.gz" />
</Component>
<Component Id="cmp1A38450971536177F12598D9DA69460B" Guid="{A75C8817-B1F6-4DA9-9900-B40F240C5DC1}">
<File Id="filBB8B83E5A719B33BDFBE76BD743CCF89" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Shared.dll" />
</Component>
<Component Id="cmpB3C98B1AF19712A5A4C90299621D5AA3" Guid="{96975A6F-A077-4100-B12E-1DD3399CCB5A}">
<File Id="filEB014231B74E00067909368905F30EE7" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Shared.dll.br" />
</Component>
<Component Id="cmpB532E6FD17B9FD1DDEF930DAB1CDCC8C" Guid="{C682083C-EBDE-4A5F-B609-AAED3ADD024F}">
<File Id="fil5E81E1CB0A6DE77CBC8370A61E06C38B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Shared.dll.gz" />
</Component>
<Component Id="cmp930FCEACB08C3F828E26B2B4AAAD3B58" Guid="{F87DB6C4-DE5E-4274-8DC5-E93C92AE35BB}">
<File Id="filF270CDA0AFA589A3714231A594BCD5FB" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\BlazorAppForInstaller.Shared.pdb.gz" />
</Component>
<Component Id="cmp94D35364CD546AECFF1FD3E16E7705BC" Guid="{2E38C9A8-06D4-4A9E-A090-C47083799C8B}">
<File Id="fil0170682B3A5D149D65261C93955427C3" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.6.0.4.33aaebng0v.js" />
</Component>
<Component Id="cmpEEB478F290FD8E012F256864DA59B87A" Guid="{9D6ADBA3-2C2B-40A3-AD1C-A622C796B35B}">
<File Id="fil4BFFAB0897DDFF6616372F10D397F4C5" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.6.0.4.33aaebng0v.js.br" />
</Component>
<Component Id="cmpABBCFC94814B14153BE6A9A7989C2A0A" Guid="{921EBFCE-279F-4146-A223-6AC7A86B82B3}">
<File Id="filC837371EBEBB4A85095F62968F246518" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.6.0.4.33aaebng0v.js.gz" />
</Component>
<Component Id="cmpF242BF7465335E363684D1995205E1BD" Guid="{7238E4CE-E418-4603-AB1F-2C5064257911}">
<File Id="fil100971A9827D4A995FD58C69132C7F78" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.timezones.blat" />
</Component>
<Component Id="cmp02E6C2F0AD10D0478D86BE37452B0914" Guid="{256ED6AB-05AB-4201-9B25-CC374E7AC3E2}">
<File Id="fil349A7A48CB5B0B3B0DBE9F8FDB0E73A3" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.timezones.blat.br" />
</Component>
<Component Id="cmp4A0D7430E5062327165BBC0627BB2583" Guid="{979FCAC9-D8EE-44AB-9B0C-850E5D1BEBAF}">
<File Id="fil0886807D84E5ADBFAE7CA9BEC8FFA851" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.timezones.blat.gz" />
</Component>
<Component Id="cmp39219EB53A18F9EF8C1D9E629B44B00E" Guid="{22B4717D-5557-4F1B-971F-23FE4E288EA6}">
<File Id="fil68C7BC2EE4C13DECCA9E6FB9D7C824A9" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.wasm" />
</Component>
<Component Id="cmpA1E64C6DD02D1B8D3365CDF712DE7740" Guid="{B626E6DB-2D54-4452-A1A4-6F3E26C040CB}">
<File Id="fil2A596AD93D719FC8D9587E4071ADD444" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.wasm.br" />
</Component>
<Component Id="cmp2F00835F6AB457CB0746B0CF23BBABC4" Guid="{B58C9A4C-87F2-4854-AAC7-6D2872E24C9E}">
<File Id="fil9EFAF48DDA876292454A09D0ABB854E5" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\dotnet.wasm.gz" />
</Component>
<Component Id="cmp728A6879EC0D4538CF0D9A610CDB29AB" Guid="{73825831-1C6F-4309-BD38-DA71EB9D08C7}">
<File Id="filA6E451B0F223EACAE5E0D5C4634C5F3D" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt.dat" />
</Component>
<Component Id="cmpCF6F10CA4A3650B98898E76461DBDB47" Guid="{3116E39D-5666-4B49-A07C-C3DFEB00431E}">
<File Id="filD2CE1A50BBA0A22996BE87C71FB6B412" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt.dat.br" />
</Component>
<Component Id="cmp512FC92BCC546D0A442E2A50E378BA60" Guid="{D815DB8F-3108-4B6B-8233-C0E9DB54359D}">
<File Id="fil18707646D8908FCB093B7109B82D706C" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt.dat.gz" />
</Component>
<Component Id="cmpA8FCAF75866687FC4A4693E426913FBA" Guid="{EBBDA200-5E60-41F6-8A34-8237385C2BE1}">
<File Id="fil9BDA85D8F75E1651CAC2432153EB4836" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_CJK.dat" />
</Component>
<Component Id="cmp747FF5C347AA12FFF91DF70F289BC1F7" Guid="{0F1FF7D6-ECFF-4321-9AD2-5B7B078BCE6D}">
<File Id="filCD2D30AC48BC4F5A8FE9379F4D69A5EF" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_CJK.dat.br" />
</Component>
<Component Id="cmpDEF19AE67395660D7A04537C771DEAEA" Guid="{E02B6461-7A78-4680-8E25-5992D1ADAC3C}">
<File Id="fil1D562F69200614371432FB36A61CF636" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_CJK.dat.gz" />
</Component>
<Component Id="cmp286486FA354377E5944B31BCB5E1BD86" Guid="{38D93EA2-EDE3-49FB-977A-B8AC290C63BF}">
<File Id="filC6F93228041B4AC1C5D2CB9DAD61425C" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_EFIGS.dat" />
</Component>
<Component Id="cmpDA5F2E45468ACB6957DF118202F57CBA" Guid="{2877D2BE-A1D7-46B8-AE47-53D9B447FA9D}">
<File Id="filA7C7633C832FDE23C3A3D543BE4E0117" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_EFIGS.dat.br" />
</Component>
<Component Id="cmp329238427D6DFA82B9DE0EC84FAA175F" Guid="{19E13614-89FD-4B1F-BC3F-4D9FB4A82391}">
<File Id="fil85E8885AF7B63E77FC30F33EA7464A10" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_EFIGS.dat.gz" />
</Component>
<Component Id="cmp006F8D28BA0AFE320C8E136D5C68A581" Guid="{B03BEBED-7876-4B59-A69A-07C2B09D0F56}">
<File Id="fil308F3F6ED362594B77EF7CE88BCCB855" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_no_CJK.dat" />
</Component>
<Component Id="cmp538D88FA41B7B0483DDF492891D5D684" Guid="{AE37820A-AD7E-4A3B-85B5-5C713E0F701C}">
<File Id="fil164352E303F8D7119412937E644F3D90" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_no_CJK.dat.br" />
</Component>
<Component Id="cmpF9E68B4BB97E17771AA221E83025CF38" Guid="{6A00E0B1-C08D-493B-A5FF-01001D31ABC0}">
<File Id="fil74816C0820AAF70E089B169C5EFB8E03" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\icudt_no_CJK.dat.gz" />
</Component>
<Component Id="cmpA38DF32DEFA15EAB22A6AF80CC0DBA93" Guid="{92746487-239F-4375-A057-E73C72E0CBB3}">
<File Id="fil6A69DAD1824C6F4ADEEB75886F45C215" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.dll" />
</Component>
<Component Id="cmp7A14C98BD98024E214134EE58D8A2A0D" Guid="{75D3F763-C971-439B-9659-73B0A2E3921A}">
<File Id="fil40B121415F82041273E4F86F31649747" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.dll.br" />
</Component>
<Component Id="cmpFB1DAD1066930B4BCF63BD47478DA044" Guid="{EA42F28D-BB0F-4C93-AC68-E7DC429407D2}">
<File Id="fil4C568CE1D72145CE5D718E8A0D713E94" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.dll.gz" />
</Component>
<Component Id="cmpD5C2C4A360A21B8188754FC87E3531E0" Guid="{6FBD58DA-054C-4E9F-B2E4-5BCBBE4A096D}">
<File Id="fil20852D9320634269944588FC0AB30EF4" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.Web.dll" />
</Component>
<Component Id="cmp971F14265094A43D81FE6F2B7D1AF6B7" Guid="{9D277B49-4260-4A16-8DC7-BB1507080255}">
<File Id="fil4D323C615D70E0296DE05A39ABCF2483" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.Web.dll.br" />
</Component>
<Component Id="cmp0326270DDC7B6B2E7294E885AF295E3A" Guid="{E678F79C-3DF4-46A4-AF1F-31479BD0735E}">
<File Id="fil8A47DF30080F4F85E90D8AEA0D7C68AE" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.Web.dll.gz" />
</Component>
<Component Id="cmp514A78E3D9A3A1B0381C2609914F3FCD" Guid="{0A8FC9D2-72EE-4D7C-A4EE-9BE0F95C367E}">
<File Id="fil802D2750CD020A3D5E78C40AF27FCE7E" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.WebAssembly.dll" />
</Component>
<Component Id="cmp3B994E9EC7D69DA30E3341DDCA1C2E35" Guid="{C6668F6E-6A32-48D5-93DF-C808FFF25500}">
<File Id="filFFAD2F1CF56AFA39BB66C4F6E53F5D7C" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.WebAssembly.dll.br" />
</Component>
<Component Id="cmp8648F3FB6E0C32E344C77586438BA083" Guid="{50B5A6DB-AABA-45D9-9A8A-F1970F04DF92}">
<File Id="fil658F0AC6351BC749808CDEBEDCD9E184" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.AspNetCore.Components.WebAssembly.dll.gz" />
</Component>
<Component Id="cmpA160DA65B8DFE4CF4F6754B9B315896E" Guid="{39112D1E-BF00-4F2B-BE9C-233E177B3CC6}">
<File Id="fil009E11A5AB23FA4EAEC7ED47EB533CDD" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.Abstractions.dll" />
</Component>
<Component Id="cmp4242E026351F6B91ED373820F5BA7E70" Guid="{BD35E2A6-3DE8-4E26-9FEE-9FEF1D2CE7D7}">
<File Id="filA06F61D6AE665C6ACBA435342CFC6210" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.Abstractions.dll.br" />
</Component>
<Component Id="cmp42CC4971550CD97B0B702F1471CB4C72" Guid="{108B946B-835F-4724-8286-A79019524C9B}">
<File Id="fil34237AA456807B011EED94EEC76855E5" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.Abstractions.dll.gz" />
</Component>
<Component Id="cmpF91962248A2205ABCF3B6BD33C74BAF4" Guid="{98E07B5D-447B-4731-9947-A6E6C7010E56}">
<File Id="fil8D0B84ED97BAF65B0ACE402589060BB0" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.dll" />
</Component>
<Component Id="cmp5DEDEDAD272B08B21352520216DB4781" Guid="{A268F034-777A-40D8-8AE7-86F41E5002A2}">
<File Id="filD823E906EA5BDACAD60F824A553714AE" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.dll.br" />
</Component>
<Component Id="cmp9173B268855879B81EDE2F0FD17367A7" Guid="{A1BE20EE-4DB9-458A-8D4F-EAA9D4FA098F}">
<File Id="fil1CACF1BC049F6E4239657CF6557D1070" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.dll.gz" />
</Component>
<Component Id="cmp5F4A3E3B2CBE10DA3D1BE6856D377E48" Guid="{D6EE7763-CA19-4AD8-AAB6-2579C4B1C214}">
<File Id="fil1F782C0520BFAD02930D3D41F1B1AC17" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.Json.dll" />
</Component>
<Component Id="cmpAEAABAB05E5E18C6E5D596B5134B11AA" Guid="{41A05EF2-9B05-47EE-ABA9-5D6FF05FE9AF}">
<File Id="fil1EA5135DAEC4BCA7F0393E23CEE978B0" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.Json.dll.br" />
</Component>
<Component Id="cmpB7F61D4C72FC6E25B4BD2D7C406028AF" Guid="{C650C27C-854B-4357-898A-B9BD5483A508}">
<File Id="filA7E3A736B61DC726180AD1A11AE061BC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Configuration.Json.dll.gz" />
</Component>
<Component Id="cmpF7B0EE03C7D98B064308BA96508AE479" Guid="{29C33D15-B96B-47C0-8DAF-B95D330F7FF5}">
<File Id="filAC0A7B0EDFBB7791CBCAA7ABF495C580" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.DependencyInjection.Abstractions.dll" />
</Component>
<Component Id="cmp86A1AADE6BF473BDAE88C6F24BCCA966" Guid="{48EE1B2B-54E1-468E-8EBD-6FB26F2B3919}">
<File Id="filD07CE14E098E28AF0A5FD83A0C257049" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.DependencyInjection.Abstractions.dll.br" />
</Component>
<Component Id="cmp975438FFB4C20A8535CA709CDD345C48" Guid="{91C733F3-782D-4219-9A92-43BBEF0BA3B3}">
<File Id="fil606F02CF9E1797C7B7F108712DC24500" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.DependencyInjection.Abstractions.dll.gz" />
</Component>
<Component Id="cmpAE73F552B8F7B3A26A0C4D716BDDB8B8" Guid="{D1A9B445-04EE-4611-8928-DA4AC13AAF6C}">
<File Id="fil15FEEF6525A9FC4EF41735F78B121AF3" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.DependencyInjection.dll" />
</Component>
<Component Id="cmp7858B731FC612FE7E07A6122BFDBA4D8" Guid="{A1FBA75E-A354-4DE8-BB97-F8FEB0AC4A97}">
<File Id="filEA94D6EFC482DE959D14E73DEF2F9799" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.DependencyInjection.dll.br" />
</Component>
<Component Id="cmp3CD942B25C15D4F3B3B8BA16662EFCEC" Guid="{86F17A53-55B0-437B-A9BE-6A73951D1B2F}">
<File Id="fil0A304EF7F79CF49A169E5A885F189277" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.DependencyInjection.dll.gz" />
</Component>
<Component Id="cmp7BC7B696CC9C4EC000AAB5D52588B1BC" Guid="{469F6FDB-2C12-4404-96FC-C2C1C2DA989F}">
<File Id="filC4A48A09556A780EB3CFC1A33F965EFE" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Logging.Abstractions.dll" />
</Component>
<Component Id="cmp707551BC0DBA68C6D49E4ED09CC3FE90" Guid="{3E54DD8E-C58E-406E-BA57-2A269E781CDA}">
<File Id="filDBB61B02BDFF3C6843B1B468A559ADA9" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Logging.Abstractions.dll.br" />
</Component>
<Component Id="cmp515E95EEE930BE8B288A5B6D95C4F6B6" Guid="{245D47D0-F8E5-4623-8C58-D7A61C846FF4}">
<File Id="fil7FD0B4E3B7BCF3AA9C6C0E29EACDA2CD" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Logging.Abstractions.dll.gz" />
</Component>
<Component Id="cmpE060C6A31FDC9AA148DBE1CD795BDD87" Guid="{FE7403C6-356B-4185-9E9D-4D97822E63B4}">
<File Id="fil5605734554345F4F36AA24D3C64053AF" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Logging.dll" />
</Component>
<Component Id="cmp51F55DD4FA3ECC6EC277B603BAE77E4B" Guid="{EDDB08FF-FA51-4EB9-A38E-81CAC6F6E0F0}">
<File Id="fil40167D8C2CE51BF97351AF5BA196B067" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Logging.dll.br" />
</Component>
<Component Id="cmp09275652FE8A5CC3B05F9F04F4ACDAB8" Guid="{4CA48B37-DA80-46E2-8791-932F9BD2B90E}">
<File Id="fil7E1DCF5917210F2713343978FEAFC18C" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Logging.dll.gz" />
</Component>
<Component Id="cmp4C12430D81FCE43486C72C98ACA22DE4" Guid="{4E35A9F2-29C9-4898-BA11-F97B7F2468A1}">
<File Id="fil497BDFF56C9C493B4EA3BB05CB84E6C4" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Options.dll" />
</Component>
<Component Id="cmpAF9DE5022005A570309CDC608D8817FE" Guid="{D7F8D688-C979-4049-8D0D-B7902ACD1E9B}">
<File Id="filEDEFBD7086806983D3A9F7B302294874" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Options.dll.br" />
</Component>
<Component Id="cmp864779AFDF069BB096C3D55EB7E67D17" Guid="{5F1E29A3-6ED6-4339-93CE-E008A48E0167}">
<File Id="fil95DA4561466E116EBCFFB2304CE45E3D" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Options.dll.gz" />
</Component>
<Component Id="cmpBDCF4227A3F14BFD217701F4E1AEF581" Guid="{1D9DE43C-B81C-4166-97E4-BB869393E51C}">
<File Id="filFCEA26229C64F5B0DDC4F300E527003B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Primitives.dll" />
</Component>
<Component Id="cmp8C2B056893FC9B4F917F1D60A86CAF46" Guid="{F5C200A4-4B00-4BC9-ADF0-816528383EE2}">
<File Id="filA5FEC50FDD462EFE465ED50197DA27AC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Primitives.dll.br" />
</Component>
<Component Id="cmp5205763847DAE3B1F0E9A557ECEA0294" Guid="{8D771669-627C-47A5-A0B6-83148104C4F2}">
<File Id="fil6FE0C53D273C04D664103B017EB6B7FC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.Extensions.Primitives.dll.gz" />
</Component>
<Component Id="cmpE22F274295C3DEF43785B45EC2A93623" Guid="{9F311DB3-4571-4CB6-86C2-AD10F536A480}">
<File Id="fil9CF7F6D0082CC00831BCB79B512F6DDC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.JSInterop.dll" />
</Component>
<Component Id="cmpB8A2E71C8CF36DE8D8F53A1D8C90371C" Guid="{1AA84CBE-D211-45D4-9F58-76554544CC42}">
<File Id="fil343FB5CD812AFA562BF31FD0BDC5BCEE" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.JSInterop.dll.br" />
</Component>
<Component Id="cmp73A0603CACC8FD37AE5400E72FB390B4" Guid="{F4869EBE-CA6E-459B-BE6B-6F64E4E98C60}">
<File Id="fil8A998F649F697B54B836C9E31DFEFD27" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.JSInterop.dll.gz" />
</Component>
<Component Id="cmp2F2ED6725809828FFA8AF2B1F4793156" Guid="{5E0F9CD9-A13A-4F21-9B81-F4232A460F08}">
<File Id="fil2A6F7DDF91413905561875B8A447A547" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.JSInterop.WebAssembly.dll" />
</Component>
<Component Id="cmpDA5844562D73C6F04F932F5314A77A39" Guid="{51C97F73-DD58-4529-B174-E4FA52FA7AA9}">
<File Id="fil0F726A6415D2ADD8D2559118F8727F5B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.JSInterop.WebAssembly.dll.br" />
</Component>
<Component Id="cmp7C9F2443CAE1F55295CD79951408C721" Guid="{620AC919-B5C7-47CA-9328-A997EF2A6253}">
<File Id="fil71F4B87F19AEAFF7939C1EE93FE6FE73" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\Microsoft.JSInterop.WebAssembly.dll.gz" />
</Component>
<Component Id="cmpA65D953E5A54247042B256470D47D4AB" Guid="{F053B0E4-C996-4310-8252-897F53F3E1B8}">
<File Id="fil8895E72799380F4E05CAEBCD685DDBE2" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Collections.Concurrent.dll" />
</Component>
<Component Id="cmp51F02589BA588D783C3C603656194CC7" Guid="{7DBE3773-D328-4905-AEB0-55547E987881}">
<File Id="fil004F6DABDDB1C96CE27C8F35F0DC9DDA" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Collections.Concurrent.dll.br" />
</Component>
<Component Id="cmp5937FF9962810B779AC2D3AB0E1FFA31" Guid="{B4E3EFBD-D454-427C-89CF-4992325069B0}">
<File Id="filBD9E064AE6BA6531330CC8A72F2D68BE" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Collections.Concurrent.dll.gz" />
</Component>
<Component Id="cmpB4F75E93D852D00850CC0545706516AC" Guid="{AFB6171F-EB34-4887-B8A6-AEB05E9DBDDB}">
<File Id="fil72DFEAD849270C7487E1922671555A98" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Collections.dll" />
</Component>
<Component Id="cmpC482BD0E23AD6B0866F0EC3B3EE21912" Guid="{96712566-72E8-4398-9281-BDC6920958B1}">
<File Id="fil9DD14B36011AD1AED77223FE87E184FC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Collections.dll.br" />
</Component>
<Component Id="cmp20D34FC7203469574D5B870FBFDB6F7F" Guid="{12C35146-B5E7-4160-8F7D-ABAC85ECC51A}">
<File Id="filBB29036EFDD1D8D5AA5DC924CD208D5D" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Collections.dll.gz" />
</Component>
<Component Id="cmpA826E1BF780AE0933557676389100061" Guid="{FEB1C65D-1E53-4E89-BAD3-BE9BDC8B0B8E}">
<File Id="filAFDFA52206BB9423B6CE2C685284CA99" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.ComponentModel.dll" />
</Component>
<Component Id="cmp2A2D126124E8909219DB6B0BD3DB7281" Guid="{7B41DDFB-6A7D-4B79-B200-A4DDAACD6A22}">
<File Id="fil271CA6B703F5070B21C12F8EADEAB1BF" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.ComponentModel.dll.br" />
</Component>
<Component Id="cmp48F0DEF6E07C958C489DB5F099A47D02" Guid="{5C0DAE60-1552-4F6A-B845-9B509E04C91C}">
<File Id="filB43BEEE84D76BE6B8E121624D1937EB4" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.ComponentModel.dll.gz" />
</Component>
<Component Id="cmpE51D0DCA6EE2771B65D0DB930DA0F422" Guid="{7E2CCB1F-0AB1-438C-A2D0-CC29E22270D8}">
<File Id="fil25D4C6054723DCF53741AEA2FCE1D13B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Memory.dll" />
</Component>
<Component Id="cmp16DCE2C779691329ACBD41A17893807C" Guid="{1BF83602-DC3E-46B8-9B18-E0D8878B4413}">
<File Id="filBA4C797C8626633866C4D2E2FE570242" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Memory.dll.br" />
</Component>
<Component Id="cmp607A37F44559C1B9663107B3C5780416" Guid="{23343BC9-BF41-4E66-B3F6-A368A8889DB5}">
<File Id="filBFEDF80BCA685FDC664033CA845F4233" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Memory.dll.gz" />
</Component>
<Component Id="cmp3750CA84737F30C6A133B736D82311DC" Guid="{6CBA8DC9-B192-42C3-8D31-AD9A026C1E94}">
<File Id="filFE5E821A8E08C92D63E707F7DAB9B3A6" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Http.dll" />
</Component>
<Component Id="cmp5F48A2E610A688238A2DF46678BFC4DA" Guid="{38C8A848-63A6-48B1-BC49-248952C3CA5A}">
<File Id="fil6A576146A10F514A4FEE0D9A2F62E66A" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Http.dll.br" />
</Component>
<Component Id="cmp333F8CFB28D84B1BFBCFD0207AB4C8DC" Guid="{3AD9E240-3E6D-4E09-B91E-A8E471866767}">
<File Id="fil5C3E404B87A4A624EA1008033586135B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Http.dll.gz" />
</Component>
<Component Id="cmpED48E5DDB3EBB7C71EDACF54D349688E" Guid="{6432BBFD-BF55-4F25-BD89-746508129B88}">
<File Id="fil945264EEB7D05962944632DB40D103F6" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Http.Json.dll" />
</Component>
<Component Id="cmpFA624270AF509809FE8CD8C49FA60779" Guid="{D65CACAF-3BED-4591-B80B-AF9CA572F470}">
<File Id="fil48DFB166E1B2D0E5F602E450BDA268D5" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Http.Json.dll.br" />
</Component>
<Component Id="cmp50C00207A15C4550FE7A85241C74BBE8" Guid="{2AD2A4A1-7007-4413-AEDB-2590D7E520B0}">
<File Id="fil6585BFE45253B14831A430FDDECF04C7" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Http.Json.dll.gz" />
</Component>
<Component Id="cmp56887909ACB3B8F6402B40E26751C3B3" Guid="{F7F53191-F371-46DA-B469-04D6D73ADFDF}">
<File Id="filE0FF1A9872F99F1E4D32910E53C186C0" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Primitives.dll" />
</Component>
<Component Id="cmp0976629DB2D3387B7524A1EA5BB9828A" Guid="{A1D24AE4-2A92-42F3-927A-C7F6F0FA9BDA}">
<File Id="fil00CC944E233AB04D3545A0E244417382" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Primitives.dll.br" />
</Component>
<Component Id="cmp9BEE2BBA2E625E10ACE5D38F9CE29E25" Guid="{AC479C09-1430-473B-B535-353378D3E807}">
<File Id="fil7EA368F875D5AAD4C64F77E41A6E23AF" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Net.Primitives.dll.gz" />
</Component>
<Component Id="cmp1740817C651EE407F3A14689504EEF0B" Guid="{5F40E782-D9F5-4094-BF3A-D96BA646519A}">
<File Id="fil92050D8BEB3B82F62508D2473289059B" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.CoreLib.dll" />
</Component>
<Component Id="cmpB1F2210BCA59E771BFE567C4B70223E3" Guid="{9F599BC5-AC3F-4708-8EEE-33AD7CF44D9F}">
<File Id="filFC0EA5B332077F9C3AD1339464605983" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.CoreLib.dll.br" />
</Component>
<Component Id="cmpA098BA5EC2A20A12327DB7E9D1560C36" Guid="{B46F7ACB-8D2F-48E4-8329-4DB270626DF5}">
<File Id="filF20866D9620DEA24F42C6BC3533B0DD0" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.CoreLib.dll.gz" />
</Component>
<Component Id="cmp4DBC5ACFDAEC1C4E3CD7EF1AC171CDD4" Guid="{B6B28027-F77B-4BA9-82BE-99F5D12BD14A}">
<File Id="fil84342B01143909094AC4F27D453CCF22" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.Runtime.InteropServices.JavaScript.dll" />
</Component>
<Component Id="cmp1173314C87D3A1C6669E796D63BA0B5D" Guid="{9B209BED-B524-4AD2-843B-66C0358E78C9}">
<File Id="fil3ABC05F2D210D029B9BC94BE2FC22A9C" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.Runtime.InteropServices.JavaScript.dll.br" />
</Component>
<Component Id="cmp0A248A654EDFBDA44693AADCAC9DD461" Guid="{922B4040-685C-460D-BF3F-28AA61DD8BFC}">
<File Id="fil9FB6E89FC7B2CCB51474A12BFA99B4FC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.Runtime.InteropServices.JavaScript.dll.gz" />
</Component>
<Component Id="cmp9DB136D1B06E1CFF3226F8FF247FA400" Guid="{D7D96DAF-DF94-42AA-866D-7283605EAD93}">
<File Id="fil112BD196CC1B5B4AD4D7D583398FE147" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.Uri.dll" />
</Component>
<Component Id="cmpDCFCF9BD3503D6340AA0A2B21FE7FBCC" Guid="{ED5FEA3F-00F4-41B5-B97A-402ACCE765C8}">
<File Id="filE2A25AFD13442571FE641F364E470893" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.Uri.dll.br" />
</Component>
<Component Id="cmpD1D9EEDAFC075B3BC32EE7298288086F" Guid="{E14DA94F-CC7D-46E7-A992-B8A75A49E432}">
<File Id="fil9B542E73B61E1A0DB2E6354A641F6CEB" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Private.Uri.dll.gz" />
</Component>
<Component Id="cmp740321EAD6FA852678D49E02C9131145" Guid="{12F99079-3F99-4690-BCB8-431A0CC37716}">
<File Id="fil64814F821C696DC6C9496821E23668F2" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Runtime.CompilerServices.Unsafe.dll" />
</Component>
<Component Id="cmp743C84704C46065CC2390782C88647FE" Guid="{44B7F53C-993A-40B0-A8E5-7D38720E4111}">
<File Id="filC26B779E0B33BAFC1A30D48B1A870ED8" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Runtime.CompilerServices.Unsafe.dll.br" />
</Component>
<Component Id="cmpC370C60937565F7FB65302F95A8C1FF0" Guid="{EF593AFB-4158-479E-AAC2-192AC7F57579}">
<File Id="fil19E6EEB3BDAF719BF0133E45D88A03DF" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Runtime.CompilerServices.Unsafe.dll.gz" />
</Component>
<Component Id="cmpE9537DAAFB13ACF42382B5F39E041AAE" Guid="{F2484F22-5F1F-4490-B163-5D80D8822135}">
<File Id="filB923ECB75321ADB1F2B711305B6AB357" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Runtime.dll" />
</Component>
<Component Id="cmp3AE669088A014BAB8C199390E02DB7E7" Guid="{E5B2977C-1B3E-4CF2-876C-DAC9579C9330}">
<File Id="filF4DCDF75398370DD75D51E1510602BFC" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Runtime.dll.br" />
</Component>
<Component Id="cmpAB7158EA13F736C1E0451D0807BE4947" Guid="{AC9943C5-30E1-4ED4-B75C-F0B067C1A090}">
<File Id="filD4698EA1B34887AE694A74475593E3E3" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Runtime.dll.gz" />
</Component>
<Component Id="cmpBE312FE3FB6A6BDDAB0FE75F1EC0F480" Guid="{04293042-0055-4A8E-A2E8-DE9374B4758A}">
<File Id="fil18CECB88CBBA124C417F9726260D1B30" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Text.Encodings.Web.dll" />
</Component>
<Component Id="cmp9D0A4D86ADBE049A6CD726A4C5FD96EE" Guid="{DED6A3FF-479E-45E9-BA1C-1D48FEAD61FE}">
<File Id="filE932324B082B8169CC0334B9B68E7346" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Text.Encodings.Web.dll.br" />
</Component>
<Component Id="cmp6C9D44905338F4A80BCF436FADD3333E" Guid="{7482DA68-E977-4B51-BD6B-44DE843BFBF6}">
<File Id="fil2CD4D93571823B42747D1E81549C12DA" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Text.Encodings.Web.dll.gz" />
</Component>
<Component Id="cmpED3B8CFD2C58E76550E55BB568433B01" Guid="{77F7D092-BAFF-4368-BD35-FBB8D7E4A676}">
<File Id="fil6242EB6396FCEB42E682BC2B7EB5ECAD" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Text.Json.dll" />
</Component>
<Component Id="cmpBA0FF53077EEA56D55F8AB637925580B" Guid="{9010AEC8-0EB3-4DA4-A69C-16CCA4CA82FA}">
<File Id="fil1D0FC0B73348482750C57247305BA66E" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Text.Json.dll.br" />
</Component>
<Component Id="cmp63CB25923717C691B1A5EA40B6C111F0" Guid="{A570FD8B-480D-4429-8EF9-90DB914E9A08}">
<File Id="filA19C569DA0C381BF3584866DD2BAA824" KeyPath="yes" Source="$(var.BasePath)\wwwroot\_framework\System.Text.Json.dll.gz" />
</Component>
</Directory>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="PublishedComponents">
<ComponentRef Id="cmpA0863526952F7834E7C922F065E4C8A8" />
<ComponentRef Id="cmpF82FCA80BBAF44D285C97F10993DEEE6" />
<ComponentRef Id="cmp80A32365AE3ACFE27BDD385AE91DCE74" />
<ComponentRef Id="cmpF69BDBE9F42451436A0B8C022F6D4636" />
<ComponentRef Id="cmpFD59DF07063AC308C40670A4B81A9B57" />
<ComponentRef Id="cmpECDF00A9B659260C50885BEEADBCABC0" />
<ComponentRef Id="cmpE351BCDC42EF493685CEF4080E08E51E" />
<ComponentRef Id="cmp651C3999A00B5D89ACAE2D3A9BE7F91D" />
<ComponentRef Id="cmpBCBFD41B8B964007BA9BF340925C6493" />
<ComponentRef Id="cmp9A7CD58BE639399F7BDAA987492B6E65" />
<ComponentRef Id="cmpB818026BC106A80C4FD6E90BF8F06CDA" />
<ComponentRef Id="cmp2F0A313AE6306F9CE5E760AF214DC789" />
<ComponentRef Id="cmp6D6CC90C40E2F632C9128346BA7F188F" />
<ComponentRef Id="cmpA76C6CFFA9DCB201D0EEDB226B0B9E25" />
<ComponentRef Id="cmp17959BADF0C2D7B7AB4867F09DA031B8" />
<ComponentRef Id="cmpDF4C205418A6D7FE6FEA71F3B8998FAC" />
<ComponentRef Id="cmpDA8B0BBD16E996DE615D6861DBA6442F" />
<ComponentRef Id="cmp3D2A78302A6149F7464B0EDCD758BCCF" />
<ComponentRef Id="cmp8C674FD6A69988A60A77A4CEE0F53781" />
<ComponentRef Id="cmpDB4717CBBFD23A9652DB5B136ABB5D75" />
<ComponentRef Id="cmpCF0F711637230B4D1AE41109C02C9142" />
<ComponentRef Id="cmpF88B96E5973E0D28B511DC6371DB06E0" />
<ComponentRef Id="cmpB139B49DF4DF8F44C525B449EA8187F7" />
<ComponentRef Id="cmp5B65C45828B950384B8C5C76AB9F6EF0" />
<ComponentRef Id="cmp5A9228A102598245A49CC73E4B42BFFD" />
<ComponentRef Id="cmp0B11C97F8D96134C5A582DAA9D362721" />
<ComponentRef Id="cmp22B9B089D6F03FEB02531ECB35C82F8E" />
<ComponentRef Id="cmp958171B03EC06C56FB11A52D468E5F57" />
<ComponentRef Id="cmpB322B77CE8D40EBAD199D45D0E4F25F0" />
<ComponentRef Id="cmp920020A0D51F9A626EB2143066649049" />
<ComponentRef Id="cmp6A573805E6F545A7F37C18527646950E" />
<ComponentRef Id="cmp0D2F1CB83AD7A688791EFF1B2407B5F1" />
<ComponentRef Id="cmp8D45D052C68877B0B807B3D45E104FF6" />
<ComponentRef Id="cmpD91242D38C41E4403B7679B93F1EEBB4" />
<ComponentRef Id="cmpCB80CFC92D7C1BB2787B948E67B42B03" />
<ComponentRef Id="cmpBCCB7ADB11BD8E995C2D17B5FDFD7CA8" />
<ComponentRef Id="cmp6300BF95DDDCF98EC047B2991C2BA653" />
<ComponentRef Id="cmp087AEDA3ECF7BE8C1137AADA0E56E0A6" />
<ComponentRef Id="cmpEBA035EA7685839B21FA1B833C2D781C" />
<ComponentRef Id="cmp87BF3E7D495DC9B53F7ED2A371F1FE92" />
<ComponentRef Id="cmp2220CCF66448F1A862D1353191CE69F5" />
<ComponentRef Id="cmp791F5746D6F2AC68E2E8A50343B869F7" />
<ComponentRef Id="cmp3DA139ADE5BC562B564DECE23AFFD8D0" />
<ComponentRef Id="cmp3F52B8D89D587889C8A65D69E74B5F51" />
<ComponentRef Id="cmp102AA2B65E2F7CFDBE0F937F8D225168" />
<ComponentRef Id="cmp022B66C05DEF11B72F5542F7A563B670" />
<ComponentRef Id="cmp0F72C70E7993CC0B3E9FF70ED40066D9" />
<ComponentRef Id="cmpFA0036474721DE0D4163E05499F39951" />
<ComponentRef Id="cmpB5AF9E63913432C07629EC20330320A3" />
<ComponentRef Id="cmp9D66267AB1CAF7A98DFC42947DC635D4" />
<ComponentRef Id="cmpCD4F94EB73F3962B42308170454B4366" />
<ComponentRef Id="cmp6D7DA841FD268735AFB1026BA6AE24A3" />
<ComponentRef Id="cmp08111D788677D8B8150650EE58FB5962" />
<ComponentRef Id="cmp5A46DA40AED3B5E10AF9751BA0029C2C" />
<ComponentRef Id="cmp6A6C2351815759B4DB8982A7741D0ABA" />
<ComponentRef Id="cmp82623C6CA3D1FE2B38C69748720D46CB" />
<ComponentRef Id="cmp2EAADFED8A771ED40D36F4261011FC42" />
<ComponentRef Id="cmp0C35E5441CB1AEE868B0841FC2B3727D" />
<ComponentRef Id="cmpF7B971FD5EDDB748109439252E62DBB2" />
<ComponentRef Id="cmp1A38450971536177F12598D9DA69460B" />
<ComponentRef Id="cmpB3C98B1AF19712A5A4C90299621D5AA3" />
<ComponentRef Id="cmpB532E6FD17B9FD1DDEF930DAB1CDCC8C" />
<ComponentRef Id="cmp930FCEACB08C3F828E26B2B4AAAD3B58" />
<ComponentRef Id="cmp94D35364CD546AECFF1FD3E16E7705BC" />
<ComponentRef Id="cmpEEB478F290FD8E012F256864DA59B87A" />
<ComponentRef Id="cmpABBCFC94814B14153BE6A9A7989C2A0A" />
<ComponentRef Id="cmpF242BF7465335E363684D1995205E1BD" />
<ComponentRef Id="cmp02E6C2F0AD10D0478D86BE37452B0914" />
<ComponentRef Id="cmp4A0D7430E5062327165BBC0627BB2583" />
<ComponentRef Id="cmp39219EB53A18F9EF8C1D9E629B44B00E" />
<ComponentRef Id="cmpA1E64C6DD02D1B8D3365CDF712DE7740" />
<ComponentRef Id="cmp2F00835F6AB457CB0746B0CF23BBABC4" />
<ComponentRef Id="cmp728A6879EC0D4538CF0D9A610CDB29AB" />
<ComponentRef Id="cmpCF6F10CA4A3650B98898E76461DBDB47" />
<ComponentRef Id="cmp512FC92BCC546D0A442E2A50E378BA60" />
<ComponentRef Id="cmpA8FCAF75866687FC4A4693E426913FBA" />
<ComponentRef Id="cmp747FF5C347AA12FFF91DF70F289BC1F7" />
<ComponentRef Id="cmpDEF19AE67395660D7A04537C771DEAEA" />
<ComponentRef Id="cmp286486FA354377E5944B31BCB5E1BD86" />
<ComponentRef Id="cmpDA5F2E45468ACB6957DF118202F57CBA" />
<ComponentRef Id="cmp329238427D6DFA82B9DE0EC84FAA175F" />
<ComponentRef Id="cmp006F8D28BA0AFE320C8E136D5C68A581" />
<ComponentRef Id="cmp538D88FA41B7B0483DDF492891D5D684" />
<ComponentRef Id="cmpF9E68B4BB97E17771AA221E83025CF38" />
<ComponentRef Id="cmpA38DF32DEFA15EAB22A6AF80CC0DBA93" />
<ComponentRef Id="cmp7A14C98BD98024E214134EE58D8A2A0D" />
<ComponentRef Id="cmpFB1DAD1066930B4BCF63BD47478DA044" />
<ComponentRef Id="cmpD5C2C4A360A21B8188754FC87E3531E0" />
<ComponentRef Id="cmp971F14265094A43D81FE6F2B7D1AF6B7" />
<ComponentRef Id="cmp0326270DDC7B6B2E7294E885AF295E3A" />
<ComponentRef Id="cmp514A78E3D9A3A1B0381C2609914F3FCD" />
<ComponentRef Id="cmp3B994E9EC7D69DA30E3341DDCA1C2E35" />
<ComponentRef Id="cmp8648F3FB6E0C32E344C77586438BA083" />
<ComponentRef Id="cmpA160DA65B8DFE4CF4F6754B9B315896E" />
<ComponentRef Id="cmp4242E026351F6B91ED373820F5BA7E70" />
<ComponentRef Id="cmp42CC4971550CD97B0B702F1471CB4C72" />
<ComponentRef Id="cmpF91962248A2205ABCF3B6BD33C74BAF4" />
<ComponentRef Id="cmp5DEDEDAD272B08B21352520216DB4781" />
<ComponentRef Id="cmp9173B268855879B81EDE2F0FD17367A7" />
<ComponentRef Id="cmp5F4A3E3B2CBE10DA3D1BE6856D377E48" />
<ComponentRef Id="cmpAEAABAB05E5E18C6E5D596B5134B11AA" />
<ComponentRef Id="cmpB7F61D4C72FC6E25B4BD2D7C406028AF" />
<ComponentRef Id="cmpF7B0EE03C7D98B064308BA96508AE479" />
<ComponentRef Id="cmp86A1AADE6BF473BDAE88C6F24BCCA966" />
<ComponentRef Id="cmp975438FFB4C20A8535CA709CDD345C48" />
<ComponentRef Id="cmpAE73F552B8F7B3A26A0C4D716BDDB8B8" />
<ComponentRef Id="cmp7858B731FC612FE7E07A6122BFDBA4D8" />
<ComponentRef Id="cmp3CD942B25C15D4F3B3B8BA16662EFCEC" />
<ComponentRef Id="cmp7BC7B696CC9C4EC000AAB5D52588B1BC" />
<ComponentRef Id="cmp707551BC0DBA68C6D49E4ED09CC3FE90" />
<ComponentRef Id="cmp515E95EEE930BE8B288A5B6D95C4F6B6" />
<ComponentRef Id="cmpE060C6A31FDC9AA148DBE1CD795BDD87" />
<ComponentRef Id="cmp51F55DD4FA3ECC6EC277B603BAE77E4B" />
<ComponentRef Id="cmp09275652FE8A5CC3B05F9F04F4ACDAB8" />
<ComponentRef Id="cmp4C12430D81FCE43486C72C98ACA22DE4" />
<ComponentRef Id="cmpAF9DE5022005A570309CDC608D8817FE" />
<ComponentRef Id="cmp864779AFDF069BB096C3D55EB7E67D17" />
<ComponentRef Id="cmpBDCF4227A3F14BFD217701F4E1AEF581" />
<ComponentRef Id="cmp8C2B056893FC9B4F917F1D60A86CAF46" />
<ComponentRef Id="cmp5205763847DAE3B1F0E9A557ECEA0294" />
<ComponentRef Id="cmpE22F274295C3DEF43785B45EC2A93623" />
<ComponentRef Id="cmpB8A2E71C8CF36DE8D8F53A1D8C90371C" />
<ComponentRef Id="cmp73A0603CACC8FD37AE5400E72FB390B4" />
<ComponentRef Id="cmp2F2ED6725809828FFA8AF2B1F4793156" />
<ComponentRef Id="cmpDA5844562D73C6F04F932F5314A77A39" />
<ComponentRef Id="cmp7C9F2443CAE1F55295CD79951408C721" />
<ComponentRef Id="cmpA65D953E5A54247042B256470D47D4AB" />
<ComponentRef Id="cmp51F02589BA588D783C3C603656194CC7" />
<ComponentRef Id="cmp5937FF9962810B779AC2D3AB0E1FFA31" />
<ComponentRef Id="cmpB4F75E93D852D00850CC0545706516AC" />
<ComponentRef Id="cmpC482BD0E23AD6B0866F0EC3B3EE21912" />
<ComponentRef Id="cmp20D34FC7203469574D5B870FBFDB6F7F" />
<ComponentRef Id="cmpA826E1BF780AE0933557676389100061" />
<ComponentRef Id="cmp2A2D126124E8909219DB6B0BD3DB7281" />
<ComponentRef Id="cmp48F0DEF6E07C958C489DB5F099A47D02" />
<ComponentRef Id="cmpE51D0DCA6EE2771B65D0DB930DA0F422" />
<ComponentRef Id="cmp16DCE2C779691329ACBD41A17893807C" />
<ComponentRef Id="cmp607A37F44559C1B9663107B3C5780416" />
<ComponentRef Id="cmp3750CA84737F30C6A133B736D82311DC" />
<ComponentRef Id="cmp5F48A2E610A688238A2DF46678BFC4DA" />
<ComponentRef Id="cmp333F8CFB28D84B1BFBCFD0207AB4C8DC" />
<ComponentRef Id="cmpED48E5DDB3EBB7C71EDACF54D349688E" />
<ComponentRef Id="cmpFA624270AF509809FE8CD8C49FA60779" />
<ComponentRef Id="cmp50C00207A15C4550FE7A85241C74BBE8" />
<ComponentRef Id="cmp56887909ACB3B8F6402B40E26751C3B3" />
<ComponentRef Id="cmp0976629DB2D3387B7524A1EA5BB9828A" />
<ComponentRef Id="cmp9BEE2BBA2E625E10ACE5D38F9CE29E25" />
<ComponentRef Id="cmp1740817C651EE407F3A14689504EEF0B" />
<ComponentRef Id="cmpB1F2210BCA59E771BFE567C4B70223E3" />
<ComponentRef Id="cmpA098BA5EC2A20A12327DB7E9D1560C36" />
<ComponentRef Id="cmp4DBC5ACFDAEC1C4E3CD7EF1AC171CDD4" />
<ComponentRef Id="cmp1173314C87D3A1C6669E796D63BA0B5D" />
<ComponentRef Id="cmp0A248A654EDFBDA44693AADCAC9DD461" />
<ComponentRef Id="cmp9DB136D1B06E1CFF3226F8FF247FA400" />
<ComponentRef Id="cmpDCFCF9BD3503D6340AA0A2B21FE7FBCC" />
<ComponentRef Id="cmpD1D9EEDAFC075B3BC32EE7298288086F" />
<ComponentRef Id="cmp740321EAD6FA852678D49E02C9131145" />
<ComponentRef Id="cmp743C84704C46065CC2390782C88647FE" />
<ComponentRef Id="cmpC370C60937565F7FB65302F95A8C1FF0" />
<ComponentRef Id="cmpE9537DAAFB13ACF42382B5F39E041AAE" />
<ComponentRef Id="cmp3AE669088A014BAB8C199390E02DB7E7" />
<ComponentRef Id="cmpAB7158EA13F736C1E0451D0807BE4947" />
<ComponentRef Id="cmpBE312FE3FB6A6BDDAB0FE75F1EC0F480" />
<ComponentRef Id="cmp9D0A4D86ADBE049A6CD726A4C5FD96EE" />
<ComponentRef Id="cmp6C9D44905338F4A80BCF436FADD3333E" />
<ComponentRef Id="cmpED3B8CFD2C58E76550E55BB568433B01" />
<ComponentRef Id="cmpBA0FF53077EEA56D55F8AB637925580B" />
<ComponentRef Id="cmp63CB25923717C691B1A5EA40B6C111F0" />
</ComponentGroup>
</Fragment>
</Wix>
Добавьте этот новый файл в проект инсталлятора (Solution Explorer -> Add -> Existing Item).
Product.wxs
Теперь, перейдем в файл Product.wxs. Если кратко, то это основной файл, в котором описывается вся логика создания инсталлятора, его конфигурация и метаданные. Для небольших решений проект wix может в полне себе состоять только из этого файла.
Давайте добавим компоненты в сам инсталлятор. Для этого нам необходимо перед закрывающимся тегом </Wix>
удалить узел <Fragment>
(он генерится Wix по-умолчанию при создании проекта) на следующую секцию:
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<ComponentGroupRef Id="PublishedComponents"/>
</ComponentGroup>
</Fragment>
Таким образом, мы создали группу компонентов ProductComponents, которые будут развернуты по пути соответствующему свойству INSTALLFOLDER (она же виртуальная директория), при этом сами компоненты мы передали по ссылке из группы PublishedComponents, сгенерированной c помощью Heat.exe.
Удалите тег <MediaTemplate/>
(ищите внутри тега Product) — он используется в качестве заглушки и, если его не удалить, то вы обнаружите, что вместе с .msi-файлом генерится .cab-файл. Нам же необходимо поместить его внутрь файла .msi. Для этого перед закрывающимся тегом <Product>
необходимо добавить тег <Media>
:
<Media Id="1"
Cabinet="media.cab"
EmbedCab="yes"
DiskPrompt="CD-ROM #1" />
<Property Id="DiskPrompt"
Value="$(var.ProductName) CD-ROM #1" />
Тем самым мы описываем компонент media.cab – архив с файлами для установки. EmbedCab=”yes”
– указывает на то, что архив будет встроен в .msi-файл, а свойство DiskPrompt="CD-ROM #1"
– является легаси-наследием со времен, когда программные продукты распространялись на материальных носителях и разработчикам инсталляционных пакетов приходилось решать проблему поставки продукта на нескольких дисках из-за нехватки дискового пространства на носителях. Также не забываем добавить Property со ссылкой на DiskPromt, чтобы Windows Installer мог создать сообщение пользователю о необходимости вставить определенный диск. Обращаю внимание, что DiskPrompt является необязательным, и, если вы не планируете поставлять ваш продукт на физическом носителе, то и проставлять его ненужно (то же самое касается и Property Id=»DiskPromt»).
Теперь нам необходимо добавить интерфейс для взаимодействия с пользователем: сделать это можно двумя путями. Или самостоятельно описывать интерфейс, или воспользоваться готовыми шаблонами, которые поставляются вместе с wix. Так как разработка интерфейса – это очень объемная тема, мы воспользуемся готовым решением.
Щелкаем правой клавишей по названию проекта в Solution Explorer -> Add Reference — открываем папку, в которую был установлен WiX, подкаталог bin, файл WixUIExtension.dll.
Снова перед закрывающимся тегом <Product>
добавляем следующий код:
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" ></Property>
<UIRef Id="WixUI_InstallDir"/>
Wix предлагает пользователю несколько сценариев пользовательского интерфейса один из которых называется WixUI_InstallDir и, как можно догадаться из названия, позволяет пользователю выбирать в какую директорию будет произведена установка продукта. Путь до выбранной директории передается через свойство INSTALLFOLDER, которое используется в шаблоне WixUI_InstallDir на что и указывается Id="WIXUI_INSTALLDIR"
.
Работа с IIS
Для установки проекта, в нашем случае, описанных шагов недостаточно – не случайно же был выбран web-проект: теперь его нужно затащить на IIS. Разработчики Wix позаботились о нас и добавили в пакет поставки WixIISExtention – расширение, позволяющее развернуть приложение на web-сервере.
Подключаем расширение WixIISExtention: правая кнопка маши по проекту -> Add Reference — директория в которую установлен WiX, подкаталог bin, файл WixIISExtension.dll. У меня здесь C:\Program Files (x86)\WiX Toolset v3.11\bin\WixIISExtension.dll
Снова правая кнопка мыши по проекту инсталлятора -> New item… -> Wix/v3 и выбираем Installer File (.wxs). Назовем его IISConfiguration.wxs. Стираем все, что находится внутри файла и заменяем на следующее содержание:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Fragment>
<DirectoryRef Id="TARGETDIR">
<!--Creating an application pool-->
<Component Id="BlazorAppPool"
Guid="{5766F29A-7FD5-4359-BD6C-5E5C543FEFFD}"
KeyPath="yes"
Win64="yes">
<iis:WebAppPool Id="BlazorAppPool"
Name="BlazorAppWebSite"
Identity="localSystem"
ManagedPipelineMode="Integrated"
ManagedRuntimeVersion="v4.0"/>
</Component>
<!--Setup IIS for Blazor App-->
<Component Id="InstallWebsite"
Guid="{4AB0376B-F778-4D0F-8CA6-2F308AB7B077}"
KeyPath="yes">
<iis:WebSite Id="BlazorApp"
Description='BlazorAppWasm'
Directory='INSTALLFOLDER'
AutoStart='yes'
StartOnInstall='yes'>
<iis:WebAddress Id="localhost_BlazorApp"
Port="8085" IP="127.0.0.1"/>
<iis:WebApplication Id="BlazorWasmApplication"
Name="Blazor Web Application"
WebAppPool="BlazorAppPool"/>
</iis:WebSite>
</Component>
</DirectoryRef>
<ComponentGroup Id="BlazorAppIisConfiguration">
<ComponentRef Id="InstallWebsite"/>
<ComponentRef Id="BlazorAppPool"/>
</ComponentGroup>
</Fragment>
</Wix>
Давайте разберем по тегам содержимое файла:
-
внутри тега Wix добавляем ссылку на IISExtention c помощью вот этого атрибута
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
. Не забываем это делать, иначе проект не заведется. -
внутри тега Fragment начинаем описывать настройку IIS. Так как все компоненты должны получить путь установки обязательно упаковываем их в тег
Directory
илиDirectoryRef
, если директория уже объявлена. В нашем случае этоTARGETDIR
– корень виртуального каталога, объявленный на стадии создании проекта Wix -
объявляем компонент с помощью тега
Component
, присваиваем емуID
– не забывайте, что Id должен быть уникальным для каждого компонента (помним, что для базы данных Windows Installer он выполняет роль первичного ключа). Генерим GUID любым удобным для вас способом. Я предпочитаю использовать средства Visual Studio (Tools -> Create GUID и выбрать Registry Format). Указываем компоненту свойствоkeypath=”yes”
– это необходимо, чтобы установщик удостоверился, что данный компонент не был ранее установлен чтобы избежать перетирания существующих версий компонента (будет заменен только в том случае, если будет предложена более новая версия компонента), а также для осуществления восстановления. -
Внутри компонента описываем настройки
AppPool
дляIIS
: прописываем уникальный Id, имя пула, указываем тип учетной записи – в нашем случае это LocalSystem (желающие получить дополнительную информацию о них могу перейти по ссылке https://windowsnotes.ru/iis/application-pool-identities-v-iis/). Указываем режим конвейера Integrated и последнюю доступную версию .net clr.
После того, как нами были описаны настройки WebPool’а мы должны сконфигурировать сайт, для чего снова создается новый компонент. Назовем его «InstallWebsite»:
-
Конфигурация сайта производится с использованием свойств тега
<iis:WebSite>
. Через свойства тега передаем его Id (помним, что он должен быть уникальным), описание и виртуальную директорию. Чтобы после установки получить сразу работающий проект, не требующий от пользователя дополнительных телодвижений добавим свойствамAutoStart
иStartOnInstall
значение yes. -
С помощью свойств тега
iis:WebAddress
передадим адрес сайта: в нашем случае он запустится локально на порту 8085 (можете выбрать любой доступный порт) -
В теге
iis:WebApplication
мы указали связь сайта с WebPool’ом
На этом IIS можно считать сконфигурированным. Теперь создаем группу компонентов с названием BlazorAppIisConfiguration (см. 35-ю строчку) и закидываем в нее два наших созданных выше компонента (с описанием конфигурации AppPool’а и сайта).
И снова Product.wxs
Снова открываем файл Product.wxs. Добавляем перед закрывающимся тегом </Product>
тег <Feature>
со следующим содержимым:
<Feature Id="BlazorAppFeature"
Title="BlazorWasmApplication"
Level="1"
ConfigurableDirectory="INSTALLFOLDER"
AllowAdvertise="no"
Absent='disallow'>
<ComponentGroupRef Id="BlazorAppIisConfiguration" />
<ComponentGroupRef Id="PublishedComponents" />
</Feature>
Первые два свойства традиционно Id
и Название. Что касается свойства Level
– оно служит для включения (при значении «1») или исключения (при значении «0») фичи из процесса установки. Делается это, как правило, путем добавления публичного свойства (тег Property
), которое может принимать значение через аргументы командной строки или иными способами и последующим использованием через тег Condition
, который должен располагаться внутри тега <Feature>
. Обязательно разберем работу с условиями, но не в этой статье.
Свойство ConfigurableDirectory
указывает на название виртуальной директории в которой будет лежать наш программный продукт, нуждающийся в разворачивании на IIS. Свойства AllowAdvertise="no"
и Absent='disallow
‘ используем с указанными значениями, так как мы не планируем предоставлять пользователю возможность кастомизации процесса установки в части управления параметрами настройки IIS и записи файлов проекта.
Далее, внутрь указанного тега кладем ссылки на описанные ранее группы объектов (см. 7 и 8 строчки).
Теперь нам необходимо установить связь виртуальной директории, являющейся корневой для нашего проекта, с адресом в дисковом пространстве компьютера пользователя куда будет непосредственно установлен проект. Делается это следующим образом:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="InstallerForBlazorApp" />
</Directory>
</Directory>
</Fragment>
При создании проекта Wix внутри файла Product.wxs сразу после тега <Product>
у вас уже будет шаблон, обозначенный тегами <Fragment>
— замените его на код указанный выше. По сути, несмотря на то, что теги являются вложенными и кажется, что при установке будет создана иерархическая структура, фактически все файлы будут установлены в папку, которая будет выбрана пользователем во время установки, т.к. property WIXUI_INSTALDIR
(как было описано выше, с помощью этого свойства шаблону UI передается виртуальный путь) содержит ссылку на виртуальную директорию INSTALLFODER
, которая является корнем для нашего проекта.
Что касается тега Fragment
, то с помощью него достигается структурирование проекта. Раздел, помещенный внутрь тега Fragment
, может быть перемещен в отдельный файл или расположен практически в любом месте файла. Иначе, пришлось бы все инструкции для создания инсталлятора помещать внутрь тега Product
.
Конечный вариант файла Product.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="InstallerForBlazorApp" Language="1033" Version="1.0.0.0" Manufacturer="Developer" UpgradeCode="543f9f1d-2c37-403d-930c-f0eb8bf401ec">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" Platform="x64"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1"
Cabinet="media.cab"
EmbedCab="yes"
DiskPrompt="CD-ROM #1" />
<Property Id="DiskPrompt"
Value="InstallerForBlazorApp CD-ROM #1" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" ></Property>
<UIRef Id="WixUI_InstallDir"/>
<Feature Id="BlazorAppFeature"
Title="BlazorWasmApplication"
Level="1"
ConfigurableDirectory="INSTALLFOLDER"
AllowAdvertise="no"
Absent='disallow'>
<ComponentGroupRef Id="BlazorAppIisConfiguration" />
<ComponentGroupRef Id="PublishedComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="InstallerForBlazorApp" />
</Directory>
</Directory>
</Fragment>
</Wix>
Внимательный читатель заметит, что в конечном варианте отсутствует следующий кусок, который был описан вначале:
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<ComponentGroupRef Id="PublishedComponents"/>
</ComponentGroup>
</Fragment>
Для лаконичности .xml-описания в нашем случае можно отказаться от создания еще одной группы компонентов внутри файла Product.wxs и добавить ссылку на существующую группу в Feature
— см. 26 строку файла Product.wxs.
После того, как все необходимые .xml документы будут созданы, давайте соберем проект: правая кнопка мыши по проекту wix -> build. После сборки из папки проекта перейдем по следующему пути: ~\InstallerForBlazorApp\bin\Release (или Debug — в зависимости от выбранной вами конфигурации сборки проекта в Visual Studio) – в нем лежит собранный инсталлятор InstallerForBlazorApp.msi. Запускаем его:
Принимаем лицензию (так как мы не передавали файл лицензии, то имеем Lorem impsum…)
Далее мы имеем возможность выбрать директорию, в которую будет произведена установка продукта (по умолчанию, Program Files (x86))
Next, next, install.
После положительного ответа на запрос разрешения на установку, продукт будет развернут в указанной директории.
Убедиться в этом вы можете сами, перейдя в директорию установки. Однако, это еще не говорит о том, что все прошло по плану. Откройте IIS -> Application Pool. Там должен появится созданный нами новый пул приложений
А в папке сайтов появится новый BlazorAppWasm
Нажимаем на Browse: http://127.0.0.1:8085/ и в браузере открывается страница установленного проекта, после чего установку можно считать успешной.
Удалить приложение вы можете или через установку и удаление программ, или непосредственно через инсталлятор путем его повторного запуска. При этом, будет произведено не только удаление файлов, но и пула с сайтом из IIS.
Таким образом, можно резюмировать, что технология Wix позволяет относительно быстро описать и собрать инсталлятор (который позволяет произвести выбор директории установки) для достаточно большого проекта – главное знать какие теги и в каком порядке использовать.
При наличии у хабрчан интереса к данной теме, я планирую подробно рассказать про работу с реестрами, создание пользовательских действий, разработку интерфейса, внедрение скриптов в процесс установки, написание бутстрапера, а также использование расширений и инструментов, поставляемых вместе с Wix.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Продолжать писать про Wix toolset?
25.58% Я томат — любому варианту рад11
Проголосовали 43 пользователя. Воздержался 1 пользователь.
Nullsoft Scriptable Install System is also known as NSIS open-source system to create Windows application installers. NSIS is a script-based system allowing you to create the logic behind your installer/setup file in a complex way to install tasks. NSIS offers plug-ins and other scripts, for example, to download/install 3rd-party files or communicate with Windows.
The tutorial application
This tutorial will guide you through installing and creating your first Windows installer with Nullsoft Scriptable Install System and how to compile your project. Captura Portable will be used as «our application» for the sake of this tutorial.
Installation
Head to NSIS official site and download the latest release and install it. Run NSIS and you will be welcomed with a menu like below, It’s always a good practice to read the Documentation before jumping in to it.
Structure
Structure is key, not only in code/scripting but also in everyday life. Structuring your files and folder is important for easy access, locate various files and versions.
Navigate to your Documents and create a new folder named NSIS and sub-folder after your project name, In our case Captura. Your path should look something like this
C:\Users\Bitxo\Documents\NSIS\Captura
Navigate in to your project directory «Captura» and create following files and folders.
Captura ├── app ├── assets ├── license.txt ├── redist └── setup.nsi
- app directory is for your project, You can also pretend that it is «root» directory for your project.
- assets: This directory is only for NSIS script.
- license.txt: (Optional) Can be located in your app directory. Show license to end-user in the install application.
- redist: this directory you can include DirectX or any other third-party software needed for your install application (Parent folder for each third-party software).
Your file/directory structure should look similar to the Captura example witch also covers third-party software in its tree.
Captura ├── app │ ├── captura-cli.exe │ ├── captura-cli.exe.config │ ├── captura.exe │ ├── captura.exe.config │ ├── keymaps │ ├── languages │ ├── lib │ ├── licenses ├── assets │ ├── head.bmp │ └── welcome.bmp ├── license.txt ├── redist │ └── directx │ └── dxwebsetup.exe │ └── setup.nsi
BITMAP (Optional)
NSIS offers header and welcome image in bmp format. Great opportunity to promote your company or maybe another project you may have.
MUI_HEADERIMAGE_BITMAP | MUI_WELCOMEFINISHPAGE_BITMAP |
---|---|
head.bmp | welcome.bmp |
150×57 pixels | 164×314 pixels |
The beginning of scripting
NSIS language for scripting is something between PHP and assembly, slightly more to assembly.
Lines starting with ; are comments, You may also comment out lines of code but comments placed before code will be ignored.
Edit setup.nsi in your project directory with your favorite text editor. At the start of the document we need to including a few things.
-
MUI2.nsh also know as Modern User Interface 2 provides a user interface (UI).
-
logiclib.nsh provides familiar logic and easier flow with things like if, else, while loops etc.
;-------------------------------- ; Includes !include "MUI2.nsh" !include "logiclib.nsh"
About !define
The !define commands will add gflag to the global define list, in other words when you declare !define it will be global and accessed all over the script and even inside another !defines.
Create global define with !define
Retrieve data from hello
Remove item from the global define list with undef
Add defines
The purpose with this define list is to avoid entering same content multiple times, In the next step this will make sense.
;-------------------------------- ; Custom defines !define NAME "Captura" !define APPFILE "captura.exe" !define VERSION "7.0.0" !define SLUG "${NAME} v${VERSION}"
General
At first glance you noticed repeated calls to custom defines in the previous step and other arguments.
- Name: Set name of the installer window.
- OutFile: Set name of compiled installer by MakeNSISW.
- InstallDir: Specify the default installation directory manualy or with constants.
- InstallDirRegKey: Tells the installer to check a string in the registry and use it as the install dir if valid.
- RequestExecutionLevel: Specifies request by user level.
;-------------------------------- ; General Name "${NAME}" OutFile "${NAME} Setup.exe" InstallDir "$PROGRAMFILES\${NAME}" InstallDirRegKey HKCU "Software\${NAME}" "" RequestExecutionLevel admin
Icon & Banners
Set Icon, Banners and Welcome title message.
;-------------------------------- ; UI !define MUI_ICON "assets\captura.ico" !define MUI_HEADERIMAGE !define MUI_WELCOMEFINISHPAGE_BITMAP "assets\welcome.bmp" !define MUI_HEADERIMAGE_BITMAP "assets\head.bmp" !define MUI_ABORTWARNING !define MUI_WELCOMEPAGE_TITLE "${SLUG} Setup"
Pages
Define pages to use with !insertmacro witch inserts content from a macro created with !macro. Pages will appear in the order you set.
;-------------------------------- ; Pages ; Installer pages !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "license.txt" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ; Set UI language !insertmacro MUI_LANGUAGE "English"
Install DirectX
Create option to install third-party software like DirectX.
- SetOutPath: Sets output path and create.
- File: Extract file(s) to output path.
- DetailPrint: Add string to details view.
- ExecWait: Execute program and wait for process to end.
;-------------------------------- ; Section - DirectX Section "DirectX" DirectX SetOutPath "$INSTDIR\Redist" File "redist\directx\dxwebsetup.exe" DetailPrint "Running DirectX Setup..." ExecWait "$INSTDIR\Redist\dxwebsetup.exe" DetailPrint "Finished DirectX Setup" SectionEnd
Install Captura
This section is hidden from the user with -hidden argument and force check with SectionIn RO. WriteRegStr stores the installation folder and WriteUninstaller creates the uninstaller.
;-------------------------------- ; Section - Install App Section "-hidden app" SectionIn RO SetOutPath "$INSTDIR" File /r "app\*.*" WriteRegStr HKCU "Software\${NAME}" "" $INSTDIR WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd
Create Shortcut
Create option to create desktop Shortcut for user or not.
;-------------------------------- ; Section - Shortcut Section "Desktop Shortcut" DeskShort CreateShortCut "$DESKTOP\${NAME}.lnk" "$INSTDIR\${APPFILE}" SectionEnd
Set Section Description
Set description for each section visible.
;-------------------------------- ; Descriptions ;Language strings LangString DESC_DeskShort ${LANG_ENGLISH} "Create Shortcut on Dekstop." LangString DESC_DirectX ${LANG_ENGLISH} "Microsoft DirectX is a collection of application programming interfaces for handling tasks related to multimedia." ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${DeskShort} $(DESC_DeskShort) !insertmacro MUI_DESCRIPTION_TEXT ${DirectX} $(DESC_DirectX) !insertmacro MUI_FUNCTION_DESCRIPTION_END
Remove empty parent directories
RMDirUP is used to recursively delete empty parent folders of a given folder. This function is used with uninstaller. The command RMDir /r «$INSTDIR» cant remove parent folder.
;-------------------------------- ; Remove empty parent directories Function un.RMDirUP !define RMDirUP '!insertmacro RMDirUPCall' !macro RMDirUPCall _PATH push '${_PATH}' Call un.RMDirUP !macroend ; $0 - current folder ClearErrors Exch $0 ;DetailPrint "ASDF - $0\.." RMDir "$0\.." IfErrors Skip ${RMDirUP} "$0\.." Skip: Pop $0 FunctionEnd
Remove empty parent directories
This section in called with uninstaller. Removes shortcut and any other associated files. Command RMDir /r «$INSTDIR» does not remove the parent folder there for is function RMDirUP called last for cleanup.
;-------------------------------- ; Section - Uninstaller Section "Uninstall" ;Delete Shortcut Delete "$DESKTOP\${NAME}.lnk" ;Delete Uninstall Delete "$INSTDIR\Uninstall.exe" ;Delete Folder RMDir /r "$INSTDIR" ${RMDirUP} "$INSTDIR" DeleteRegKey /ifempty HKCU "Software\${NAME}" SectionEnd
Compile
Last to do is compiling the script and get your setup file. Select setup.nsi then MOUSE + RIGHT-CLICK and Compile NSIS Script. When compiling is finished, Press Test installer