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