]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/installer.wxs
5bb52914b9932d5cf840db9fbefec1664372dce8
[PuTTY.git] / windows / installer.wxs
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <!-- WiX source code for the PuTTY installer. -->
4
5 <?if $(var.Win64) = yes ?>
6   <?define ProgramName = "PuTTY (64-bit)" ?>
7   <?define RegKeyPathLocation = "Software\SimonTatham\PuTTY64" ?>
8   <?define InstallerVersion = "200" ?>
9   <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
10   <?define UpgradeCode_GUID = "C9EAA861-2B72-4FAF-9FEE-EEB1AD5FD15E" ?>
11   <?define PuTTY_Component_GUID = "C673C970-25AE-4659-9621-A1FE0598E9DC" ?>
12   <?define Pageant_Component_GUID = "BA37328A-9A9C-4912-B84D-9C4A21B4E79A" ?>
13   <?define PSFTP_Component_GUID = "8BC2740F-CD4A-4076-8C33-2847ECA17B4E" ?>
14   <?define PuTTYgen_Component_GUID = "4E3F554E-C9C9-419B-9816-94135D1F6EFF" ?>
15   <?define Plink_Component_GUID = "72C38830-1C06-40D5-B2C5-BE21F4C9D529" ?>
16   <?define PSCP_Component_GUID = "58FCAA52-CEF9-4665-B95E-7695FCF8F0A9" ?>
17   <?define HelpFile_Component_GUID = "B880CECB-2CDA-4DB1-8EB3-1627D29394FB" ?>
18   <?define Website_Component_GUID = "08A334E8-D376-438A-98C7-4E65BE09A335" ?>
19   <?define LICENCE_Component_GUID = "D15E5FA9-C912-4F7A-A663-9FE3CFD5FB01" ?>
20   <?define README_Component_GUID = "B8F2F9DE-0311-436E-86A4-BEFED84968C0" ?>
21   <?define PPK_Assoc_Component_GUID = "70B4360C-7A2E-4C9E-9135-289C5467CB04" ?>
22   <?define Path_Component_GUID = "A0CFC986-489D-452B-8A8F-F9DBEF6916F4" ?>
23   <?define ProgramMenuDir_GUID = "3B2B7A2B-25F1-4EC4-987F-75BFD038632E" ?>
24   <?define Desktop_Shortcut_Component_GUID = "0A715416-EA6E-4A1C-8670-838307083EE5" ?>
25 <?else ?>
26   <?define ProgramName = "PuTTY" ?>
27   <?define RegKeyPathLocation = "Software\SimonTatham\PuTTY" ?>
28   <?define InstallerVersion = "100" ?>
29   <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
30   <?define UpgradeCode_GUID = "DCE70C63-8808-4646-B16B-A677BD298385" ?>
31   <?define PuTTY_Component_GUID = "07ACF511-6DF6-4883-AABA-33BC14901324" ?>
32   <?define Pageant_Component_GUID = "649F963E-21C4-4755-8CE4-D80598DCEE6D" ?>
33   <?define PSFTP_Component_GUID = "3D7B9536-EC0E-4A6A-A3DF-8D285474391A" ?>
34   <?define PuTTYgen_Component_GUID = "4774F6B3-8A07-42A5-9F4D-E7FE6AA78B84" ?>
35   <?define Plink_Component_GUID = "7D96F9BB-4154-49D6-86AE-0D8F1379ACBC" ?>
36   <?define PSCP_Component_GUID = "71519D4A-3ED5-4A46-A7E4-B6E4600A8684" ?>
37   <?define HelpFile_Component_GUID = "72806A73-9D4D-49BF-8CAA-E90B0D83AEED" ?>
38   <?define Website_Component_GUID = "7DAD6536-C1A7-430C-BC8A-90176CCB78D0" ?>
39   <?define LICENCE_Component_GUID = "6AB710C0-F7A1-4B7A-AC2E-6993D6E98332" ?>
40   <?define README_Component_GUID = "0AB63F2A-0FD9-4961-B8F7-AB85C22D9986" ?>
41   <?define PPK_Assoc_Component_GUID = "13BBF036-F4C0-4F5B-9167-7BA35C673AAB" ?>
42   <?define Path_Component_GUID = "D1F68AAA-D20D-4047-828F-D0AC443FAF64" ?>
43   <?define ProgramMenuDir_GUID = "C12C3BB3-EC24-4883-8349-4AC8017C9E6A" ?>
44   <?define Desktop_Shortcut_Component_GUID = "D039E3D1-CE42-488D-96CC-90E1DE3796F8" ?>
45 <?endif ?>
46
47 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
48
49   <!--
50       Product tag. The Id component is set to "*", which causes WiX to
51       make up a new GUID every time it's run, whereas UpgradeCode is
52       set to a fixed GUID. This combination allows Windows to
53       recognise each new PuTTY installer as different (because of Id)
54       versions of the same underlying thing (because of the common
55       UpgradeCode).
56
57       $(var.Winver) is define on candle.exe's command line by the
58       build script, and is expected to be a dotted tuple of four
59       16-bit decimal integers (similar to a Windows VERSIONINFO
60       resource). For PuTTY's particular conventions, see comment in
61       Buildscr.
62   -->
63   <Product
64       Name="$(var.ProgramName)"
65       Manufacturer="Simon Tatham"
66       Id="*"
67       UpgradeCode="$(var.UpgradeCode_GUID)"
68       Language="1033" Codepage="1252" Version="$(var.Winver)">
69
70     <!--
71         We force the install scope to perMachine, largely because I
72         don't really understand how to make it usefully switchable
73         between the two. If anyone is a WiX expert and does want to
74         install PuTTY locally in a user account, I hope they'll send a
75         well explained patch!
76
77         $(var.Puttytextver) is again defined on the candle command
78         line, and describes the version of PuTTY in human-readable
79         form, e.g. "PuTTY 0.67" or "PuTTY development snapshot [foo]".
80     -->
81     <Package Id="*" Keywords="Installer"
82              Description="$(var.Puttytextver) installer"
83              Manufacturer="Simon Tatham"
84              InstallerVersion="$(var.InstallerVersion)" Languages="1033"
85              Compressed="yes" SummaryCodepage="1252"
86              InstallScope="perMachine" />
87
88     <!--
89         Permit installing an arbitrary one of these PuTTY installers
90         over the top of an existing one, whether it's an upgrade or a
91         downgrade. In particular, this makes it easy to switch between
92         trunk development snapshots and a release or prerelease, in
93         cases where you change your mind about whether you want the
94         features or the stability.
95
96         Setting the REINSTALLMODE property to "amus" (from its default
97         of "omus") forces every component replaced by a different
98         version of the installer to be _actually_ reinstalled; the 'o'
99         flag in the default setting breaks the downgrade case by
100         causing Windows to disallow installation of an older version
101         over the top of a newer one - and to do so _silently_, so the
102         installer claims to have worked fine but putty.exe isn't
103         there.
104     -->
105     <MajorUpgrade AllowDowngrades="yes" MigrateFeatures="yes" />
106     <Property Id="REINSTALLMODE" Value="amus"/>
107
108     <!-- Boilerplate -->
109     <Media Id="1" Cabinet="putty.cab" EmbedCab="yes" />
110
111     <!--
112         The actual directory structure and list of 'components'
113         (individual files or shortcuts or additions to PATH) that are
114         installed.
115
116         We install directly under "Program Files\PuTTY" rather than
117         the recommended three-level pathname including a manufacturer.
118         It's bad enough that I put my name irrevocably in everyone's
119         Registry without putting it in all of their filesystems as
120         well...
121     -->
122     <Directory Id="TARGETDIR" Name="SourceDir">
123       <Directory Id="$(var.PlatformProgramFilesFolder)" Name="PFiles">
124         <Directory Id="INSTALLDIR" Name="PuTTY">
125
126           <!--
127               The following components all install things in the main
128               install directory (implicitly, by being nested where
129               they are in the XML structure). Most of them also put a
130               shortcut in a subdir of the Start menu, though some of
131               the more obscure things like LICENCE are just there for
132               the sake of being _somewhere_ and don't rate a shortcut.
133           -->
134           <Component Id="PuTTY_Component"
135                      Guid="$(var.PuTTY_Component_GUID)">
136             <File Id="PuTTY_File"
137                   Source="$(var.Builddir)putty.exe" KeyPath="yes">
138               <Shortcut Id="startmenuPuTTY" Directory="ProgramMenuDir"
139                         WorkingDirectory="INSTALLDIR"
140                         Name="PuTTY" Advertise="no" />
141             </File>
142           </Component>
143           <Component Id="Pageant_Component"
144                      Guid="$(var.Pageant_Component_GUID)">
145             <File Id="Pageant_File"
146                   Source="$(var.Builddir)pageant.exe" KeyPath="yes">
147               <Shortcut Id="startmenuPageant" Directory="ProgramMenuDir"
148                         WorkingDirectory="INSTALLDIR"
149                         Name="Pageant" Advertise="no" />
150             </File>
151           </Component>
152           <Component Id="PSFTP_Component"
153                      Guid="$(var.PSFTP_Component_GUID)">
154             <File Id="PSFTP_File"
155                   Source="$(var.Builddir)psftp.exe" KeyPath="yes">
156               <Shortcut Id="startmenuPSFTP" Directory="ProgramMenuDir"
157                         WorkingDirectory="INSTALLDIR"
158                         Name="PSFTP" Advertise="no" />
159             </File>
160           </Component>
161           <Component Id="PuTTYgen_Component"
162                      Guid="$(var.PuTTYgen_Component_GUID)">
163             <File Id="PuTTYgen_File"
164                   Source="$(var.Builddir)puttygen.exe" KeyPath="yes">
165               <Shortcut Id="startmenuPuTTYgen" Directory="ProgramMenuDir"
166                         WorkingDirectory="INSTALLDIR"
167                         Name="PuTTYgen" Advertise="no" />
168             </File>
169           </Component>
170           <Component Id="Plink_Component"
171                      Guid="$(var.Plink_Component_GUID)">
172             <File Id="Plink_File"
173                   Source="$(var.Builddir)plink.exe" KeyPath="yes" />
174           </Component>
175           <Component Id="PSCP_Component"
176                      Guid="$(var.PSCP_Component_GUID)">
177             <File Id="PSCP_File"
178                   Source="$(var.Builddir)pscp.exe" KeyPath="yes" />
179           </Component>
180
181           <Component Id="HelpFile_Component"
182                      Guid="$(var.HelpFile_Component_GUID)">
183             <File Id="HelpFile_File"
184                   Source="..\doc\putty.chm" KeyPath="yes">
185               <Shortcut Id="startmenuManual" Directory="ProgramMenuDir"
186                         Name="PuTTY Manual"
187                         Advertise="no" />
188             </File>
189           </Component>
190           <Component Id="Website_Component"
191                      Guid="$(var.Website_Component_GUID)">
192             <File Id="Website_File"
193                   Source="website.url" KeyPath="yes">
194               <Shortcut Id="startmenuWebsite" Directory="ProgramMenuDir"
195                         Name="PuTTY Web Site"
196                         Advertise="no" />
197             </File>
198           </Component>
199           <Component Id="LICENCE_Component"
200                      Guid="$(var.LICENCE_Component_GUID)">
201             <File Id="LICENCE_File"
202                   Source="..\LICENCE" KeyPath="yes" />
203           </Component>
204           <Component Id="README_Component"
205                      Guid="$(var.README_Component_GUID)">
206             <File Id="README_File"
207                   Source="README-msi.txt" Name="README.txt" KeyPath="yes" />
208           </Component>
209
210           <!--
211               This component sets up the file associations for the
212               .ppk private key file extension: right-clicking should
213               give options to launch both Pageant and PuTTYgen with a
214               given key.
215
216               Unlike all the above components, this one also puts a
217               registry entry in HKEY_LOCAL_MACHINE, which is the 'key
218               path' for the component, i.e. the thing Windows checks
219               to know whether this component is installed. Those have
220               to be either files or registry entries; so for all the
221               above things the key paths are the actual files we
222               wanted to install, whereas for this one we have to
223               invent a spurious extra thing to be the key path.
224           -->
225           <Component Id="PPK_Assoc_Component"
226                      Guid="$(var.PPK_Assoc_Component_GUID)">
227             <ProgId Id="PPK_Assoc_ProgId"
228                     Description="PuTTY Private Key File">
229               <Extension Id="ppk"
230                          ContentType="application/x-putty-private-key">
231                 <Verb Id="open" Command="Load into Pageant"
232                       TargetFile="Pageant_File" Argument='"%1"'/>
233                 <Verb Id="edit" Command="Edit with PuTTYgen"
234                       TargetFile="PuTTYgen_File" Argument='"%1"' />
235               </Extension>
236             </ProgId>
237             <RegistryValue Root="HKLM"
238                            Key="$(var.RegKeyPathLocation)\PPKAssociation"
239                            Type="string" Value="" KeyPath="yes" />
240           </Component>
241
242           <!--
243               This component appends the install directory to PATH, so
244               that command prompt windows automatically get the
245               ability to run the command-line utilities (PSCP, PSFTP
246               and Plink, though all the others are available too if
247               you want). Again, it needs a pointless registry entry to
248               act as a key path.
249           -->
250           <Component Id="Path_Component"
251                      Guid="$(var.Path_Component_GUID)">
252             <Environment Id="Path_Environment"
253                          Name="PATH"
254                          Value="[INSTALLDIR]"
255                          Permanent="no"
256                          Part="last"
257                          Action="set"
258                          System="yes"/>
259             <RegistryValue Root="HKLM"
260                            Key="$(var.RegKeyPathLocation)\PathEntry"
261                            Type="string" Value="" KeyPath="yes" />
262           </Component>
263         </Directory>
264       </Directory>
265
266       <!--
267           This component doesn't actually install anything, but it
268           arranges for the Start Menu _directory_ to be removed again
269           on uninstall. All the actual shortcuts inside the directory
270           are placed by code above here.
271       -->
272       <Directory Id="ProgramMenuFolder" Name="Programs">
273         <Directory Id="ProgramMenuDir" Name="$(var.ProgramName)">
274           <Component Id="ProgramMenuDir"
275                      Guid="$(var.ProgramMenuDir_GUID)">
276             <RemoveFolder Id="ProgramMenuDir" On="uninstall" />
277             <RegistryValue Root="HKLM"
278                            Key="$(var.RegKeyPathLocation)\StartMenu"
279                            Type="string" Value="" KeyPath="yes" />
280           </Component>
281         </Directory>
282       </Directory>
283
284       <!--
285           This component puts a shortcut to PuTTY itself on the
286           desktop.
287       -->
288       <Directory Id="DesktopFolder" Name="Desktop">
289         <Component Id="Desktop_Shortcut_Component"
290                    Guid="$(var.Desktop_Shortcut_Component_GUID)">
291           <Shortcut Id="DesktopPuTTY"
292                     WorkingDirectory="INSTALLDIR" Target="[INSTALLDIR]putty.exe"
293                     Name="$(var.ProgramName)" Advertise="no" />
294           <RegistryValue Root="HKLM"
295                          Key="$(var.RegKeyPathLocation)\DesktopEntry"
296                          Type="string" Value="" KeyPath="yes" />
297         </Component>
298       </Directory>
299     </Directory>
300
301     <!--
302         Detect an installation of PuTTY made by the old Inno Setup
303         installer, and refuse to run if we find one. I don't know what
304         would happen if you tried anyway, but since they install files
305         at the same pathnames, it surely wouldn't end well.
306
307         It could be argued that a better approach would be to actually
308         _launch_ the Inno Setup uninstaller automatically at this
309         point (prompting the user first, of course), but I'm not
310         nearly skilled enough with WiX to know how, or even if it's
311         feasible.
312     -->
313     <Property Id="LEGACYINNOSETUPINSTALLERNATIVE32PROPERTY">
314       <RegistrySearch
315           Id="LegacyInnoSetupInstallerNative32RegSearch"
316           Root="HKLM"
317           Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PuTTY_is1"
318           Name="QuietUninstallString" Type="raw" />
319     </Property>
320     <Property Id="LEGACYINNOSETUPINSTALLER32ON64PROPERTY">
321       <RegistrySearch
322           Id="LegacyInnoSetupInstaller32On64RegSearch"
323           Root="HKLM"
324           Key="SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\PuTTY_is1"
325           Name="QuietUninstallString" Type="raw" />
326     </Property>
327     <Condition Message="A version of PuTTY is already installed on this system using the old Inno Setup installer. Please uninstall that before running the new installer.">
328       <![CDATA[Installed OR
329                (LEGACYINNOSETUPINSTALLERNATIVE32PROPERTY = "" AND
330                 LEGACYINNOSETUPINSTALLER32ON64PROPERTY = "")]]>
331     </Condition>
332
333     <!--
334         Separate the installation into 'features', which are parts of
335         the install that can be chosen separately.
336
337         Since PuTTY is tiny, I haven't bothered to separate the actual
338         _files_ into features; I've just put them all in a single
339         feature that's always installed. The only features that are
340         separately disableable are the auxiliary ones for desktop
341         shortcuts, .PPK file extension and modifying PATH.
342
343         DesktopFeature (the desktop icon) is disabled by default, on
344         the basis of not cluttering up desktops too much unless
345         someone actually wants it. The .PPK association and PATH are
346         behind-the-scenes sorts of thing, so they're on by default.
347
348         (The old Inno Setup installer also made it optional whether
349         PuTTY got a Start Menu subfolder. That seems to be harder in
350         WiX, because the Start Menu shortcuts are tied in to the
351         installation of the files themselves, so the Start Menu
352         subfolder is mandatory if you're using this installer at all.
353         That doesn't seem unreasonable to me - if you don't want
354         _that_, you might as well just unpack the zip file and not
355         bother with an installer at all.)
356     -->
357     <Feature Id="FilesFeature" Level="1" Absent="disallow" AllowAdvertise="no"
358              Title="Install PuTTY files">
359       <ComponentRef Id="PuTTY_Component" />
360       <ComponentRef Id="Pageant_Component" />
361       <ComponentRef Id="PSFTP_Component" />
362       <ComponentRef Id="PuTTYgen_Component" />
363       <ComponentRef Id="Plink_Component" />
364       <ComponentRef Id="PSCP_Component" />
365       <ComponentRef Id="HelpFile_Component" />
366       <ComponentRef Id="Website_Component" />
367       <ComponentRef Id="LICENCE_Component" />
368       <ComponentRef Id="README_Component" />
369       <ComponentRef Id="ProgramMenuDir" />
370     </Feature>
371     <Feature Id="DesktopFeature" Level="2" Absent="allow" AllowAdvertise="no"
372              Title="Add shortcut to PuTTY on the Desktop">
373       <ComponentRef Id="Desktop_Shortcut_Component" />
374     </Feature>
375     <Feature Id="PathFeature" Level="1" Absent="allow" AllowAdvertise="no"
376              Title="Put install directory on the PATH for command prompts">
377       <ComponentRef Id="Path_Component" />
378     </Feature>
379     <Feature Id="PPKFeature" Level="1" Absent="allow" AllowAdvertise="no"
380              Title="Associate .PPK files with PuTTYgen and Pageant">
381       <ComponentRef Id="PPK_Assoc_Component" />
382     </Feature>
383
384     <!--
385         Installer user interface.
386
387         WiX provides several pre-cooked UIs, but annoyingly, every
388         single one of them has the wrong combination of features for
389         what I want. For example, WixUI_InstallDir lets me select the
390         install directory, but not the feature set. WixUI_Advanced
391         lets me select both, but also insists on giving me the option
392         of per-user vs systemwide install (and I haven't managed to
393         get per-user to behave sensibly). And _most_ of them insist on
394         having a click-through EULA page in the interface, which I
395         absolutely don't want - the MIT licence does not need to be
396         presented as a EULA at all (if you didn't accept it in your
397         mind you had no business copying the software in the first
398         place, and it's not imposing any scary restrictions anyway).
399
400         So what we see below is my own sequence of UI dialogs, all
401         included by reference from the WiX standard set. It's probably
402         most similar to WixUI_InstallDir, but I've removed LicenseDlg
403         and included FeaturesDlg.
404
405         (I'm not actually sure that FeaturesDlg is all that good a fit
406         for this particular project, with a treeview control that
407         doesn't really get used as a tree, and inappropriate wording
408         in the dropdown you use to select or deselect features.
409         Perhaps in future I might replace it with a simpler dialog box
410         containing a checkbox for each of the desktop shortcut, the
411         PATH addition and the PPK associations.)
412     -->
413     <UIRef Id="WixUI_Common" />
414
415     <UI>
416       <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
417       <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
418       <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
419
420       <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
421       <Property Id="WixUI_Mode" Value="InstallDir" />
422
423       <DialogRef Id="BrowseDlg" />
424       <DialogRef Id="DiskCostDlg" />
425       <DialogRef Id="ErrorDlg" />
426       <DialogRef Id="FatalError" />
427       <DialogRef Id="FilesInUse" />
428       <DialogRef Id="MsiRMFilesInUse" />
429       <DialogRef Id="PrepareDlg" />
430       <DialogRef Id="ProgressDlg" />
431       <DialogRef Id="ResumeDlg" />
432       <DialogRef Id="UserExit" />
433       <DialogRef Id="FeaturesDlg" />
434
435       <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
436       <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
437
438       <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
439
440       <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
441       <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="FeaturesDlg">Installed</Publish>
442
443       <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
444       <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
445       <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
446       <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
447       <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="FeaturesDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
448       <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
449       <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
450
451       <Publish Dialog="FeaturesDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">Installed</Publish>
452       <Publish Dialog="FeaturesDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg">NOT Installed</Publish>
453       <Publish Dialog="FeaturesDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
454
455       <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
456       <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
457       <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
458
459       <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
460
461       <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
462       <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
463       <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
464
465       <Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" 
466                Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
467
468       <!--
469           This ARPNOMODIFY flag prohibits changing the set of
470           installed features, which would otherwise be possible by
471           reactivating the same MSI (from its original disk file, or
472           in Add/Remove Programs, or I think also by GUID on the
473           msiexec command line) and selecting 'Change' from the
474           maintenance-type dialog.
475
476           The reason I've prohibited it is because I couldn't get it
477           to *work* in my initial testing - it would look as if it had
478           done the right thing, but in fact the features it should
479           have removed would still be there after the installer
480           finished running. So if any WiX expert can help me fix this,
481           I'd love to take this flag out and make the installation
482           retrospectively modifiable!
483
484           (As well as removing this flag and fixing whatever the
485           problem is, I'd also have to add a line in the above set of
486           Publish tags which points MaintenanceTypeDlg's ChangeButton
487           at FeaturesDlg.)
488       -->
489       <Property Id="ARPNOMODIFY" Value="1" />
490     </UI>
491
492     <!--
493         Offer to display README after installation.
494     -->
495     <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT"
496               Value="View README file" />
497     <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1" />
498     <Property Id="WixShellExecTarget" Value="[#README_File]" />
499     <CustomAction Id="LaunchApplication" BinaryKey="WixCA"
500                   DllEntry="WixShellExec" Impersonate="yes" />
501
502     <!-- Glue: tell the install dir part of the UI what id my actual
503          install dir is known by. Otherwise the former won't know how
504          to alter the setting of the latter. -->
505     <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
506
507     <!--
508         Include my custom installer artwork, created in Buildscr.
509     -->
510     <WixVariable Id="WixUIDialogBmp" Value="msidialog.bmp" />
511     <WixVariable Id="WixUIBannerBmp" Value="msibanner.bmp" />
512
513     <!--
514         Set the icon that will show up in Add/Remove Programs.
515
516         http://www.codeproject.com/Articles/43564/WiX-Tricks says that
517         for some weird reason the Id of this icon has to end in .exe.
518     -->
519     <Icon Id="installericon.exe" SourceFile="puttyins.ico" />
520     <Property Id="ARPPRODUCTICON" Value="installericon.exe" />
521
522   </Product>
523 </Wix>