More on WiX, and Suppressing the License Dialog

As previously discussed, Visual Studio 2012 and later no longer include any sort of MSI/Installer/Setup project template. That means if you create a WinForms, command-line, or Windows Service type of application, there is no way to create an installer for it out-of-the-box.

Instead, you have a couple of free options: Flexera InstallShield Express and WiX. You might find if you work for a company, Flexera has no interest or incentive in helping you find a way to automate their per-developer, but “free” license activation stuff. If you contact them, you might just find that they spend all their time trying to get you to buy the more-expensive products they sell. So, you might be stuck with using Wix.

If you can use InstallShield, I definitely recommend using that if you can!

WiX is pretty bad:
Well, I went to dig into this again and I was immediately frustrated again by WiX. This is a really poorly-written product, with inaccurate documentation, dead links, documentation which points to blog posts from the year 2006, and samples which simply don’t work.

In fact, I don’t think I found a single reference, tutorial or link that actually had a working sample. For example, you will find many blog posts or documentation pages which tell you to add some XML elements, but they don’t say where in the XML they should go, which XML namespaces you need, which .dll’s to reference, etc, etc. Just understand that as you go to look for documentation, there isn’t a lot and what is there is almost all incorrect or missing information.

I’m saying all of this because what I wanted to do is very simple: create an installer for an .exe, and have that installer have a user interface – and it took me probably 3+ hours to gather and scrape all of this information, just to do something that simple. Very frustrating.

Wait, so what’s the point again?
So, the point of this blog post is to help out future Robert not to get mad again at WiX. In pretty much all circumstances where I’d want an installer, all I really care about is letting the user pick the installation directory. So, how do you do that? Unfortunately, I don’t have a simple answer, because the solution isn’t simple – but hopefully this blog post will answer those questions, step-by-step, and with the actual details needed!

I’m using VS2013 Ultimate for the example below, but this should work with any SKU of Visual Studio 2012 or later, I believe.

STEP 0: Install WiX:
As of this writing, v3.8 is out and that’s what I’m using, here. Navigate to: http://wixtoolset.org/ and run the installer.

STEP 1: Create a WinForms Project:
For my example it was WinForms, but this can really be any Windows application which you would typically install. This might include WinForms, command-line, a windows service, etc.  So, just to be very clear, this is just a regular WinForms app called “SederSoftware.WinFormsUI” (we’re going to reference this by name, later):

image

