Creating Professional Installations with WiX | Tips

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Nigel: With a presentation on building professional installations for Windows installer XML, please welcome back Steve Ives. Steve: Thank you, Nigel. All right. So yeah, as Nigel says, that's what I'm going to do now is talk to you a little bit about Windows Installer XML and how you can use it to create professional installations for your Synergy and other applications. You know, more and more of us have made the move to Windows now - a lot as I look around the room, there's an awful high percentage of people who are now on the Windows platform and not too many on Linux and VMS anymore. Still, it's still a lot of customers out there, but a lot of you guys, seems to me, are on Windows and once you obviously get to the Windows platform, one of the things that can be very important, particularly if you're creating an application for resale, but even if not - even for internal deployments, it can be pretty important to have a good installation experience for that product. Many of us have used a variety of tools over the years to achieve that, be it InstallShield or other products that are available in that market space, and in recent years an alternative has come to surface and it's actually quite a nice environment and one that's very easy to get up and running with, and it's also free, which is very nice. So that toolset is called WiX, it's called the Windows Installer for XML. It is as the slide says a free software toolset, it builds basically Windows installer packages - MSI files, essentially, or they can be wrapped up in setup.exe's as well. Based on a definition of your product that is simply defined or expressed through XML. So it's a very easy syntax to get up and running, you don't need any complex tools, there are some - there is tooling available on top of it, if you want to use those tooling, there are some commercial products that you can buy if you want to put a UI on some of this stuff. But the basics of WiX, certainly in terms of, you know, when you think of a typical Synergy application, and most other applications as well, unless it's a really complex product, the installation is largely about providing files into certain places, creating shortcuts, maybe putting some things in the registry, maybe modifying paths, or setting some environment variables, so it's pretty straightforward stuff much of the time and that's something - all of those things are things that are really easy to achieve just through simple editing of XML in a text editor or in Visual Studio. There are extensions that you can download, the toolkit that you can download does provide some Visual Studio project templates that help you very easily put this stuff together as well. WiX supports all of the Windows installer features, so it's a complete implementation and it scales from the very small list of projects, you can literally throw an installation together for a very simple product in a few minutes, through to the very largest of products. Microsoft themselves heavily use WiX and have done for some time. WiX actually was Microsoft's first open-source project several years ago. Now pretty much half the stuff they do is open-source. So it did come out of Microsoft, and WiX is the technology that they use to install Microsoft Office, Visual Studio, SQL Server, Exchange Server, so this is a mainstream product set and it's open-source, so it's heavily used by Microsoft and a lot of other large software companies as well. WiX itself was created by Rob Mensching, or a guy called Rob Mensching, who did use to work at Microsoft. He personally worked heavily on creating the installations for Office, and Visual Studio, and Windows, and so on, and he was also the original author of a utility called Orca. If you've ever done any work with installations you're probably familiar with Orca - it lets you open up an MSI file, and peek inside, and edit things, and stuff like that, and he's widely recognized as a leading authority on the subject of deploying software. He created WiX in 1999 and designed it from the ground up to be very easy to use - just simple XML-based, that you don't need any fancy tools, you simply could use Notepad, literally, if you wanted to. It quickly got adopted throughout Microsoft and, like I say, it became Microsoft's first open-source project. Rob now is the co-founder of a - he left Microsoft in 2013 and founded a company called FireGiant and there they are basically in business to put commercial tooling around WiX, and they have some add-on products if you want to put UI - deal with this stuff through UIs, they have commercial support available, they have consulting services available, and so on, if you want to get some assistance. And Marty and Jeff were actually very good friends with Rob, they meet him frequently at the Microsoft events that they attend. They're all part of the Visual Studio integration program together, so we got a pretty good working relationship with the guy and his company. Just a little bit about our history with with WiX and FireGiant. CodeGen's been using a WiX installer since the rewrite, since the version 5 release came out, so that's where I kind of learned what I needed to do. And Synergy/DE itself, we're in the process as Roger mentioned the other day, of moving to WiX-based installers. Right now, the ODBC installer is now - has now switched over to WiX, the other ones are still being - still basically going through the QA process and didn't quite make it through in time for the 10.3.3 release, but in the near future all of our installers will be WiX-based, moving away from the traditional InstallShield products that we've used for many many years. In terms of how to get started, just a few pointers if you are interested in this stuff: a good place to start is wixtoolset.org. That's the, kind of, open source environment. There's lots of samples, and the tools you can download from there, and so on. There is a really good tutorial that is pretty extensive on Fire Giant's website, and there's all kinds of reference materials out there. There's a couple of recommended books on the subject as well, so it's pretty easy to get up and running with. I just pretty much worked my way through the tutorial and looked at other information and samples that are available, either on the wixtoolset.org site, or Fire Giant site, and it was pretty easy to get up and running with. Once you install the tool set, you do get some tooling in Visual Studio, so you get a new folder in the "New Project" dialog, I think it's titled "Windows installer XML" and within there, plugs into each language. So it - under C#, you get a folder with with these projects and the same for VB, and so - uh, no, I guess I'm wrong, sorry. There is a folder as you can see. So basically a setup project is the main type of project that you'll use but you can also create the other kinds of things that are common in the MSI world, so a merge module is kind of a part of a product or something that you're shipping and maybe embedding in other projects. You can create setup libraries which are kind of shared components so you can share functionality between multiple installations, same as you would use a class library and reference it in other projects. A bootstrapper project can be used to to create a setup.exe experience if you wish, rather than just the plain MSI experience and then there are various custom action projects. Custom actions - a way that you can extend the functionality of the standard MS windows installer environment and write custom code that executes during an installation or an uninstall or repair, and you can write those as you can see in C#, VB, C++, and we have added a Synergy .NET custom action template to our project templates as well, so you can also write them in Synergy. Obviously, you have to be a little bit careful with that, because if you do that, then you have to ensure that Synergy is installed before you try and install the product that uses the Synergy .NET custom actions. The hierarchy of an installation: basically everything starts with a product and you'll see that product is the kind of the main element in the in the XML file, and below products are features. Every installation will have at least one feature, but could have multiple features representing required and optional components within a product set perhaps. A feature might be the documentation, might be sample files that kind of thing. They can also be hierarchical so you can have features within features and so on, and they get presented in the install dialog in that tree that we've all seen from time to time. Below features are components. Components are used to define things that are installed together as a group, so maybe a file and a shortcut to the file would probably - possibly be in the same component, and below that you have things like files, registry entries, environment variables, and all of the other things that can be part of a product. So I'll fly through these fairly quickly because I've already spoken to some of these now, so components are really the main building block of an installation. A component is all of the individual pieces that go together in some combination to make up a product. So components contain resources, files, registry keys, and so on. A component should only contain things that logically go together. So a file and a shortcut to it would be a reasonable example of two things that you might put together in the same component. Every component has an identifier that's used to refer to it and is identified uniquely globally through a GUID. So as you're building up this XML you'll be using the GUID generator tool to generate unique GUIDs for every component, every file, every feature - all of the main entities within an installation have a GUID that uniquely identifies them not just within the installation, but on the target system as well. So this GUID is globally unique and it can be used on some Windows system to say "is this particular component part of this product present on this system?" So it's important that they are unique and you never - if you copy and paste XML code, it's really critical that you refresh all the GUIDs and assign new values to them. Component groups are ways of simply grouping components together. So within a feature, maybe there's ten files that you want that you go into ship together or not, so it will be a reasonable thing to put each file in its own component and then collect them together in a component group, and that component group could be declared as part of a feature, for example. How you organize this, there's lots of different ways of organizing this stuff. You'll figure it out and you'll get - first, you sort of throw everything together but as you work more in this environment you kind of get a feel for the best way to achieve things. And then you define features. Features are user-selectable things within the installation, assuming the user interface allows the dialog or shows the dialog that allows the user to pick features. So features: generally the idea is it's something that maybe - some features that can be declared as required, some are optional and the user gets to pick, and you can default them either way and so on. And features contain components, and component groups, and so on. So all installs have at least one feature. Fragments. Fragments is a syntax in the in the WiX XML language that basically allows you to just compartmentalize useful pieces of code. A fragment just simply delimits other pieces of WiX code, and they are used to, for example, split things out into separate files. So it may be you've got a piece of WiX XML that you want to use in different installations, maybe it does a particular thing, maybe it's going to be in a WiX library and you just want to separate that piece of source code out into a separate file just for maintainability, then you would put that code in what's called a fragment. Okay. And fragments typically go in source files. There are include files and .wxi is an include file, it's another way of sharing information between multiple installations or different places in an installation and also set up libraries if you have multiple installs. I've already mentioned this kind of thing but a lot of these elements have GUIDs and IDs - the ID is the name by which you refer to something somewhere else in the in the XML. The GUID is, again, globally unique worldwide and that identifies specifically that particular - well, mainly components - but there are some other things that that GUIDs get assigned to. There are various tools to let you generate GUIDs that are online tools to let you generate GUIDs. Visual Studio has a little GUID generator utility that you can use, you can write a program to do it, there's a guid.newGuid will produce a GUID for you. So it's - but it is critical, like I say, if you're copying and pasting, I think in any samples I've produced I always take the GUIDs and put, you know, "put GUID here" kind of thing so you can't accidentally reuse them. That's fairly common on the Fire Giant sites as well. The default setup project when you create one basically looks like this. It's very, very simple. As you can see, the root element of the document says WiX and declares a namespace and within that there is a product tag that defines the product, and the product defines the name of the product, the version number, the manufacturer. You'll notice that there is an upgrade code GUID in there. I'm not sure why they generate that into a new project, I would have thought they would have left it blank, but one of the things you should probably do is immediately replace that GUID when you create a new project. I'm assuming it's generate - haven't actually checked - I assume it's generated on the fly. But you can see you just do some basic configuration here to name the product and name the manufacturer, set the version that you want to use, and so on. And we've got a default fragment here that's declaring a hierarchy of locations, so TARGETDIR ProgramFilesFolder is a special keyword - special variable in WiX that refers to the Program Files folder on the system, and within that we're naming something called "INSTALLFOLDER" that has a name of "SetupProject1," so we're going to put - we're gonna target files to go in an install folder and they'll go in Program Files x86 "SetupProject1." So we can name this probably after our company and our product name and that kind of stuff. So you'll see how we start to customize things. And then we've got a default - oops - we've got a default fragment with a component and some comments saying, "start to insert your components here." And here we got a feature called "ProductFeature" with a title. Level one is the hierarchy in that tree of features and it references component group "ProductComponents," which is this guy. So basically any components that we put in here - files, shortcuts, that kind of stuff, become part of this default feature and part of the installation. Okay. Configuring new installation. So initially you're going to pretty much go through the same steps to configure that default XML file. You're going to provide the manufacturer and product names, set the version number to whatever you want it to do, if it, want it to be, if there's an existing product, and specify unique product code and upgrade code GUIDs. Those are those two things that you saw here, so I would recommend you replace this one with one of your own. Product ID asterisk makes it generate a new going every each time it's built. Again, I like to not do that, I tend to generate a GUID and put it into that Product ID field as well. So you have a product ID GUID and an upgrade code GUID. Okay. The product ID - I think actually I'll talk about those in a little while, so we will come back to that. Frequently you'll also do some work on the media token that's in that default file. That basically determines what gets created and how. Is it an MSI file, is it big enough to go on 1.4 megabyte floppy disks or a 650 megabytes CD, or does it just create one huge file as big as it needs to be. There's all kinds of options for, does it break it into files that have a 50 megabytes maximum and then it creates another one and another one, there's all kinds of options for how you want to actually create the media. By default if you just add 'EmbedCab=yes," the cab file in Windows installation is like a zip file it contains all the actual files and then there's the MSI. If you say "EmbedCab=yes," it builds the cab with all the files and puts it inside the MSI file. So by doing that, that and only that, you just wind up with an MSI that is the installation. So that's what - that's the starting point a lot of people go with. And customizing the target location. By default it has a product name. Most of us put, uh, program files, than a company name than a product name. So here's an example of that. We've customized it, we've said manufacturer is Synergex, name is Sample Application. We've provided product ID and upgrade code GUIDs. The product ID GUID basically is used to identify a specific version of a product. And the product ID value should change every time you do another release. Ok. The upgrade code is used to chain multiple versions together. So for a given product the upgrade code GUID should never change. It should always be the same for that product and you change the product ID GUID between versions. And that's what allows Windows installer to realize that this is an upgrade to that one so uninstall that one and reinstall this one. They get hooked together through that upgrade code GUID. And it's not just the GUID actually, it's the GUI that compares version - you know - the version number has to be logically higher and there's a couple of other things involved as well to do an upgrade. Customizing the target install location: the default behavior is on the top left there, basically ProgramFilesFolder, Set up project one, that gets populated with the name of whatever project you create and a very common thing to do is something like the one here, where we've said, below ProgramFilesFolder bind.property.manufacturer is a way of doing data binding to the value of the manufacturer field in the product definition higher up in the XML file. So whatever you've set your product name to be, accompanying manufacturer name and then below it bind property product name, so you wind up with Program Files x86, Synergex, Sample Application. So that's an example of how to do that. Installing files: here's an example of installing a file, you simply define a component somewhere for the file. The ID is a some kind of unique reference. The way that WiX works is, you put the setup project in the Visual Studio solution with your product and you reference the product projects that make up the product, and this this syntax here: var.SampleApp.TargetFileName is a reference to the target binary that is produced by the Sample App project in the solution. So it's the .exe for the project, or the dll for the project that you've referenced. You can also just name physical file specs and things like that. So this is generating an ID and this is actually referring to the target file itself. KeyPath equals yes. Every component has to be - has to have one item that is defined as the KeyPath, and what that means is during things like repair and uninstall it is - in this case it is this file because KeyPath is set to yes, therefore Windows installer will look for the presence of that file on the target system to decide if this component has been installed or not. Okay. So if you've got a component with multiple files in it, one of them says KeyPath equals yes and that's what Windows installer will look for the presence of that file when it's doing to say, "Is this component installed on the system?" For that reason, there's a general recommendation as far as I can tell, that pretty much good practice is considered to be to have basically one file per component. So that - because for repair purposes, if you've got a component that's got multiple files and one of them is the KeyPath, if that file is the one that happens to have got deleted that you're trying to fix with a repair, it can't figure it out because the KeyPath file itself has gone. So by making every component contain one file, which is also the KeyPath, a possible repair can detect literally at the minutest level files that may or may not be missing and put them back in a repair or know to take them away in an uninstall. So a best practice is one component - one file per component. You can also, if you're shipping .NET executables - and you could ship traditional Synergy with this stuff as well it doesn't have to be .NET, you could ship DBRs and ELBs and all that kind of stuff - but if you are shipping .NET components, another thing that's fairly common is to use the NGEN utility to precompile the IL to native code during the installation so that it doesn't have to be JIT compiled when the application gets run every time. So at the bottom there you can see the example. You actually include an X - you reference one of the WiX extensions called net - WiXNetFxExtension. There's a namespace that you have to import at the top of the file and then within a file declaration you use this NetFx NativeImage, and basically what that does is it instructs Windows installer to NGEN that assembly after it's been copied to the target location. For better startup performance. So I'm going to demonstrate to you very briefly a sample installation. I've got three, I was going to actually build this installation on the fly during the demo but unfortunately one of the things WiX do not support in their XML editor is they don't let you do snippets. So I was hoping to be able to actually build this thing on the fly but we'll have to just go with pre-configured ones. So here's an example of a very simple installation. It's a simple demo app. The app is in the project, it's called sample app. It's just a little Synergy .NET WPF application. If I run it, it doesn't really do anything particularly interesting. It has some menus, it has an icon, it has, "show the value of DAT and EXE," which aren't set right now but later after the installs run they will be. It has a help file that is available, so we're shipping a help file and launching it, and it has an "about" box which displays information about the user and the company which is going to be entered through custom UI in the installation later in the process. So it's looking in the registry and right now it's not finding it because we haven't run the installer yet. That's all the application does. It's made up of an executable and a class library, and then the third project here is the setup project. So we've got a WPF application, we've got class library, and we've got the installation, and here's the product.wxs. And in this first version, basically it's not doing an awful lot. You can see we've said, "EmbedCab equals yes." I've set the product name and the the GUID values and so on. I've said, "EmbedCab equals yes," so all we expect to get out of this thing is a single MSI file. We've got a single feature called product components and if we look down here we'll see Fragment, ProductGroup, IDs, ProductComponents, and within there we've got two files being shipped. We've got references - if I look in the setup project, you see I've got references to the app and the class library, so I'm using those references to refer to the EXE and the DLL, and both of them are being NGEN'd during the installation, basically. So that component group lists the components which in turn contains the files and is referred to from the feature, so when we run the install those two files will be provided, basically. I've also got a separate installer file that I've added and in there I've got a little fragment, and the fragment contains a component group called "DocumentationComponents" and ships the "HelpFile." So SampleApp.chm is the help file that's actually part of the Sample App project up here somewhere, I think it is, yeah. So there's the help file that's been developed in the project. So that's a reference to that and then back in the main product we've got a second feature declaration: DocumentationFeature, and it ships anything in the documentation components fragment. Ok. And then back in the - somewhere up here, where are we? No, that's it, yeah. Two features declared within the main product element, so we'll get those two features. We've also modified the target location, so it's going to go to Synergex Sample Application under Program Files and that's pretty much it, that's all this install does. When we build the installation project, WiX has two utilities: one's WiX Candle - one's called Candle, and one's called Light. WiX...the Candle...Candle is the compiler. It creates an intermediate file, it's kind of like a IL and then a binary, so Candle is the compiler, WiX is that - Light is the linker, basically, and it just drives them for us, so you can see it's done a Candle, it's done a Light, and if we go off to the file system and - I should have done this earlier so I know where it is...where are we - WiX, Sample App, demo one, app set up, bin release, because I'm in release mode in the project, so in bin release, SampleAppSetup.msi. There's our installation. And if we run the installation, it should provide those files for us. Now, we haven't got any shortcuts yet, so you know, we're not going to expect - it's done, ok. Default UI is basically nothing. Ok. So it's done, it's installed, so if we go off and look in C/program files/x86, we should have Synergex/SampleApplication. There's the EXE, the DLL, and the help file. And it should, in theory, run and be able to launch its help file at this point. But we don't have any shortcuts or anything like that yet. Ok. I'm going to - why did I close that? I'm not going to run through this process all the time because I'm going to run out of time if I do, but let me just go back one time and uninstall that, so WiX, SampleApp, demo one, setup, bin, release, and we will uninstall. I could have gone to programs and features, of course, it would show up in the programs and features list, and now it's been uninstalled again. Ok. Let's move on. Sample UI options. The WiX toolkit ships with five combinations of UI that you can choose to use in your application. Minimal basically is, you get a single welcome dialog and a license screen, and then it just goes off and does the install. Feature tree gives the user access to that list of features so they can pick them. Mondo is pretty much everything as a whole series of dialogues. Advanced has got a bunch of additional options: change the target location, and all that kind of stuff. These things are shipped built-in and they're also in XML format so that you can take one of the default and customize it, which I'll show you an example of how to do that very briefly as well. Some of them have certain requirements, so you just need to do a bit of research and figure out - you have to have certain variables in your installation to provide values for certain fields, and that kind of stuff. We're going to base ours on feature tree. These are the dialogues that you get with the feature tree UI: you get a welcome dialogue, a license dialogue, you get to pick features that you do or don't want to install, you get a "we're ready to install" dialog, you get a progress dialog, and you get a finished dialogue. So feature tree is a fairly typical set of dialogues for most installs. There are other dialogues involved as well on uninstall, and repair, and all of those kind of things, but these are the dialogues you'll see during the install. Other UI - yeah, so there's other things, like if you interrupt it there's a "are you sure you want to cancel?" dialogue, if you select repair, there's a repair dialog that says, you want to change repair or remove. So there are a few other things floating around in the background as well. In terms of customizing the UI, the UI itself is defined with XML, so those - there are those five XML files that are shipped, you can literally include them in your project and then start modifying them. And then you simply refer to the dialogue that you wish to use - you'll see this one it's called - I've named this one - if I can get my mouse..."CustomUI" and in my main product token I'm saying, "UIRef ID is CustomUI." So I'm overriding the UI that's being used, that default one that just very basically shows you nothing, and providing this one. And then I'll show you an example of - well, this is, in fact, an example of customizing. So within that XML file, I've declared a new dialogue with controls, and these controls are text boxes, and radio buttons, and labels, and you know, it's not that usual set of windows controls that you can build up a little piece of UI to modify your installation. So this piece of XML defines this little UI where you get to type in a username and a company name. And through some reserved names, these things get automatically populated with the Windows registration information, for example. So there's all kinds of things that you can do with this. This is a very simple example of customizing the UI. Creating shortcuts: once you've got files, it's a reasonable thing to want to create shortcuts, so here we've got an example of a component that contains a shortcut. Again, it has - it's basically, the shortcut has a name, it has a working directory, (where is the shortcut going to get created), a description, and again, we're binding to product name, and a target. So that's the ID of the component that provides the executable and therefore this shortcut points to that executable. Okay. And then, for shortcuts, generally you have to put a value in the registry to act as the key path to determine if that shortcut's been provided or not. That's the recommended path. So this is simply dumping a value in the registry simply so it can be used as a key path for the component to determine if the shortcut has been installed on the system. And again, that's used during repair and uninstall. Updating the registry. Well you just saw an example of that with the key path, but there's this registry key syntax putting in the H key local machine (HKLM) tree in the key of "Software/Synergex/SampleApplication," again binding to the values elsewhere in the XML and then creating a registry value type equals "string," name equals, value equals, and again, it is the key path for the component. So fairly straightforward to create shortcuts, to put things in the registry. Demo two basically just takes the same environment and walks it through a little bit further with those two things. So let me just show you briefly - probably not going to run this one because I'm getting very - little bit short on time and I don't want to go over if I can avoid it, but basically this is the same installation we had before. A couple of things have changed: I've got this registry entries file, and within it has a frag - it has a fragment and it has a component group called "RegistryEntries," and basically what's happening here is, well, let me show you the other part first. Before we do that, I've got custom UI. So this was a copy of the WiX UI feature tree XML, and I renamed it to custom UI. This is all the standard feature tree stuff, and then I've injected this new dialog called "UserCompanyDlg," and these controls are just labels, and text boxes, and so on, that present the UI and buttons. And then it's just plugged into the sequence. So the license agreement dialog, which is the previous dialog in the sequence has had its - where is it - it's next button now goes to "UserCompanyDlg," and UserCompanyDlg's next button goes to what was the next UI in the sequence. So you just chain the things together in the order in which you want them to appear. So we've got custom UI, back in our product, we've plugged that UI in. "UIRef Id" is "CustomUI." So that's now the UI we're going to see. The UI has a license screen and it requires you to have a variable called "WixUILicenseRtf," which points to an RTF file that contains the text for the license screen. So we've plugged that in there. That custom UI puts the user name and company name that are entered into two variables called "USERNAME" and "COMPANYNAME," so declaring these properties lets me get a handle on those values that are entered back in my main installation so I can do something with them. And what I'm doing with them is in registry entries, here's some code that puts four things in the registry, so I'm recording in the registry so that it's available to the application, the username that was entered, the company name that was entered, the location where the application was installed, and the version of the product that's installed. Okay. And then that gets plugged into the main installation. If we look back up here, we've got feature "ProductFeature" now includes a reference to the RegistryEntries group, so it all hangs together that way. And that's pretty much what changed in here. Okay. I'll not run this one - I'll run the final one and show you what the final version looks like in a few minutes time. But hopefully - does this make sense? You see how you sort of incrementally build up the installation just by adding files, and registry entries, and so on. Standard actions. There are a whole bunch of what are called "standard actions," and these are like pieces of functionality that you can declare somewhere in your hierarchy. For example there's an element called "InstallExecuteSequence" where you can declare actions that take place and what order they take place in, and do they take place on an install, or an uninstall, or a repair, and stuff like that. And the examples of standard actions are things like, to install Windows - there's an action that installs a Windows service, there's an action that starts a Windows service, register new fonts into the Windows system, force a reboot to happen during the - after the installation, all those kind of things where you want to make something happen on the system. There are standard actions to support those kind of activities that installations commonly need to do. And you can also declare custom actions. So a custom action is a piece of code - custom code - that you want to write to make something happen during the installation. You can write custom code in several ways: you can write them in native code, in C++, you can write them in managed code, in Synergy, in C#, in VB. I think you can also write them in PowerShell as well, PowerScript. So there is a Synergy custom actions template that we've added into our installation and basically you just have a static method, you attribute it as custom action, as you can see here in the code. There's a certain signature it passes in a session object that has various information about the installation, and you can use it to get our installer variables, or what's the location of the install, and all that kind of stuff. And you can see these examples: EditSynergyIni is an example of something you might want to do during an install, CreateIsamFiles, DeleteIsamFiles. The final example I'll show you has these as examples with some code built-in as well. So I've just I've shipped a Synergy INI file that has some placeholders in there because I don't necessarily know where the data folder is going to be on the system until install time, so I have a custom action that edits that file with the install location during the installation because it might not be the C drive, it could be a D drive or E drive depending on the system, you know, so you have to do that kind of thing. And I've got an example custom action that creates a data folder in a public writable folder and puts a bunch of ISAM files in there and an uninstall action that removes those ISAM files again during the uninstall. Once you've written the custom actions you declare them, so basically this "binary ID equals" is basically declaring when you build a custom actions DLL, it gets this weird .CA.dll extension, and this is declaring a reference to that DLL and saying this assembly contains custom actions, and then you declare with a custom action token each of the custom actions that you want to execute and give it what's called a binary key, and then, basically, you modify the, again, the InstallExecuteSequence token to say what runs and when. So here we're saying, we're referring to the EditSynergyIni after InstallFinalize, which is pretty close to the end of the installation. Not "Remove equals All," which believe it or not is how you say, "only during install," because it's not "remove all." CreateIsamFiles - run this during installation, and then DeleteIsamFiles runs before InstallFinalize "Remove equals All." So only during uninstall. Okay. Setting environment variables is another thing we might typically want to do. So here's an example of how to do that: Environment Id equals the ID just referred - lets you refer to it elsewhere, "Action" is "set," "Part" is "All" - we're setting the whole value, you can also prepend or our append information to an existing environment variable like path, for example. The name of the environment variable, the value - is it system-wide or user-wide, and is it permanent, so if you say "Permanent equals yes," it will remain after an uninstall. Okay. So, pretty straightforward. Also a common thing that installers like to do, or should do, is check prerequisites. This is just an example of how to check if the .NET framework - actually, this will check if 4.5.2 is there, specifically. The 4.5.2 is based on this number here, this 379893 is - I think it's the build number for .NET framework 4.5.2 or something like that, there's a documented list of them. So this just checks if it's there, it doesn't do anything - all it does if not is, it will report the error and terminate the installation. There are also ways that you can chain on and go download it and install it, and then carry on with your install, and stuff like that. But this is a simple example of just checking a typical prerequisite. There's another example of how you might go about saying, "is Synergy installed?" Again, all this is doing is doing a registry search looking for the SOFTWARE/Synergex/Install...we put a value in the registry SDELOC when we install Synergy, so this snippet of code is just checking that that SDELOC value exists in the registry. Not - it could be smarter, I'm not checking versions or anything like that, I'm just saying, "is Synergy installed?" But it's a simple example. Also, another thing that's nice to do is, in programs and features, when your program shows up, there are various hyperlinks that you can choose to provide at the bottom of the screen that lets the the user know, "Where do I go for support? Where do I go to check new versions?" So this little snippet of code in the - again, in the main product token, which would provide values for those things that would just get surfaced in programs and features, just to make it a nice experience for the user. So let me just walk you through the final sample. Again, I'm not going to go through the whole thing in vast detail. I have put the code for all these three examples out on Github, so there's the URL, or if you just go to Github and search for Synergex, you'll find me and in my part of the little Github world, you'll find Synergy WiX example that has all of these three solutions in there. So let's just look - just so that you've seen the final solution, we'll go for the third one, which is this guy. So what's happened here is, we've got our custom UI still, we've looked at registry entries. We've got some custom actions, so SetupCustomActions, here's my Synergy .NET custom actions, one called EditSynergyIni that just gets a handle on the location using DataFolder, that's one of the IDs in that location hierarchy back in the product node. And it goes and searches for ***INSTALLFOLDER and replaces it with the actual install folder, for example. So these are just public static methods that basically are attributed as custom action and then they get plugged into the installation, I've put it in a separate fragment so custom actions, and declare the reference to the assembly that contains the custom actions, and name the three custom actions. And then in product, what we will find is that in our execute sequence - you saw this on the slide earlier, in fact - so called during installation, edit the Synergy.Ini and then create ISAM files, and during uninstall, delete ISAM files. So just plugging in the custom actions. You can see we've got our checks for the framework, we've got our checks for Synergy version, we've got our informational URLs. I didn't show you this part earlier when we created the shortcuts, but as well as INSTALLFOLDER under ProgramFiles/Synergex, I've got ProgramMenuFolder. So that gets you the location of the Start menu, and then below there I created a sample application folder in the Start menu and that's where the shortcut gets created. Okay. Other than that, you've pretty much seen most of this stuff, I think there's the stuff that's putting the values in the registry. Let's build it and run it just so that you can see it happening. So let's build the setup program. We are in release mode, so it's going to get created over in demo three, setup, bin, release, there's the MSI that we - we're still writing it - there we go, it's finished, and if we install it, we should see the full experience. This is going to be pretty similar to the CodeGen installer at this point, so there's our welcome screen, there's our license screen with our custom UI that we provided - custom text that we provided through that RTF file. We have to accept that before we move on. Here's our custom UI that we implemented, the user registration stuff. Let's just put a custom value in there, just so you can see it running. There's our two features sample - the sample application is a required feature, documentation, if I don't want it I can turn it off. And then we should get our ready to install, there's our progress dialog as it goes through, and now we're finished and we're installed. So now we should, in our Start menu, find...if we go to the S area, we should find Sample Application. We've got a shortcut to the app, we've got a shortcut to the documentation, and actually I didn't show you this earlier, but I will: it also adds an uninstall shortcut as well. As well as showing up in programs and features. And if we run the app, we should be able to, for example, go to our About screen which looks in the registry for those values, and there's that custom company name that our installer put into the registry after I typed it into the custom UI. Okay. All right. Let's leave it at that. Let's do an uninstall this way again, just to leave it clean. And just a couple of wrap-up slides. Back here...Just one more point that if you're building installations, really you need to digitally sign them as well. If you do not - if you build an MSI and just ship it out to customers, they're going to get a pretty scary experience when they try and install that MSI. You won't see it on your own machine because it gets - if you don't sign it with a real certificate, it gets signed with a temporarily generated certificate, and it'll look perfectly normal on your own machine, but if you run it on another machine...And Microsoft have been making this experience a little bit scarier and scarier for the last few versions. Now, it's really not that obvious how you proceed.There used to be a big "okay, install it anywhere" button, but now you have to drill down into more info, and next, and it says install anywhere. So they've really done it - they're really trying to hide it away and encourage users not to run these installations. So the way you get around this is, you buy a real Microsoft authentic code, code-signing certificate from Verisign or Thought, or one of those registers or recognized certification authorities. Yes, that's going to cost you two or three hundred dollars a year, but it's important that you have one of those and sign the MSI file with it after you've created it. In fact, my build, not this one, but my CodeGen build, I just automated that through a process and it runs as a post-build task, every time I build, the MSI just gets signed. But it's an important step. So the recommended reading for this session is Copying and Pasting from Stack Overflow. Yeah, while copying and pasting from the wixtoolset.org, definitely I can recommend, it's got some great samples out there and the tutorial does take a little bit of working through, it's like 70 or 80 pages, but it is pretty good. And of course Blaming the User. One of the best reads out there. Absolutely highly recommended. Any questions about using the WiX toolset? Yes, Ace. Ace: We use WiX pretty heavily and one thing that I didn't see you cover and we're kind of interested in, is how to do MSI patching, because that seems to be a pretty common thing for us. And I guess my second question to you would be, you guys ship a lot of hot fixes, when are you going to start giving me MSI patches? I don't have to run it in a zip file. Steve: Unfortunately, I'm not going to be able to answer any - either of those two questions. It's something that has been in the back of my mind to look into as well and I haven't yet. I'm kind of a novice at this as well, I just learned what I need to learn so far. But you're right, you can build patches, and you can build merge modules that can get shipped with other products and embedded, and all of that kind of stuff. And I'll be honest, I haven't even gone there yet. Marty's the WiX guy at Synergex. Marty: Yeah, I was just going to say, as for shipping MSI patches, the reason we don't is, it would add a lot more testing. We can currently run a full install through a full QA cycle in a reasonable amount of time, so it's more - we're more confident in the product if we just ship the complete installer. Steve: Okay. Audience: Just going back to the merge modules how do we do a silent install to embed Synergex - the Synergy into our installer or is that not going to be best practice. Steve: That is how you do a site - that is something that our stuff does support and I'll be honest, I've never done it, but it's MSI exec - slash whatever it is to suppress the UI. It is supported, you can do it. Okay. Thank you guys. Nigel: Thank you, Steve.
Info
Channel: Synergex
Views: 24,873
Rating: 4.875 out of 5
Keywords: Synergy/DE, Synergy, WiX, Windows Installer
Id: usOh3NQO9Ms
Channel Id: undefined
Length: 46min 7sec (2767 seconds)
Published: Mon Oct 17 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.