(NET) NET (2019)

Windows installers (VS installer, Wix, MakeMsi, InnoSetup, Nsis)


Article about windows installer is one of the ancient articles of my blog (Windows Installer. 2003 year). Also many times I have created my own installers on VB6. Usually windows installer can be start without .NET Framework on target computer, therefore windows installer need to create by unmanaged code. There are only one workable technology on MS Platform to create GUI unmanaged code - VB6. Therefore it's impossible to avoid exactly VB6 for own custom installers.

There are two opposite way of installation process

You can install ORCA from Windows Installer Development Tools to see into MSI-package, also installation of Wix contains description of each parameters and fields in MSI-package.

1. Microsoft Visual Studio Installer

The simplest installer is Microsoft Visual Studio Installer. This is description from MS about Visual Studio Installer Deployment.



It working fine and simple, but only on simple project. But unexpectedly in some project this installer begin to stupefy. For example I assembly my project on 112 version of SQLlite, but VS Installer unexpectedly and unreasonable require a 111 version of SQLite. This induce a error to target client computer.



And at common this installer uncontrolled and doing incomprehensible operation. Sometimes it going for assembly to GAC, sometimes to NUGET packages, sometimes to VS assembly cache. Sometimes is exclude most important library. I don't understand how this installer calculate library dependences.



There are also another questions of this installer, for example how to create a banner for installation.



2. Wix installer

There are opensource and full manually controlled alternatives for Visual Studio Installer - Wix Installer. MSI database is fill manually by XML languages. You can add any function supported MsiExec, installation banner, EULA, manually add all needed files, own custom code and so on. Project also has full documentation to own future and full documentation to Windows installer(MsiExec).



Below you can see a example of Wix project. In this project I use SQLite without native library - this is a my package.config in this case.


   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <packages>
   3:    <package id="AutoClosingMessageBox" version="1.0.0.2" targetFramework="net48" />
   4:    <package id="EntityFramework" version="6.4.0" targetFramework="net48" />
   5:    <package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net48" />
   6:    <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.6.0" targetFramework="net48" />
   7:    <package id="Microsoft.IdentityModel.Logging" version="5.6.0" targetFramework="net48" />
   8:    <package id="Microsoft.IdentityModel.Tokens" version="5.6.0" targetFramework="net48" />
   9:    <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net48" />
  10:    <package id="System.Configuration.ConfigurationManager" version="4.7.0" targetFramework="net48" />
  11:    <package id="System.Data.SQLite" version="1.0.112.0" targetFramework="net48" />
  12:    <package id="System.Data.SQLite.Core" version="1.0.112.0" targetFramework="net48" />
  13:    <package id="System.Data.SQLite.EF6" version="1.0.112.0" targetFramework="net48" />
  14:    <package id="System.Data.SQLite.Linq" version="1.0.112.0" targetFramework="net48" />
  15:    <package id="System.Security.AccessControl" version="4.7.0" targetFramework="net48" />
  16:    <package id="System.Security.Permissions" version="4.7.0" targetFramework="net48" />
  17:    <package id="System.Security.Principal.Windows" version="4.7.0" targetFramework="net48" />
  18:    <package id="TA-Lib" version="0.5.0.3" targetFramework="net48" />
  19:  </packages>

This is app.config of my application.


   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <configuration>
   3:    <configSections>
   4:      <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
   5:        <section name="Folex_2.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
   6:      </sectionGroup>
   7:      <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
   8:      <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
   9:      <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  10:      <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  11:    </configSections>
  12:    <startup>
  13:      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
  14:    </startup>
  15:    <runtime>
  16:      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  17:        <dependentAssembly>
  18:          <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
  19:          <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
  20:        </dependentAssembly>
  21:        <dependentAssembly>
  22:          <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
  23:          <bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
  24:        </dependentAssembly>
  25:        <dependentAssembly>
  26:          <assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
  27:        </dependentAssembly>
  28:        <dependentAssembly>
  29:          <assemblyIdentity name="System.Data.SQLite.EF6" publicKeyToken="db937bc2d44ff139" culture="neutral" />
  30:        </dependentAssembly>
  31:      </assemblyBinding>
  32:    </runtime>
  33:    <applicationSettings>
  34:      <Folex_2.My.MySettings>
  35:        <setting name="BaseApiURL" serializeAs="String">
  36:          <value>https://testsystemapi.folex.io</value>
  37:        </setting>
  38:      </Folex_2.My.MySettings>
  39:    </applicationSettings>
  40:    <entityFramework>
  41:      <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  42:      <providers>
  43:        <!--<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />-->
  44:        <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
  45:        <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
  46:      </providers>
  47:    </entityFramework>
  48:    <system.data>
  49:      <DbProviderFactories>
  50:        <remove invariant="System.Data.SQLite.EF6" />
  51:        <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
  52:        <remove invariant="System.Data.SQLite" />
  53:        <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
  54:    </system.data>
  55:    <connectionStrings>
  56:      <add name="FolexDb" connectionString="metadata=res://*/FolexDB.csdl|res://*/FolexDB.ssdl|res://*/FolexDB.msl;provider=System.Data.SQLite.EF6;provider connection string=&quot;data source=C:\Users\khark\AppData\Local\Folex-1\FolexDB.sqlite&quot;" providerName="System.Data.EntityClient" />
  57:    </connectionStrings>
  58:  </configuration>

And this is result folder for this case.




For use list of files I receive filelist by Dir /s /b, create this SQL command for generate XML tag with guid, then format XML. Below you can see full my project. EULA must bu created by wordpad with rtf format.