STEP 2: Create a WiX Setup Project:
When you installed WiX (again, from http://wixtoolset.org/), you should have some new project templates under the “Windows Installer XML” folder (note, I also installed IsWix from here: https://iswix.codeplex.com/ but won’t reference it in this post):

image

So, in this case though, I am going to choose “Setup Project”, and per-convention, I will name it the same as my WinForms application, but add a “.Setup” suffix on the end of the name.

STEP 3: Add Project Reference:
Now, I have a WinForms app and a Setup project. In the Setup project, I want to right-click and Add Reference to my WinForms application, as a project reference:

image

Go to the “Projects” tab, select the UI project and click the “Add” button, then click OK. So, the setup project now has a reference to the UI project:

image

STEP 4: Modify the XML to install the Project Output:
If you try to simply build at this point, you will get a compiler error:

mx329D2

So, the first thing we need to do is open that “Product.wxs” file (which is an XML file, with no designer), find <Wix>, then the <Product> element within it, In that <Product> element, there is a Manufacturer attribute which you must set. Here’s how I set mine: Manufacturer=”Seder Software LLC”:

mx36AF8

Now, re-compile and it at least builds. If you were to run the MSI at this point, there would be no UI and it wouldn’t install anything. To have this installer simply copy your .exe to a folder in Program Files, you need to make one modification to that same XML file. That is, you need to find the XPath of Wix/Fragment/ComponentGroup in your Product.wxs file. Within there, there is this comment of:

<!-- <Component Id="ProductComponent"> -->
    <!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

like this:

mx340BD

Uncomment the <Component part, and delete the TODO part. Instead, you want to point to your WinForms project, for me, that is something like this:

<Component Id="ProductComponent">
  <File Source="$(var.SederSoftware.WinFormsUI.TargetPath)" />
</Component>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Note that the “SederSoftware.WinFormsUI” part, is the name of my WinForms project. So now, modified, my Product.wxs looks like this:

mx3D368

If you compile and run the the msi, you will find that it installs your executable under the project name, in Program Files – but you still have no UI.

STEP 5: Modify the XML to include a basic setup UI:
You have a few options for having a UI. There are some built-in ones, and you can create entirely custom setup screens too. Again, for my purposes, just showing the installation directory is fine. To do that, you have to modify that XML again. This time, right in the Wix/Product level of the XML file, add the following at the END of the <Product element:

<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
<UIRef Id="WixUI_InstallDir" />

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

And to be clear, here’s what my modified file now looks like (noting that INSTALLFOLDER is referencing the “ComponentGroup” we have in that file too):

mx3D5EA

So I added that Property and UIRef as the last elements within the WiX/Product element in Product.wxs. If you compile the project, you will now get this error:

mx3FD9D

STEP 6: Add a reference so that the setup UI works:
To correct this error, we need to add a reference to WixUIExtension.dll

image

when this dialog opens, it is already pointing there for me, but in case it isn’t for you, this file is in C:Program Files (x86)WiX Toolset v3.8bin on a 64-bit machine, C:Program FilesWiX Toolset v3.8bin for 32-bit.

Once you do that, you can compile and run the MSI. You now see a minimal installer:

image

image

image

image

image

And you will see an entry in Add/Remove Programs as well:

mx34E4D

STEP 7: And finally, suppressing the License Agreement dialog:
Now, the main thing I wanted to do was to suppress that License Agreement page. I patched together a bunch of information from many sources and found this to work:

<UI>
  <UIRef Id="WixUI_InstallDir" />
  <Publish Dialog="WelcomeDlg"
            Control="Next"
            Event="NewDialog"
            Value="InstallDirDlg"
            Order="2">1</Publish>
  <Publish Dialog="InstallDirDlg"
            Control="Back"
            Event="NewDialog"
            Value="WelcomeDlg"
            Order="2">1</Publish>
</UI>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

So this goes within Wix/Product – I put it after the UIRef thing from above. So, here is what the top of my Product.wxs file now looks like:

mx39C21

Now, finally, when you compile and run the setup, it should show the wizard from up above, but it skips the license agreement screen.

Posted in New Technology, Uncategorized, Visual Studio, Windows, WinForms
7 comments on “More on WiX, and Suppressing the License Dialog
  1. Steven Bone says:

    Rob – Sorry to see that you are not a fan of Wix. All that Wix gives you is an abstraction over the Windows Installer MSI format. Each version adds a bit more abstraction that you can opt-in to using, while not cutting off direct control of everything that it produces. If you recall Joel on Software’s ‘Leaky Abstraction’ article, you can say that Wix leaks like a sieve. By design.

    An MSI executes in a transaction-based engine. Of COURSE it is hard! That is a fault of the designers of Windows Installer. It is up to you to learn the system under which the installer operates, and design your installer appropriately within the constraints of that format. If this is not something you wish to do, use a different installer technology (NSIS, for example).

    Every installation product I have ever worked with for MSI authoring has attempted to make something that is intrinsically difficult easy to use, and that made each of these products fall well short of what you need to author anything of medium complexity. You are locked into their abstraction of how visual studio and windows installer files should be built and patched. This sub-optimal approach results in sub-optimal results. In these products you still have 100% leak, but the product itself prevents you from fixing the holes in their philosophy. Want to exclude some ‘content files’ based on a pattern from your installer in InstallShield? Good luck!

    With Wix I was able to easily create a rather difficult set of installers very simply with incredible amounts of reuse. Just think about developing a product that has three versions (demo, full, embedded), each of which has 4 language variants for resource and content files, plus some bilingual editions (18 or so different MSI files, prerequisites, CD images, etc). This task would have been impossible to do in a single installer project in InstallShield, or even multiple projects if you wanted any reuse of logic – and it was done in a single Wix project. With that kind of power, yeah, it is difficult.

    I agree completely that the Wix documentation is poor. The Windows Installer documentation is rather complete but poorly designed and cross-linked. Both are lacking in concrete examples. But so is every other third party installer authoring tool. There are books on the subject for both Wix and InstallShield, but you’d be better off starting with a book on Windows Installer.

    Like

    • Robert Seder says:

      All I’m saying is that when I go to pick up a new car, I don’t expect the dealer to give me a box-full of things that I need to install before I can drive it off the lot! When I “buy” a product, I expect to be able to use it, right out of the box (even if it’s open source).

      98% of users who need a Windows installer need: Welcome, choose directory, finish. To do that, took me SEVERAL hours to accomplish. So, I’m just suggesting that the “product” that is released should have a developer-friendly: “hey, if you don’t want to learn the internals of MSI to create a setup project”, just start with this simple project to get started. You can dig into the more complicated stuff later if you need it!”. It’s a very simple thing, but it’s missing.

      I understand that this is likely a philosophical choice, kind of like how network cards aren’t enabled by default on many distros of Linux. From their perspective it’s “Of course they are disabled, wouldn’t you want to go in and configure every detail about your network card before just letting it loose on your network?” My answer is: “No. No, I wouldn’t. I just want the network to work. I’ll open up ‘vi’ and edit that config file later if I want to do something special!”

      So – I’m guess it just comes down that that sort of philosophical difference.

      Like

  2. Tony says:

    Well, all I can say is, thank you for taking those several hours of research (and more) to produce this blog, I have only had to spend less than 10 minutes following your example and I now have a simple (but perfect for my needs) installer!

    I can now spend days learning all the other features available in Wix… without the worry of any deadline.

    Cheers!

    Like

  3. George says:

    Robert,

    I want to thank you for the code that removes the license agreement. I spent almost two hours going back an forth with different solutions before I came to your easy solution. Thank You!

    Like

  4. Artem T. says:

    Hi Robert, thank you for this post. For some reason after installing latest version of Wix tools, I got the License dialog which I wasn’t able to get rid of. Your post saved a few hours for me.

    I fully share your feeling about Wix toolset, it is so cumbersome and hard to use properly. Even after all these years since your original post…

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 5 other followers

%d bloggers like this: