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