Install prerequisites for winforms application with WiX bootstrapper - winforms

I have created a C# WinForms Application which depends on the .NET Framework Version 4.6.1 and GhostScript 9.2.1 (32-bit Windows). I made a simple Windows Installer ( .msi file) for the WinForms App, but the GhostScript library refused to install. Therefore, I decided to make a bundle installer using the WiX bootstrapper.
In the bootstrapper project I packaged the GhostScript exe installer and the simple msi installer from earlier. I think I also took care of the .NET framework in the first few lines of the bootstrapper.
Now, I'm still facing an issue while with the Bootstrap Installer. The issue is that the installation skips over the msi installer. How do I get the Bootstrap installation to successfully complete?
Here is the XML for the bootstrapper project:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle Name="Bootstrapper1" Version="1.0.0.0" Manufacturer="POD" UpgradeCode="390cbc0b-980b-4f35-a9de-a11228f75b69">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<PayloadGroup Id="NetFx461RedistPayload">
<Payload Name="redist\NDP461-KB3102436-x86-x64-AllOS-ENU.exe"
SourceFile="C:\Users\Admin\Downloads\NDP461-KB3102436-x86-x64-AllOS-ENU.exe"/>
</PayloadGroup>
<Chain>
<!-- TODO: Define the list of chained packages. -->
<!-- <MsiPackage SourceFile="path\to\your.msi" /> -->
<PackageGroupRef Id="NetFx461Web"/>
<ExePackage Id="Ghostscript_32_bit_Version_9.2.1"
Cache="yes"
Compressed="yes"
PerMachine="yes"
Permanent="yes"
Vital="yes"
SourceFile="C:\Users\Admin\Downloads\gs921w32new.exe"
InstallCommand="/passive /norestart" />
<MsiPackage Id="POD_Measuring_Tool"
Cache="yes"
Compressed="yes"
Permanent="yes"
Vital="yes"
SourceFile="C:\Users\Admin\Documents\POD\Workspace Folder\c# projects\6lumber\toolPOD\Debug\toolPOD.msi" />
</Chain>
</Bundle>
</Wix>
I reference the WixBalExtension and the WixNetFxExtension, and the msi file and ghostscript exe are from my computer.

The issue is that the installation skips over the msi installer.
This may indicate that the product is already install. MsiPackage will automatically detect if the msi is already installed by checking the product code in the registry.
The MsiPackage/#Permanent attribute will also mean that your product will not be removed when uninstalling your Bootstrapper - so check that you did remove your msi manually and logging helps with the -l logfile.txt switch.

Related

How to get current wpf project assembly version in wix toolset bootstrapper project?

I have a wpf project for which the installer is created by wix setup project. the wix setup project is compiled to get the .msi. The .exe is generated from the .msi file using wix bootstrapper project.Now my question is how to get the assembly version [assembly: AssemblyFileVersion("x.x.x.xx")] form wpf .cs file?
Andy is right, you will not be able to pull the version number from a .cs file as WiX does not compile or know anything to do with the C# code.
What you want to do is version your main executable file (presumably the .csproj application) using the assembly version properties. (These can be found in the project properties)
1) In the Product.wxs add said main executable as a file in the installer.
<Component Id='MainExecutable' Guid='*'>
<File Id='MainExe' Name='MainExe.exe' Source='Path-to-exe' KeyPath='yes' />
</Component>
2) Bind the version of the .msi to this main executable. This is done in the Version attribute of the Product element.
<Product Id="*" Name="My Product Name" Language="1033" Version="!(bind.FileVersion.MainExe)" Manufacturer="Debabrata" UpgradeCode="PUT-GUID-HERE">
Not that the value after the FileVersion is the ID of your file. This is important.
Now to use this version number in the bootstrapper project - the process is very similar.
1) Add the MSI to the bootstrapper.
<MsiPackage SourceFile="Path-to-msi" Id="MyMSI">
2) In the Version attribute of the Bundle element the binding should be.
<Bundle Name="My Bundle" Version="!(bind.packageVersion.MyMSI)">
Again, note how the ID matches.
Hope this helps!