This is SQL command for generating XML for Wix project in my case.


   1:  create table #tmp1 (i INT IDENTITY(1, 1) primary key, N nvarchar (200))
   2:  Insert into #tmp1 (N) Values('AutoClosingMessageBox.dll')
   3:  Insert into #tmp1 (N) Values('BinanceExcangeInfo.txt')
   4:  Insert into #tmp1 (N) Values('EntityFramework.dll')
   5:  Insert into #tmp1 (N) Values('EntityFramework.SqlServer.dll')
   6:  Insert into #tmp1 (N) Values('EntityFramework.SqlServer.xml')
   7:  Insert into #tmp1 (N) Values('EntityFramework.xml')
   8:  Insert into #tmp1 (N) Values('Folex-1.exe')
   9:  Insert into #tmp1 (N) Values('Folex-1.exe.config')
  10:  Insert into #tmp1 (N) Values('Folex-1.pdb')
  11:  Insert into #tmp1 (N) Values('Folex-1.xml')
  12:  Insert into #tmp1 (N) Values('Microsoft.CSharp.dll')
  13:  Insert into #tmp1 (N) Values('Microsoft.IdentityModel.JsonWebTokens.dll')
  14:  Insert into #tmp1 (N) Values('Microsoft.IdentityModel.JsonWebTokens.xml')
  15:  Insert into #tmp1 (N) Values('Microsoft.IdentityModel.Logging.dll')
  16:  Insert into #tmp1 (N) Values('Microsoft.IdentityModel.Logging.xml')
  17:  Insert into #tmp1 (N) Values('Microsoft.IdentityModel.Tokens.dll')
  18:  Insert into #tmp1 (N) Values('Microsoft.IdentityModel.Tokens.xml')
  19:  Insert into #tmp1 (N) Values('Newtonsoft.Json.dll')
  20:  Insert into #tmp1 (N) Values('Newtonsoft.Json.xml')
  21:  Insert into #tmp1 (N) Values('SQLitePCLRaw.batteries_v2.dll')
  22:  Insert into #tmp1 (N) Values('SQLitePCLRaw.core.dll')
  23:  Insert into #tmp1 (N) Values('SQLitePCLRaw.nativelibrary.dll')
  24:  Insert into #tmp1 (N) Values('SQLitePCLRaw.provider.dynamic_cdecl.dll')
  25:  Insert into #tmp1 (N) Values('System.Buffers.dll')
  26:  Insert into #tmp1 (N) Values('System.Buffers.xml')
  27:  Insert into #tmp1 (N) Values('System.ComponentModel.DataAnnotations.dll')
  28:  Insert into #tmp1 (N) Values('System.Configuration.ConfigurationManager.dll')
  29:  Insert into #tmp1 (N) Values('System.Configuration.ConfigurationManager.xml')
  30:  Insert into #tmp1 (N) Values('System.Configuration.dll')
  31:  Insert into #tmp1 (N) Values('System.Data.dll')
  32:  Insert into #tmp1 (N) Values('System.Data.SQLite.dll')
  33:  Insert into #tmp1 (N) Values('System.Data.SQLite.dll.config')
  34:  Insert into #tmp1 (N) Values('System.Data.SQLite.EF6.dll')
  35:  Insert into #tmp1 (N) Values('System.Data.SQLite.Linq.dll')
  36:  Insert into #tmp1 (N) Values('System.Data.SQLite.xml')
  37:  Insert into #tmp1 (N) Values('System.dll')
  38:  Insert into #tmp1 (N) Values('System.Drawing.dll')
  39:  Insert into #tmp1 (N) Values('System.IdentityModel.Tokens.Jwt.dll')
  40:  Insert into #tmp1 (N) Values('System.IdentityModel.Tokens.Jwt.xml')
  41:  Insert into #tmp1 (N) Values('System.Memory.dll')
  42:  Insert into #tmp1 (N) Values('System.Memory.xml')
  43:  Insert into #tmp1 (N) Values('System.Net.dll')
  44:  Insert into #tmp1 (N) Values('System.Net.Http.dll')
  45:  Insert into #tmp1 (N) Values('System.Net.Http.Formatting.dll')
  46:  Insert into #tmp1 (N) Values('System.Net.Http.Formatting.xml')
  47:  Insert into #tmp1 (N) Values('System.Numerics.dll')
  48:  Insert into #tmp1 (N) Values('System.Numerics.Vectors.dll')
  49:  Insert into #tmp1 (N) Values('System.Numerics.Vectors.xml')
  50:  Insert into #tmp1 (N) Values('System.Runtime.CompilerServices.Unsafe.dll')
  51:  Insert into #tmp1 (N) Values('System.Runtime.CompilerServices.Unsafe.xml')
  52:  Insert into #tmp1 (N) Values('System.Security.AccessControl.dll')
  53:  Insert into #tmp1 (N) Values('System.Security.AccessControl.xml')
  54:  Insert into #tmp1 (N) Values('System.Security.dll')
  55:  Insert into #tmp1 (N) Values('System.Security.Permissions.dll')
  56:  Insert into #tmp1 (N) Values('System.Security.Permissions.xml')
  57:  Insert into #tmp1 (N) Values('System.Security.Principal.Windows.dll')
  58:  Insert into #tmp1 (N) Values('System.Security.Principal.Windows.xml')
  59:  Insert into #tmp1 (N) Values('System.ServiceProcess.dll')
  60:  Insert into #tmp1 (N) Values('System.Transactions.dll')
  61:  Insert into #tmp1 (N) Values('System.Windows.Forms.dll')
  62:  Insert into #tmp1 (N) Values('System.Xml.dll')
  63:  Insert into #tmp1 (N) Values('TA-Lib-Core.dll')
  64:  Insert into #tmp1 (N) Values('WindowsBase.dll')
  65:  Insert into #tmp1 (N) Values('x64\SQLite.Interop.dll')
  66:  Insert into #tmp1 (N) Values('x86\SQLite.Interop.dll')
  67:  Insert into #tmp1 (N) Values('runtimes\win-arm\native\e_sqlite3.dll')
  68:  Insert into #tmp1 (N) Values('runtimes\win-x64\native\e_sqlite3.dll')
  69:  Insert into #tmp1 (N) Values('runtimes\win-x86\native\e_sqlite3.dll')
  70:   
  71:  select '<Component Id="'+ N +'" Guid="'+ convert(nvarchar(52),Newid()) + '">' +
  72:         '<File Id="'+ N +'" Source="$(var.sourceFolder)\'+ N +'" KeyPath="yes" Checksum="yes"/>' + 
  73:         '</Component>'
  74:  from #tmp1 order by N
  75:   
  76:   --select '<ComponentRef Id="'+ N +'" />' from #tmp1 order by N
  77:   
  78:   
  79:  Drop table #tmp1
  80:   
  81:  select newid()


Result looking fine.




Below you can see full code of this project:


   1:  <?xml version="1.0" encoding="UTF-8"?>
   2:  <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"   xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
   3:    <?define sourceFolder="E:\Projects\Folex\Folex-1\Folex-1\bin\Debug" ?>
   4:   
   5:    <?define NetFx48MinRelease = 528040 ?>
   6:    <?define NetFx48WebLink = https://go.microsoft.com/fwlink/?LinkId=2085155 ?>
   7:    <?define NetFx48RedistLink = https://go.microsoft.com/fwlink/?linkid=2088631 ?>
   8:    <?define NetFx48EulaLink = https://referencesource.microsoft.com/license.html ?>
   9:   
  10:    <Product Id="*" Language="1033" Version="1.0.0.2" Manufacturer="Folex" Name="FolexBot" UpgradeCode="BCB9D9C0-290C-4749-A368-725961EF2FCD" >
  11:      <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
  12:   
  13:      <Media Id="1" Cabinet="FolexBot.cab" EmbedCab="yes" />
  14:      <PropertyRef Id="WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED" />
  15:      <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
  16:      <UIRef Id="WixUI_InstallDir" />
  17:      <Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONROOTDIRECTORY" />
  18:      <WixVariable Id="WixUIDialogBmp" Value="E:\Screenshot\Folex-T302019_031345.png" />
  19:      <WixVariable Id="WixUILicenseRtf" Value="E:\Projects\Folex\Folex-2\WixSetup1\Eula.rtf" />
  20:   
  21:      <!-- Add installer icon -->
  22:      <Icon Id="icon.ico" SourceFile="E:\Projects\Folex\Folex-2\Folex-2\folex_t262019_160724_Xzz_icon.ico"/>
  23:      <Property Id="ARPPRODUCTICON" Value="folex_t262019_160724_Xzz_icon.ico" />
  24:   
  25:      <!-- Abort installation if the .NET Framework 4.8 is not installed -->
  26:      <Condition Message="FolexBot requires .NET Framework 4.6.2 or higher.">
  27:        <![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>
  28:      </Condition>
  29:   
  30:      <!-- Step  1: Define the directory structure -->
  31:      <Directory Id="TARGETDIR" Name="SourceDir">
  32:        <Directory Id="ProgramFilesFolder" Name="PFiles">
  33:          <Directory  Id="APPLICATIONROOTDIRECTORY" Name="FolexBot">
  34:            <Directory Id="APPLICATIONROOTDIRECTORY_X86" Name="X86" >
  35:            </Directory>
  36:            <Directory Id="APPLICATIONROOTDIRECTORY_X64" Name="X64" >
  37:            </Directory>
  38:            <Directory Id="APPLICATIONROOTDIRECTORY_runtimes" Name="runtimes" >
  39:              <Directory Id="APPLICATIONROOTDIRECTORY_winarm" Name="win-arm" >
  40:                <Directory Id="APPLICATIONROOTDIRECTORY_winarmnative" Name="native" />
  41:              </Directory>
  42:              <Directory Id="APPLICATIONROOTDIRECTORY_winx64" Name="win-x64" >
  43:                <Directory Id="APPLICATIONROOTDIRECTORY_winx64native" Name="native" />
  44:              </Directory>
  45:              <Directory Id="APPLICATIONROOTDIRECTORY_winx86" Name="win-x86" >
  46:                <Directory Id="APPLICATIONROOTDIRECTORY_winx86native" Name="native" />
  47:              </Directory>
  48:            </Directory>
  49:          </Directory>
  50:        </Directory>
  51:        <Directory Id="DesktopFolder" Name="Desktop">
  52:        </Directory>
  53:      </Directory>
  54:   
  55:      <!-- Step 2: Add files to your installer package -->
  56:      <DirectoryRef Id="APPLICATIONROOTDIRECTORY">
  57:   
  58:        <Component Id="AutoClosingMessageBox.dll" Guid="4A46AD9A-792B-4ED0-BA88-12C0B3381F57">
  59:          <File Id="AutoClosingMessageBox.dll" Source="$(var.sourceFolder)\AutoClosingMessageBox.dll" KeyPath="yes" Checksum="yes" />
  60:        </Component>
  61:        <Component Id="BinanceExcangeInfo.txt" Guid="8F7054A2-97D8-43B8-AFFC-D3F1E0297600">
  62:          <File Id="BinanceExcangeInfo.txt" Source="$(var.sourceFolder)\BinanceExcangeInfo.txt" KeyPath="yes" Checksum="yes" />
  63:        </Component>
  64:        <Component Id="EntityFramework.dll" Guid="E885E06F-7425-447A-8BEA-690CF426B9F8">
  65:          <File Id="EntityFramework.dll" Source="$(var.sourceFolder)\EntityFramework.dll" KeyPath="yes" Checksum="yes" />
  66:        </Component>
  67:        <Component Id="EntityFramework.SqlServer.dll" Guid="D41B305C-8AF7-4CBF-9EA3-1CAA2D5341A2">
  68:          <File Id="EntityFramework.SqlServer.dll" Source="$(var.sourceFolder)\EntityFramework.SqlServer.dll" KeyPath="yes" Checksum="yes" />
  69:        </Component>
  70:        <Component Id="EntityFramework.SqlServer.xml" Guid="5F283B1D-A4E7-4A08-B3AC-CD05B5D7196B">
  71:          <File Id="EntityFramework.SqlServer.xml" Source="$(var.sourceFolder)\EntityFramework.SqlServer.xml" KeyPath="yes" Checksum="yes" />
  72:        </Component>
  73:        <Component Id="EntityFramework.xml" Guid="D6C96816-43E1-43E8-94E7-689085FD8E0F">
  74:          <File Id="EntityFramework.xml" Source="$(var.sourceFolder)\EntityFramework.xml" KeyPath="yes" Checksum="yes" />
  75:        </Component>
  76:        <Component Id="Folex_1.exe" Guid="BFED9374-223F-4737-BC07-96EEE503F54D">
  77:          <File Id="Folex_1.exe" Source="$(var.sourceFolder)\Folex-1.exe" KeyPath="yes" Checksum="yes" />
  78:        </Component>
  79:        <Component Id="Folex_1.exe.config" Guid="69919CCE-6BEE-430D-BCA4-C999C3615DE5">
  80:          <File Id="Folex_1.exe.config" Source="$(var.sourceFolder)\Folex-1.exe.config" KeyPath="yes" Checksum="yes" />
  81:        </Component>
  82:        <Component Id="Folex_1.pdb" Guid="24F0D1ED-36F2-4D5C-96C1-F1445382A483">
  83:          <File Id="Folex_1.pdb" Source="$(var.sourceFolder)\Folex-1.pdb" KeyPath="yes" Checksum="yes" />
  84:        </Component>
  85:        <Component Id="Folex_1.xml" Guid="B67F957A-0DCE-4D4B-AB86-3086A94AF5C1">
  86:          <File Id="Fole_1.xml" Source="$(var.sourceFolder)\Folex-1.xml" KeyPath="yes" Checksum="yes" />
  87:        </Component>
  88:        <Component Id="Microsoft.CSharp.dll" Guid="4E51EA43-5DB9-40DE-9F25-84B2F7865B27">
  89:          <File Id="Microsoft.CSharp.dll" Source="$(var.sourceFolder)\Microsoft.CSharp.dll" KeyPath="yes" Checksum="yes" />
  90:        </Component>
  91:        <Component Id="Microsoft.IdentityModel.JsonWebTokens.dll" Guid="C056FB60-7E71-4475-8FF3-A800DBE8114C">
  92:          <File Id="Microsoft.IdentityModel.JsonWebTokens.dll" Source="$(var.sourceFolder)\Microsoft.IdentityModel.JsonWebTokens.dll" KeyPath="yes" Checksum="yes" />
  93:        </Component>
  94:        <Component Id="Microsoft.IdentityModel.JsonWebTokens.xml" Guid="94579C35-AF9E-45B4-AA0A-7FF54D67A327">
  95:          <File Id="Microsoft.IdentityModel.JsonWebTokens.xml" Source="$(var.sourceFolder)\Microsoft.IdentityModel.JsonWebTokens.xml" KeyPath="yes" Checksum="yes" />
  96:        </Component>
  97:        <Component Id="Microsoft.IdentityModel.Logging.dll" Guid="3EFC9804-D4D0-42E2-B31A-8C0316837591">
  98:          <File Id="Microsoft.IdentityModel.Logging.dll" Source="$(var.sourceFolder)\Microsoft.IdentityModel.Logging.dll" KeyPath="yes" Checksum="yes" />
  99:        </Component>
 100:        <Component Id="Microsoft.IdentityModel.Logging.xml" Guid="3174F5F1-3245-43A5-B372-31F89073684D">
 101:          <File Id="Microsoft.IdentityModel.Logging.xml" Source="$(var.sourceFolder)\Microsoft.IdentityModel.Logging.xml" KeyPath="yes" Checksum="yes" />
 102:        </Component>
 103:        <Component Id="Microsoft.IdentityModel.Tokens.dll" Guid="D9F65922-8889-484B-8DC6-B73C116C5346">
 104:          <File Id="Microsoft.IdentityModel.Tokens.dll" Source="$(var.sourceFolder)\Microsoft.IdentityModel.Tokens.dll" KeyPath="yes" Checksum="yes" />
 105:        </Component>
 106:        <Component Id="Microsoft.IdentityModel.Tokens.xml" Guid="76F8B273-876A-474E-8E70-0B9326ECD167">
 107:          <File Id="Microsoft.IdentityModel.Tokens.xml" Source="$(var.sourceFolder)\Microsoft.IdentityModel.Tokens.xml" KeyPath="yes" Checksum="yes" />
 108:        </Component>
 109:        <Component Id="Newtonsoft.Json.dll" Guid="D98E1BB2-323E-47FA-964C-C8C745CB3100">
 110:          <File Id="Newtonsoft.Json.dll" Source="$(var.sourceFolder)\Newtonsoft.Json.dll" KeyPath="yes" Checksum="yes" />
 111:        </Component>
 112:        <Component Id="Newtonsoft.Json.xml" Guid="25EB8F72-CB55-40EB-9A8A-98B61C8B7B6C">
 113:          <File Id="Newtonsoft.Json.xml" Source="$(var.sourceFolder)\Newtonsoft.Json.xml" KeyPath="yes" Checksum="yes" />
 114:        </Component>
 115:        <Component Id="SQLitePCLRaw.batteries_v2.dll" Guid="7F8DEF87-B40A-46FE-92EF-A399E45F08B1">
 116:          <File Id="SQLitePCLRaw.batteries_v2.dll" Source="$(var.sourceFolder)\SQLitePCLRaw.batteries_v2.dll" KeyPath="yes" Checksum="yes" />
 117:        </Component>
 118:        <Component Id="SQLitePCLRaw.core.dll" Guid="602B4235-7026-48DF-B0EA-86CC0CA9FCEB">
 119:          <File Id="SQLitePCLRaw.core.dll" Source="$(var.sourceFolder)\SQLitePCLRaw.core.dll" KeyPath="yes" Checksum="yes" />
 120:        </Component>
 121:        <Component Id="SQLitePCLRaw.nativelibrary.dll" Guid="B837B841-F62B-4A58-8A96-ECF40F72A480">
 122:          <File Id="SQLitePCLRaw.nativelibrary.dll" Source="$(var.sourceFolder)\SQLitePCLRaw.nativelibrary.dll" KeyPath="yes" Checksum="yes" />
 123:        </Component>
 124:        <Component Id="SQLitePCLRaw.provider.dynamic_cdecl.dll" Guid="9DA8CB89-F37B-4EE3-ACC3-AA8F9232CF1D">
 125:          <File Id="SQLitePCLRaw.provider.dynamic_cdecl.dll" Source="$(var.sourceFolder)\SQLitePCLRaw.provider.dynamic_cdecl.dll" KeyPath="yes" Checksum="yes" />
 126:        </Component>
 127:        <Component Id="System.Buffers.dll" Guid="70585FA5-7993-4FC3-BB15-BFF938D6181A">
 128:          <File Id="System.Buffers.dll" Source="$(var.sourceFolder)\System.Buffers.dll" KeyPath="yes" Checksum="yes" />
 129:        </Component>
 130:        <Component Id="System.Buffers.xml" Guid="0729D3B0-254D-4646-BF1C-5D8B28F1089F">
 131:          <File Id="System.Buffers.xml" Source="$(var.sourceFolder)\System.Buffers.xml" KeyPath="yes" Checksum="yes" />
 132:        </Component>
 133:        <Component Id="System.ComponentModel.DataAnnotations.dll" Guid="FE006E46-8266-4FC3-AEE8-EAE464DC91CE">
 134:          <File Id="System.ComponentModel.DataAnnotations.dll" Source="$(var.sourceFolder)\System.ComponentModel.DataAnnotations.dll" KeyPath="yes" Checksum="yes" />
 135:        </Component>
 136:        <Component Id="System.Configuration.ConfigurationManager.dll" Guid="94D67B5D-511E-43D2-841F-77ED92BC071A">
 137:          <File Id="System.Configuration.ConfigurationManager.dll" Source="$(var.sourceFolder)\System.Configuration.ConfigurationManager.dll" KeyPath="yes" Checksum="yes" />
 138:        </Component>
 139:        <Component Id="System.Configuration.ConfigurationManager.xml" Guid="EADD9218-5C69-40DD-B580-461F4F155322">
 140:          <File Id="System.Configuration.ConfigurationManager.xml" Source="$(var.sourceFolder)\System.Configuration.ConfigurationManager.xml" KeyPath="yes" Checksum="yes" />
 141:        </Component>
 142:        <Component Id="System.Configuration.dll" Guid="32F412B2-13D1-457D-A729-0D2B950CB192">
 143:          <File Id="System.Configuration.dll" Source="$(var.sourceFolder)\System.Configuration.dll" KeyPath="yes" Checksum="yes" />
 144:        </Component>
 145:        <Component Id="System.Data.dll" Guid="2BF62B30-678E-4066-BCFA-B208B3EBBA27">
 146:          <File Id="System.Data.dll" Source="$(var.sourceFolder)\System.Data.dll" KeyPath="yes" Checksum="yes" />
 147:        </Component>
 148:        <Component Id="System.Data.SQLite.dll" Guid="B371E56E-BC36-4A8C-A44C-009210FFE926">
 149:          <File Id="System.Data.SQLite.dll" Source="$(var.sourceFolder)\System.Data.SQLite.dll" KeyPath="yes" Checksum="yes" />
 150:        </Component>
 151:        <Component Id="System.Data.SQLite.dll.config" Guid="1723610A-CDE9-46DB-A764-BD469E3640AF">
 152:          <File Id="System.Data.SQLite.dll.config" Source="$(var.sourceFolder)\System.Data.SQLite.dll.config" KeyPath="yes" Checksum="yes" />
 153:        </Component>
 154:        <Component Id="System.Data.SQLite.EF6.dll" Guid="06776F13-9B33-4F5D-93DE-E3664CE76868">
 155:          <File Id="System.Data.SQLite.EF6.dll" Source="$(var.sourceFolder)\System.Data.SQLite.EF6.dll" KeyPath="yes" Checksum="yes" />
 156:        </Component>
 157:        <Component Id="System.Data.SQLite.Linq.dll" Guid="B0A600A8-C996-4EF8-BCFC-41D072B42E6B">
 158:          <File Id="System.Data.SQLite.Linq.dll" Source="$(var.sourceFolder)\System.Data.SQLite.Linq.dll" KeyPath="yes" Checksum="yes" />
 159:        </Component>
 160:        <Component Id="System.Data.SQLite.xml" Guid="460785E4-D7A8-4B07-82C6-5292D1E4ED62">
 161:          <File Id="System.Data.SQLite.xml" Source="$(var.sourceFolder)\System.Data.SQLite.xml" KeyPath="yes" Checksum="yes" />
 162:        </Component>
 163:        <Component Id="System.dll" Guid="0F1A68EB-E16A-4391-8F46-0D4AD30B397F">
 164:          <File Id="System.dll" Source="$(var.sourceFolder)\System.dll" KeyPath="yes" Checksum="yes" />
 165:        </Component>
 166:        <Component Id="System.Drawing.dll" Guid="7B09FECF-EFE5-4124-A017-B45817F0E6F4">
 167:          <File Id="System.Drawing.dll" Source="$(var.sourceFolder)\System.Drawing.dll" KeyPath="yes" Checksum="yes" />
 168:        </Component>
 169:        <Component Id="System.IdentityModel.Tokens.Jwt.dll" Guid="47015ED9-7150-47F4-8650-4DE3D7E2B176">
 170:          <File Id="System.IdentityModel.Tokens.Jwt.dll" Source="$(var.sourceFolder)\System.IdentityModel.Tokens.Jwt.dll" KeyPath="yes" Checksum="yes" />
 171:        </Component>
 172:        <Component Id="System.IdentityModel.Tokens.Jwt.xml" Guid="5359474B-38E6-4207-A41B-0109DDB86D79">
 173:          <File Id="System.IdentityModel.Tokens.Jwt.xml" Source="$(var.sourceFolder)\System.IdentityModel.Tokens.Jwt.xml" KeyPath="yes" Checksum="yes" />
 174:        </Component>
 175:        <Component Id="System.Memory.dll" Guid="920534FF-A6B1-4BD8-8340-C28FE65C69A4">
 176:          <File Id="System.Memory.dll" Source="$(var.sourceFolder)\System.Memory.dll" KeyPath="yes" Checksum="yes" />
 177:        </Component>
 178:        <Component Id="System.Memory.xml" Guid="C05C3655-D234-4903-B0BF-809194B3FB6B">
 179:          <File Id="System.Memory.xml" Source="$(var.sourceFolder)\System.Memory.xml" KeyPath="yes" Checksum="yes" />
 180:        </Component>
 181:        <Component Id="System.Net.dll" Guid="68885485-4DCC-40CC-A710-C5D1A224C6AF">
 182:          <File Id="System.Net.dll" Source="$(var.sourceFolder)\System.Net.dll" KeyPath="yes" Checksum="yes" />
 183:        </Component>
 184:        <Component Id="System.Net.Http.dll" Guid="A5B08834-BA20-463D-A6E7-755EF12E3E4F">
 185:          <File Id="System.Net.Http.dll" Source="$(var.sourceFolder)\System.Net.Http.dll" KeyPath="yes" Checksum="yes" />
 186:        </Component>
 187:        <Component Id="System.Net.Http.Formatting.dll" Guid="51603271-E715-41B6-8E9C-FE1D3C76C70A">
 188:          <File Id="System.Net.Http.Formatting.dll" Source="$(var.sourceFolder)\System.Net.Http.Formatting.dll" KeyPath="yes" Checksum="yes" />
 189:        </Component>
 190:        <Component Id="System.Net.Http.Formatting.xml" Guid="C1CFEF70-559D-4FD4-B7EE-10A62F17DEBC">
 191:          <File Id="System.Net.Http.Formatting.xml" Source="$(var.sourceFolder)\System.Net.Http.Formatting.xml" KeyPath="yes" Checksum="yes" />
 192:        </Component>
 193:        <Component Id="System.Numerics.dll" Guid="E752967B-DE3B-443C-B1B1-BCB743CE5618">
 194:          <File Id="System.Numerics.dll" Source="$(var.sourceFolder)\System.Numerics.dll" KeyPath="yes" Checksum="yes" />
 195:        </Component>
 196:        <Component Id="System.Numerics.Vectors.dll" Guid="EB00C136-0DF6-41F6-93E0-71D93113F086">
 197:          <File Id="System.Numerics.Vectors.dll" Source="$(var.sourceFolder)\System.Numerics.Vectors.dll" KeyPath="yes" Checksum="yes" />
 198:        </Component>
 199:        <Component Id="System.Numerics.Vectors.xml" Guid="30E90E87-53A4-471E-957E-79CB234ED75F">
 200:          <File Id="System.Numerics.Vectors.xml" Source="$(var.sourceFolder)\System.Numerics.Vectors.xml" KeyPath="yes" Checksum="yes" />
 201:        </Component>
 202:        <Component Id="System.Runtime.CompilerServices.Unsafe.dll" Guid="A3EA417E-8DB3-4420-B5A2-B535573E1800">
 203:          <File Id="System.Runtime.CompilerServices.Unsafe.dll" Source="$(var.sourceFolder)\System.Runtime.CompilerServices.Unsafe.dll" KeyPath="yes" Checksum="yes" />
 204:        </Component>
 205:        <Component Id="System.Runtime.CompilerServices.Unsafe.xml" Guid="4E34E3EF-5BCE-4718-A420-7201D7D2F5DE">
 206:          <File Id="System.Runtime.CompilerServices.Unsafe.xml" Source="$(var.sourceFolder)\System.Runtime.CompilerServices.Unsafe.xml" KeyPath="yes" Checksum="yes" />
 207:        </Component>
 208:        <Component Id="System.Security.AccessControl.dll" Guid="9ABD9C77-7FA0-46F2-ADC3-ED0D0D61302D">
 209:          <File Id="System.Security.AccessControl.dll" Source="$(var.sourceFolder)\System.Security.AccessControl.dll" KeyPath="yes" Checksum="yes" />
 210:        </Component>
 211:        <Component Id="System.Security.AccessControl.xml" Guid="998EE23A-0C27-49E1-B94A-51185745ACA0">
 212:          <File Id="System.Security.AccessControl.xml" Source="$(var.sourceFolder)\System.Security.AccessControl.xml" KeyPath="yes" Checksum="yes" />
 213:        </Component>
 214:        <Component Id="System.Security.dll" Guid="7FFE74C4-0BA3-437B-ABA0-9D66316328AA">
 215:          <File Id="System.Security.dll" Source="$(var.sourceFolder)\System.Security.dll" KeyPath="yes" Checksum="yes" />
 216:        </Component>
 217:        <Component Id="System.Security.Permissions.dll" Guid="0DF8B094-4752-4E88-B1F2-48645E9E3D9E">
 218:          <File Id="System.Security.Permissions.dll" Source="$(var.sourceFolder)\System.Security.Permissions.dll" KeyPath="yes" Checksum="yes" />
 219:        </Component>
 220:        <Component Id="System.Security.Permissions.xml" Guid="9748CFC9-61E5-422E-9275-07096F21079E">
 221:          <File Id="System.Security.Permissions.xml" Source="$(var.sourceFolder)\System.Security.Permissions.xml" KeyPath="yes" Checksum="yes" />
 222:        </Component>
 223:        <Component Id="System.Security.Principal.Windows.dll" Guid="8E367AA3-5A45-4C53-863F-78D27A9081ED">
 224:          <File Id="System.Security.Principal.Windows.dll" Source="$(var.sourceFolder)\System.Security.Principal.Windows.dll" KeyPath="yes" Checksum="yes" />
 225:        </Component>
 226:        <Component Id="System.Security.Principal.Windows.xml" Guid="A20FC50C-0045-46FE-A84E-C4A4320AF102">
 227:          <File Id="System.Security.Principal.Windows.xml" Source="$(var.sourceFolder)\System.Security.Principal.Windows.xml" KeyPath="yes" Checksum="yes" />
 228:        </Component>
 229:        <Component Id="System.ServiceProcess.dll" Guid="EDADC13A-DC31-441B-BDC6-B48752B7B717">
 230:          <File Id="System.ServiceProcess.dll" Source="$(var.sourceFolder)\System.ServiceProcess.dll" KeyPath="yes" Checksum="yes" />
 231:        </Component>
 232:        <Component Id="System.Transactions.dll" Guid="E173C842-71B7-48E2-A3A7-8E685D9E0521">
 233:          <File Id="System.Transactions.dll" Source="$(var.sourceFolder)\System.Transactions.dll" KeyPath="yes" Checksum="yes" />
 234:        </Component>
 235:        <Component Id="System.Windows.Forms.dll" Guid="989572D0-C7C8-42A6-AA38-EA22795F7F72">
 236:          <File Id="System.Windows.Forms.dll" Source="$(var.sourceFolder)\System.Windows.Forms.dll" KeyPath="yes" Checksum="yes" />
 237:        </Component>
 238:        <Component Id="System.Xml.dll" Guid="981136CC-E377-44C0-992C-A8092FB6135A">
 239:          <File Id="System.Xml.dll" Source="$(var.sourceFolder)\System.Xml.dll" KeyPath="yes" Checksum="yes" />
 240:        </Component>
 241:        <Component Id="TA_Lib_Core.dll" Guid="B78DEC8E-0D08-43EF-AAE4-B4FE0C00B959">
 242:          <File Id="TA_Lib_Core.dll" Source="$(var.sourceFolder)\TA-Lib-Core.dll" KeyPath="yes" Checksum="yes" />
 243:        </Component>
 244:        <Component Id="WindowsBase.dll" Guid="293D0AE8-8E85-4016-8D65-6B6CA60A5DE5">
 245:          <File Id="WindowsBase.dll" Source="$(var.sourceFolder)\WindowsBase.dll" KeyPath="yes" Checksum="yes" />
 246:        </Component>
 247:      </DirectoryRef>
 248:      <DirectoryRef Id="APPLICATIONROOTDIRECTORY_X86">
 249:        <Component Id="x86_SQLite.Interop.dll" Guid="49D973B9-B03B-4578-8534-455DCDE0A0AF"  >
 250:          <File Id="x86_SQLite.Interop.dll" Source="$(var.sourceFolder)\x86\SQLite.Interop.dll" KeyPath="yes" Checksum="yes" />
 251:        </Component>
 252:      </DirectoryRef>
 253:      <DirectoryRef Id="APPLICATIONROOTDIRECTORY_X64">
 254:        <Component Id="x64_SQLite.Interop.dll" Guid="F8F2180A-9C8D-4DC4-96E7-01284BCAB1F1"  >
 255:          <File Id="x64_SQLite.Interop.dll" Source="$(var.sourceFolder)\x64\SQLite.Interop.dll" KeyPath="yes" Checksum="yes" />
 256:        </Component>
 257:      </DirectoryRef>
 258:      <DirectoryRef Id="APPLICATIONROOTDIRECTORY_winarmnative">
 259:        <Component Id="runtimes_win_arm_native_e_sqlite3.dll" Guid="58F0A6DA-435A-43EB-81AD-5D146B9752AC">
 260:          <File Id="runtimes_win_arm_native_e_sqlite3.dll" Source="$(var.sourceFolder)\runtimes\win-arm\native\e_sqlite3.dll" KeyPath="yes" Checksum="yes" />
 261:        </Component>
 262:      </DirectoryRef>
 263:      <DirectoryRef Id="APPLICATIONROOTDIRECTORY_winx64native">
 264:        <Component Id="runtimes_win_x64_native_e_sqlite3.dll" Guid="7E65E08C-F39B-4A42-B10F-00AB596C65F2">
 265:          <File Id="runtimes_win_x64_native_e_sqlite3.dll" Source="$(var.sourceFolder)\runtimes\win-x64\native\e_sqlite3.dll" KeyPath="yes" Checksum="yes" />
 266:        </Component>
 267:      </DirectoryRef>
 268:      <DirectoryRef Id="APPLICATIONROOTDIRECTORY_winx86native">
 269:        <Component Id="runtimes_win_x86_native_e_sqlite3.dll" Guid="CC63755C-2809-41B6-A1C6-FA239638CFCE">
 270:          <File Id="runtimes_win_x86_native_e_sqlite3.dll" Source="$(var.sourceFolder)\runtimes\win-x86\native\e_sqlite3.dll" KeyPath="yes" Checksum="yes" />
 271:        </Component>
 272:      </DirectoryRef>
 273:   
 274:      <DirectoryRef Id="DesktopFolder">
 275:        <Component Id="ApplicationShortcutDesktop" Guid="184BE498-7123-49D9-92DE-BE8C189670A1">
 276:          <Shortcut Id="ApplicationDesktopShortcut"
 277:              Name="FolexBot"
 278:              Description="FolexBot"
 279:              Target="[#Folex_1.exe]"
 280:              WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
 281:          <RemoveFolder Id="DesktopFolder" On="uninstall"/>
 282:          <RegistryValue
 283:              Root="HKCU"
 284:              Key="Software/FolexBot"
 285:              Name="installed"
 286:              Type="integer"
 287:              Value="1"
 288:              KeyPath="yes"/>
 289:        </Component>
 290:      </DirectoryRef>
 291:      
 292:      
 293:      <!-- Step 3: Tell WiX to install the files -->
 294:      <Feature Id="Bot" Title="FolexBot" Level="1">
 295:        <ComponentRef Id="ApplicationShortcutDesktop" />
 296:        <ComponentRef Id="AutoClosingMessageBox.dll" />
 297:        <ComponentRef Id="BinanceExcangeInfo.txt" />
 298:        <ComponentRef Id="EntityFramework.dll" />
 299:        <ComponentRef Id="EntityFramework.SqlServer.dll" />
 300:        <ComponentRef Id="EntityFramework.SqlServer.xml" />
 301:        <ComponentRef Id="EntityFramework.xml" />
 302:        <ComponentRef Id="Folex_1.exe" />
 303:        <ComponentRef Id="Folex_1.exe.config" />
 304:        <ComponentRef Id="Folex_1.pdb" />
 305:        <ComponentRef Id="Folex_1.xml" />
 306:        <ComponentRef Id="Microsoft.CSharp.dll" />
 307:        <ComponentRef Id="Microsoft.IdentityModel.JsonWebTokens.dll" />
 308:        <ComponentRef Id="Microsoft.IdentityModel.JsonWebTokens.xml" />
 309:        <ComponentRef Id="Microsoft.IdentityModel.Logging.dll" />
 310:        <ComponentRef Id="Microsoft.IdentityModel.Logging.xml" />
 311:        <ComponentRef Id="Microsoft.IdentityModel.Tokens.dll" />
 312:        <ComponentRef Id="Microsoft.IdentityModel.Tokens.xml" />
 313:        <ComponentRef Id="Newtonsoft.Json.dll" />
 314:        <ComponentRef Id="Newtonsoft.Json.xml" />
 315:        <ComponentRef Id="SQLitePCLRaw.batteries_v2.dll" />
 316:        <ComponentRef Id="SQLitePCLRaw.core.dll" />
 317:        <ComponentRef Id="SQLitePCLRaw.nativelibrary.dll" />
 318:        <ComponentRef Id="SQLitePCLRaw.provider.dynamic_cdecl.dll" />
 319:        <ComponentRef Id="System.Buffers.dll" />
 320:        <ComponentRef Id="System.Buffers.xml" />
 321:        <ComponentRef Id="System.ComponentModel.DataAnnotations.dll" />
 322:        <ComponentRef Id="System.Configuration.ConfigurationManager.dll" />
 323:        <ComponentRef Id="System.Configuration.ConfigurationManager.xml" />
 324:        <ComponentRef Id="System.Configuration.dll" />
 325:        <ComponentRef Id="System.Data.dll" />
 326:        <ComponentRef Id="System.Data.SQLite.dll" />
 327:        <ComponentRef Id="System.Data.SQLite.dll.config" />
 328:        <ComponentRef Id="System.Data.SQLite.EF6.dll" />
 329:        <ComponentRef Id="System.Data.SQLite.Linq.dll" />
 330:        <ComponentRef Id="System.Data.SQLite.xml" />
 331:        <ComponentRef Id="System.dll" />
 332:        <ComponentRef Id="System.Drawing.dll" />
 333:        <ComponentRef Id="System.IdentityModel.Tokens.Jwt.dll" />
 334:        <ComponentRef Id="System.IdentityModel.Tokens.Jwt.xml" />
 335:        <ComponentRef Id="System.Memory.dll" />
 336:        <ComponentRef Id="System.Memory.xml" />
 337:        <ComponentRef Id="System.Net.dll" />
 338:        <ComponentRef Id="System.Net.Http.dll" />
 339:        <ComponentRef Id="System.Net.Http.Formatting.dll" />
 340:        <ComponentRef Id="System.Net.Http.Formatting.xml" />
 341:        <ComponentRef Id="System.Numerics.dll" />
 342:        <ComponentRef Id="System.Numerics.Vectors.dll" />
 343:        <ComponentRef Id="System.Numerics.Vectors.xml" />
 344:        <ComponentRef Id="System.Runtime.CompilerServices.Unsafe.dll" />
 345:        <ComponentRef Id="System.Runtime.CompilerServices.Unsafe.xml" />
 346:        <ComponentRef Id="System.Security.AccessControl.dll" />
 347:        <ComponentRef Id="System.Security.AccessControl.xml" />
 348:        <ComponentRef Id="System.Security.dll" />
 349:        <ComponentRef Id="System.Security.Permissions.dll" />
 350:        <ComponentRef Id="System.Security.Permissions.xml" />
 351:        <ComponentRef Id="System.Security.Principal.Windows.dll" />
 352:        <ComponentRef Id="System.Security.Principal.Windows.xml" />
 353:        <ComponentRef Id="System.ServiceProcess.dll" />
 354:        <ComponentRef Id="System.Transactions.dll" />
 355:        <ComponentRef Id="System.Windows.Forms.dll" />
 356:        <ComponentRef Id="System.Xml.dll" />
 357:        <ComponentRef Id="TA_Lib_Core.dll" />
 358:        <ComponentRef Id="WindowsBase.dll" />
 359:        <ComponentRef Id="x64_SQLite.Interop.dll" />
 360:        <ComponentRef Id="x86_SQLite.Interop.dll" />
 361:        <ComponentRef Id="runtimes_win_arm_native_e_sqlite3.dll" />
 362:        <ComponentRef Id="runtimes_win_x64_native_e_sqlite3.dll" />
 363:        <ComponentRef Id="runtimes_win_x86_native_e_sqlite3.dll" />
 364:      </Feature>
 365:      <!-- Step 4: Sign the MSI Install, else Web user will get unknown publisher message -->
 366:      <!-- Signing is done by executing a post-build batch file configured in project properties -->
 367:   
 368:    </Product>
 369:   
 370:  </Wix>

3. MakeMsi installer

MakeMsi is also good installer and time on time I use it, but sorry right now I have no screen related to this Installer. This is example of this installer MakeMSI example

4. InnoSetup installer from jrsoftware.org

This project do not create MSI-package for standard Microsoft Installer (MsiExec and Windows service related to MsiExec), this project similar to my own VB6 installer, but has great control of needed actions. It create .EXE file to avoid to send customer ZIP directory with project and doing other important operation like create Icon on desktop.

View of this installer look as standard installer with MSI-file. Usually it request only one click for installation and automatically start a program to be installed.



To create this installation no need to create VS project, need to create .ISS file compile and run it in special environment.




This is full code of my project.


   1:  #define MyAppName "FolexBot"
   2:  #define MyAppVersion "1.0.0.3"
   3:  #define MyAppExeName "Folex-2.exe"
   4:  #define MyAppId="C53F36AC-FBBC-4E35-AD7F-2A18C82020B1"
   5:   
   6:  [Setup]
   7:  AppId={#MyAppId}
   8:  AppName={#MyAppName}
   9:  AppVersion={#MyAppVersion}
  10:  WizardStyle=modern
  11:  DefaultDirName={autopf}\{#MyAppName}
  12:  DefaultGroupName={#MyAppName}
  13:  OutputDir="E:\Projects\Folex\Folex-2\InnoSetup"
  14:  OutputBaseFilename=FolexSetup
  15:  SourceDir="E:\Projects\Folex\Folex-2\Folex-2\bin\Debug"
  16:  Compression=lzma2
  17:  SolidCompression=yes
  18:  ; "ArchitecturesAllowed=x64" specifies that Setup cannot run on
  19:  ; anything but x64.
  20:  ;ArchitecturesAllowed=x64
  21:  ; "ArchitecturesInstallIn64BitMode=x64" requests that the install be
  22:  ; done in "64-bit mode" on x64, meaning it should use the native
  23:  ; 64-bit Program Files directory and the 64-bit view of the registry.
  24:  ;ArchitecturesInstallIn64BitMode=x64
  25:   
  26:  [Files]
  27:  Source: "*"; DestDir: "{app}"; 
  28:  Source: "E:\Projects\Folex\Folex-2\Folex-2\bin\Debug\X64\SQLite.Interop.dll"; DestDir: "{app}\X64\SQLite.Interop.dll"; 
  29:  Source: "E:\Projects\Folex\Folex-2\Folex-2\bin\Debug\X86\SQLite.Interop.dll"; DestDir: "{app}\X86\SQLite.Interop.dll"; 
  30:   
  31:  [Icons]
  32:  Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}";
  33:   
  34:  [Run]
  35:  Filename: "{app}\{#MyAppExeName}"
  36:   
  37:  [Code]
  38:   
  39:  /////////////////////////////////////////////////////////////////////
  40:  function GetUninstallString(): String;
  41:  var
  42:    sUnInstPath: String;
  43:    sUnInstallString: String;
  44:  begin
  45:    sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
  46:    sUnInstallString := '';
  47:    if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
  48:      RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
  49:    Result := sUnInstallString;
  50:  end;
  51:   
  52:   
  53:  /////////////////////////////////////////////////////////////////////
  54:  function IsUpgrade(): Boolean;
  55:  begin
  56:    Result := (GetUninstallString() <> '');
  57:  end;
  58:   
  59:   
  60:  /////////////////////////////////////////////////////////////////////
  61:  function UnInstallOldVersion(): Integer;
  62:  var
  63:    sUnInstallString: String;
  64:    iResultCode: Integer;
  65:  begin
  66:  // Return Values:
  67:  // 1 - uninstall string is empty
  68:  // 2 - error executing the UnInstallString
  69:  // 3 - successfully executed the UnInstallString
  70:   
  71:    // default return value
  72:    Result := 0;
  73:   
  74:    // get the uninstall string of the old app
  75:    sUnInstallString := GetUninstallString();
  76:    if sUnInstallString <> '' then begin
  77:      sUnInstallString := RemoveQuotes(sUnInstallString);
  78:      if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
  79:        Result := 3
  80:      else
  81:        Result := 2;
  82:    end else
  83:      Result := 1;
  84:  end;
  85:   
  86:  /////////////////////////////////////////////////////////////////////
  87:  procedure CurStepChanged(CurStep: TSetupStep);
  88:  begin
  89:    if (CurStep=ssInstall) then
  90:    begin
  91:      if (IsUpgrade()) then
  92:      begin
  93:        UnInstallOldVersion();
  94:      end;
  95:    end;
  96:  end;

This installer project support pascal code for custom action. Code above is intended to deinstallation older version of the same product.

5. NSIS by Nullsoft

NSIS installer is great project too, it working fine, full free, has full documentation and working as InnoSetup (without creating full MSI-database). Unfortunately, right now I have no screen with project with this installer.



Comments ( )
Link to this page: //www.vb-net.com/Installers/Index.htm
< THANKS ME>