FSharp.Data.SqlClient on windows with dotnet core reports type 'SqlCommand' unavailable

I'm trying to use FSharp.Data.SqlClient on Windows
c:\...> dotnet new console -lang f# -o test5
c:\...> cd test5
Now add <Import Project="fsc.props" /> to test5.fsproj and add fsc.props from https://raw.githubusercontent.com/fsprojects/FSharp.TypeProviders.SDK/master/fsc.props. Then
c:\...\test5> dotnet add package FSharp.Data.SqlClient
And edit Program.fs as follows:
open FSharp.Data
open FSharp.Data.SqlClient
[<Literal>]
let connectionString =
#"Data Source=.\SQL14X64;Initial Catalog=test;User=sa;Password=***"
[<EntryPoint>]
let main argv =
use cmd = new SqlCommandProvider<"
SELECT 1
" , connectionString>(connectionString)
0
Trying to compile it:
c:\...\test5> dotnet build
Have error:
The type 'SqlCommand' is required here and is unavailable.
You must add a reference to assembly 'System.Data.SqlClient, Version=0.0.0.0, ...
Ok, installing System.Data.SqlClient:
c:\...\test5> dotnet add package System.Data.SqlClient
Have error:
The type 'SqlCommand' is required here and is unavailable.
You must add a reference to assembly 'System.Data.SqlClient, Version=4.2.0.1, ...
O-key, let install 4.2.0.1:
c:\...\test5> dotnet remove package System.Data.SqlClient
c:\...\test5> dotnet add package System.Data.SqlClient --version 4.2.0.1
c:\...\test5> dotnet build
Have error:
The type 'SqlCommand' is required here and is unavailable.
You must add a reference to assembly 'System.Data.SqlClient, Version=4.1.0.0, ...
Hm... Replace with 4.1.0.0:
c:\...\test5> dotnet remove package System.Data.SqlClient
c:\...\test5> dotnet add package System.Data.SqlClient --version 4.1.0.0
c:\...\test5> dotnet build
Have same error again:
The type 'SqlCommand' is required here and is unavailable.
You must add a reference to assembly 'System.Data.SqlClient, Version=4.1.0.0, ...
Cannot really move any further with it.
OS: Windows, .NET Core: 2.1.2
I'm sure others are still struggling with this from time to time, so here is what I had to do in order to get the FSharp.Data.SqlClient running in a .NET Core project on a Mac (yes, it does work, beautifully!).
I believe most of it will apply to Windows as well, except that you won't need Mono.
At compile time you need full .NET framework, so you have to install Mono if you are running Linux or Mac. The project still compiles to clean .NET Core.
You need fsc.props in your project folder (place it in the same folder as your project file). Fsc.props contains the path to the tool to use at compile time. In my fsc.props file the relevant path was described as follows (I can't remember whether or not I had to edit it to get things running):
<PropertyGroup Condition="'$(IsOSX)' == 'true' AND Exists('/Library/Frameworks/Mono.framework/Versions/Current/Commands/fsharpc')">
<FscToolPath>/Library/Frameworks/Mono.framework/Versions/Current/Commands</FscToolPath>
<FscToolExe>fsharpc</FscToolExe>
</PropertyGroup>
Next you need to reference fsc.props in your .fsproj file, and DisableAutoSetFscCompilerPath:
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="fsc.props" />
<PropertyGroup>
<DisableAutoSetFscCompilerPath>true</DisableAutoSetFscCompilerPath>
<DotNetFscToolPath></DotNetFscToolPath>
<DotnetFscCompilerPath></DotnetFscCompilerPath>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="mySQLCode.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Data" Version="3.3.3" />
<PackageReference Include="FSharp.Data.SqlClient" Version="2.0.6" />
</ItemGroup>
</Project>
The relevant lines are lines 2 through 8.
Of course you also have to get the Fsharp.Data and FSharp.Data.SqlClient using your favourite package manager, which will add the PackageReference lines to the project.
Happy coding
Roland

Unable to uninstall with custom WiX installer

I've created a custom WiX Burn installer using ManagedBootstrapperApplicationHost with a WPF frontend (using WiX 3.9).
The installation of my MSI works correctly. I use mBootstrapperApplication.Engine.Detect(); to determine if the MSI package is present or not. If it is, I follow a flow similar to that of the installation, in order to uninstall:
mBootstrapperApplication.Engine.Plan(LaunchAction.Uninstall);
Once it's in the PlanComplete event and the Status == 0, I call mBootstrapperApplication.Engine.Apply(System.IntPtr.Zero); and will eventually get back to the ApplyComplete event with Status == 0.
Unfortunately though, nothing seems to have happened at that point.
I'm hooked up to the ExecuteMsiMessage and it has no messages coming through. When ExecuteBeginis fired, PackageCount is 0, where I believe it should be 1.
I can post code if necessary. My wxs file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Bundle Name="CustomInstallBootstrapper" Version="1.0.0.0" Manufacturer="Square Enix Ltd." UpgradeCode="33CA185D-083B-4D45-A0AE-693C2E09C5F0">
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
<Payload SourceFile="D:\Project\CustomInstallBootstrapper\BootstrapperCore.config"/>
<Payload SourceFile="D:\Project\CustomInstallBootstrapper\CustomInstallBootstrapper.dll"/>
</BootstrapperApplicationRef>
<WixVariable Id="WixMbaPrereqPackageId" Value="ignore" />
<WixVariable Id="WixMbaPrereqLicenseUrl" Value="ignore" />
<Chain>
<PackageGroupRef Id="NetFx451Redist"/>
<MsiPackage Id="LauncherMSI" SourceFile="D:\Project\Launcher.msi" Cache="yes" Visible="no">
</MsiPackage>
</Chain>
</Bundle>
</Wix>
If I run the MSI on its own, I can install and uninstall it without any issues.

How to embed WIC in a WiX managed bootstrapper?

I build a managed bootstrapper application, based on .NET as a prerequisite. The bootstrapper will first install .NET and then run the WPF user interface (I'm using WixNetFxExtension).
However, the .NET installer requires a component called WIC to be already installed on the machine.
The problem is that some operating systems don't come with WIC (Windows Imaging Component) installed on the machine. So, how to embed it's installer to run before the .NET one?
You'd want to download the WIC Installer and then add the package in your chain before your installer.
<Chain>
<ExePackage Id="WIC" include the source and your settings here />
<PackageGroupRef Id="NetFx40Web" />
<MsiPackage Id="Your Installer" include the source and your settings here />
</Chain>
Additionally to prevent the installer from running unnecessarily you could add a RegistrySearch to determine if it's installed and use that as an InstallCondition on the ExePackage.

Wix Silverlight prerequisite

I have a Wix bootstrapper project that installs .Net framework from the web if needed.
No I would like to do the same for Silverlight.
Ideally from the web but if I have to I will bundle it.
So how do I add Silverlight as a prerequisite?
Solved it:
<ExePackage Id="sl"
Compressed="no"
DownloadUrl="http://go.microsoft.com/fwlink/?LinkID=149156"
SourceFile="C:\Users\mah67\Downloads\silverlight.exe"
Cache="yes"
PerMachine="yes"
Protocol="netfx4"
Vital="yes"
InstallCommand="/q"
Permanent="yes"
Description="Silverlight Runtime"
DisplayName="Silverlight"
SuppressSignatureVerification="yes" >
The source file attribute is apparently needed so Wix can extract info about the file at compile time. Compressed="no" means that it should not be bundled at compile time. RemotePayload is used when the file isnt available at the time of building the package.

Resources