Skip to content

Commit 216cc90

Browse files
committed
Merge pull request #1244 from DigitalFlow/feature/WiX64Bit
Extended WiXHelper types for supporting creation of 64bit setups
2 parents 99e2dd9 + d6c22ff commit 216cc90

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

src/app/FakeLib/WiXHelper.fs

+52-19
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,36 @@ let getFilesAsWiXString files =
5656
|> Seq.map (fileInfo >> wixFile)
5757
|> toLines
5858

59+
type Architecture =
60+
| X64
61+
| X86
62+
override a.ToString() =
63+
match a with
64+
| X64 -> "x64"
65+
| X86 -> "x86"
66+
5967
/// WiX File Element
6068
type WiXFile =
6169
{
70+
/// File Id in WiX definition
6271
Id : string
72+
/// File Name in WiX definition
6373
Name : string
74+
/// File Path in WiX definition
6475
Source : string
76+
/// File Architecture, either X64 or X86, defaults to X64
77+
ProcessorArchitecture : Architecture
6578
}
66-
override w.ToString() = sprintf "<File Id=\"%s\" Name=\"%s\" Source=\"%s\" />"
67-
w.Id w.Name w.Source
79+
override w.ToString() = sprintf "<File Id=\"%s\" Name=\"%s\" Source=\"%s\" ProcessorArchitecture=\"%s\" />"
80+
w.Id w.Name w.Source (w.ProcessorArchitecture.ToString())
6881

6982
/// Defaults for WiX file
7083
let WiXFileDefaults =
7184
{
7285
Id = "fi"
7386
Name = ""
7487
Source = ""
88+
ProcessorArchitecture = X64
7589
}
7690

7791
/// Specifies whether an action occur on install, uninstall or both.
@@ -349,12 +363,13 @@ and WiXComponent =
349363
Id : string
350364
Guid : string
351365
Files : WiXFile seq
366+
Win64 : YesOrNo
352367
ServiceControls : WiXServiceControl seq
353368
ServiceInstalls : WiXServiceInstall seq
354369
}
355370
member w.ToComponentRef() = generateComponentRef (fun f -> { f with Id = w.Id })
356-
override w.ToString() = sprintf "<Component Id=\"%s\" Guid=\"%s\">%s%s%s</Component>"
357-
w.Id w.Guid
371+
override w.ToString() = sprintf "<Component Id=\"%s\" Guid=\"%s\" Win64=\"%s\">%s%s%s</Component>"
372+
w.Id w.Guid (w.Win64.ToString())
358373
(Seq.fold(fun acc elem -> acc + elem.ToString()) "" w.Files)
359374
(Seq.fold(fun acc elem -> acc + elem.ToString()) "" w.ServiceControls)
360375
(Seq.fold(fun acc elem -> acc + elem.ToString()) "" w.ServiceInstalls)
@@ -399,6 +414,7 @@ let WiXComponentDefaults =
399414
{
400415
Id = ""
401416
Guid = "*"
417+
Win64 = Yes
402418
Files = []
403419
ServiceControls = []
404420
ServiceInstalls = []
@@ -411,9 +427,6 @@ let generateComponent (setParams : WiXComponent -> WiXComponent) =
411427
failwith "No parameter passed for component Id!"
412428
parameters
413429

414-
415-
416-
417430
/// Defaults for directories
418431
let WiXDirDefaults =
419432
{
@@ -443,8 +456,13 @@ let private getDirectoryId (directoryName : string) =
443456

444457
let private getFileId (fileName : string) =
445458
"f" + calcSHA1 fileName
459+
460+
let private IsWin64 architecture =
461+
match architecture with
462+
| X64 -> Yes
463+
| X86 -> No
446464

447-
let private createComponents fileFilter directoryInfo directoryName =
465+
let private createComponents fileFilter directoryInfo directoryName architecture =
448466
directoryInfo
449467
|> filesInDir
450468
|> Seq.filter fileFilter
@@ -453,11 +471,13 @@ let private createComponents fileFilter directoryInfo directoryName =
453471
Id = getFileId (directoryName + directoryInfo.Name + file.Name)
454472
Name = file.Name
455473
Source = file.FullName
474+
ProcessorArchitecture = architecture
456475
})
457476
|> Seq.map(fun file->
458477
C{
459478
Id = "c" + file.Id.Substring(1)
460479
Guid = "*"
480+
Win64 = IsWin64 architecture
461481
Files = [file]
462482
ServiceControls = []
463483
ServiceInstalls = []
@@ -469,20 +489,20 @@ let private createComponents fileFilter directoryInfo directoryName =
469489
/// This is vital for major upgrades, since windows installer needs a consistent component guid for tracking each of them.
470490
/// You can use the getComponentRefs function for getting all created component refs and adding them to features.
471491
/// You can use attachServiceControlToComponents or attachServiceInstallToComponents to attach ServiceControl or ServiceInstall to the directory component hierarchy
472-
let rec bulkComponentTreeCreation fileFilter directoryFilter directoryInfo =
492+
let rec bulkComponentTreeCreation fileFilter directoryFilter directoryInfo architecture =
473493
let directoryName = ""
474494
let directories = directoryInfo
475495
|> subDirectories
476496
|> Seq.filter directoryFilter
477-
|> Seq.map (fun d -> bulkComponentTreeSubCreation fileFilter directoryFilter d directoryInfo.Name)
478-
let components = createComponents fileFilter directoryInfo directoryName
497+
|> Seq.map (fun d -> bulkComponentTreeSubCreation fileFilter directoryFilter d directoryInfo.Name architecture)
498+
let components = createComponents fileFilter directoryInfo directoryName architecture
479499
Seq.append directories components
480-
and private bulkComponentTreeSubCreation fileFilter directoryFilter directoryInfo directoryName =
500+
and private bulkComponentTreeSubCreation fileFilter directoryFilter directoryInfo directoryName architecture =
481501
let directories = directoryInfo
482502
|> subDirectories
483503
|> Seq.filter directoryFilter
484-
|> Seq.map (fun d -> bulkComponentTreeSubCreation fileFilter directoryFilter d (directoryName + directoryInfo.Name))
485-
let components = createComponents fileFilter directoryInfo directoryName
504+
|> Seq.map (fun d -> bulkComponentTreeSubCreation fileFilter directoryFilter d (directoryName + directoryInfo.Name) architecture)
505+
let components = createComponents fileFilter directoryInfo directoryName architecture
486506
let currentDirectory = D{
487507
Id = getDirectoryId (directoryInfo.Name + directoryName)
488508
Name = directoryInfo.Name
@@ -496,7 +516,7 @@ and private bulkComponentTreeSubCreation fileFilter directoryFilter directoryInf
496516
/// and set the GUID to "*", which will make WiX produce consistent Component Guids if the Component's target path doesn't change.
497517
/// This is vital for major upgrades, since windows installer needs a consistent component guid for tracking each of them.
498518
/// You can use the getComponentIdsFromWiXString function for getting all created component refs and adding them to features.
499-
let bulkComponentCreation fileFilter directoryInfo =
519+
let bulkComponentCreation fileFilter directoryInfo architecture =
500520
directoryInfo
501521
|> filesInDir
502522
|> Seq.filter fileFilter
@@ -505,11 +525,13 @@ let bulkComponentCreation fileFilter directoryInfo =
505525
Id = "f" + file.Name.GetHashCode().ToString().Replace("-", "")
506526
Name = file.Name
507527
Source = file.FullName
528+
ProcessorArchitecture = architecture
508529
})
509530
|> Seq.map(fun file->
510531
C{
511532
Id = "c" + file.Id.Substring(1)
512533
Guid = "*"
534+
Win64 = IsWin64 architecture
513535
Files = [file]
514536
ServiceControls = []
515537
ServiceInstalls = []
@@ -520,19 +542,19 @@ let bulkComponentCreation fileFilter directoryInfo =
520542
/// and set the GUID to "*", which will make WiX produce consistent Component Guids if the Component's target path doesn't change.
521543
/// This is vital for major upgrades, since windows installer needs a consistent component guid for tracking each of them.
522544
/// The components are embedded into the passed in root directory.
523-
let bulkComponentCreationAsSubDir fileFilter (directoryInfo : DirectoryInfo) =
545+
let bulkComponentCreationAsSubDir fileFilter (directoryInfo : DirectoryInfo) architecture =
524546
{
525547
Id = (directoryInfo.FullName.GetHashCode().ToString())
526548
Name = directoryInfo.Name
527549
Files = []
528-
Components = bulkComponentCreation fileFilter directoryInfo
550+
Components = bulkComponentCreation fileFilter directoryInfo architecture
529551
}
530552

531553
///// Use this to attach service controls to your components.
532554
let rec attachServiceControlToComponent (comp : WiXDirectoryComponent) fileFilter serviceControls =
533555
match comp with
534556
| C c -> C (if fileFilter c then
535-
{ Id = c.Id; Guid = c.Guid; Files = c.Files; ServiceControls = Seq.append c.ServiceControls serviceControls; ServiceInstalls = c.ServiceInstalls }
557+
{ Id = c.Id; Guid = c.Guid; Files = c.Files; ServiceControls = Seq.append c.ServiceControls serviceControls; ServiceInstalls = c.ServiceInstalls; Win64 = c.Win64 }
536558
else
537559
c
538560
)
@@ -545,7 +567,7 @@ and attachServiceControlToComponents (components : WiXDirectoryComponent seq) fi
545567
let rec attachServiceInstallToComponent (comp : WiXDirectoryComponent) fileFilter serviceInstalls =
546568
match comp with
547569
| C c -> C (if fileFilter c then
548-
{ Id = c.Id; Guid = c.Guid; Files = c.Files; ServiceControls = c.ServiceControls; ServiceInstalls = Seq.append c.ServiceInstalls serviceInstalls }
570+
{ Id = c.Id; Guid = c.Guid; Files = c.Files; ServiceControls = c.ServiceControls; ServiceInstalls = Seq.append c.ServiceInstalls serviceInstalls; Win64 = c.Win64 }
549571
else
550572
c
551573
)
@@ -833,6 +855,9 @@ type WiXScript =
833855

834856
/// You can nest InstallExecuteSequence actions in here
835857
ActionSequences : string
858+
859+
/// Specify architecture of package. For 64Bit Setups set ProgramFilesFolder to ProgramFiles64, package platform to X64, all components to Win64 = yes and all files' processorArchitecture to X64.
860+
Platform : Architecture
836861
}
837862

838863
/// Default values for WiX Script properties
@@ -856,6 +881,7 @@ let WiXScriptDefaults =
856881
Features = ""
857882
CustomActions = ""
858883
ActionSequences = ""
884+
Platform = X86
859885
}
860886

861887
/// Used in WiXCustomAction for determing when to run the custom action
@@ -1171,6 +1197,9 @@ type Script =
11711197

11721198
/// You can add custom replacements for the wix xml here.
11731199
CustomReplacements: (string * string) seq
1200+
1201+
/// Specify architecture of package. For 64Bit Setups set ProgramFilesFolder to ProgramFiles64, package platform to X64, all components to Win64 = yes and all files' processorArchitecture to X64.
1202+
Platform : Architecture
11741203
}
11751204

11761205
/// Default values for WiX Script properties
@@ -1195,6 +1224,7 @@ let ScriptDefaults =
11951224
CustomActions = []
11961225
ActionSequences = []
11971226
CustomReplacements = []
1227+
Platform = Architecture.X64
11981228
}
11991229

12001230
/// Generates WiX Template with specified file name (you can prepend location too)
@@ -1225,6 +1255,7 @@ let generateWiXScript fileName =
12251255
Id=\"*\"
12261256
InstallerVersion=\"200\"
12271257
Compressed=\"yes\"
1258+
Platform=\"@Product.Platform@\"
12281259
Description=\"@Product.Description@\"
12291260
Manufacturer=\"@Product.Publisher@\"
12301261
/>
@@ -1306,6 +1337,7 @@ let FillInWixScript wiXPath (setParams : WiXScript -> WiXScript) =
13061337
"@Product.MajorUpgrade@", parameters.MajorUpgrade
13071338
"@Product.Directories@", parameters.Directories
13081339
"@Product.Components@", ""
1340+
"@Product.Platform@", parameters.Platform.ToString()
13091341
"@Product.Features@", parameters.Features
13101342
"@Product.CustomActions@", parameters.CustomActions
13111343
"@Product.ActionSequences@", parameters.ActionSequences
@@ -1356,6 +1388,7 @@ let FillInWiXTemplate wiXPath setParams =
13561388
"@Product.Features@", Seq.fold(fun acc elem -> acc + elem.ToString()) "" parameters.Features
13571389
"@Product.CustomActions@", Seq.fold(fun acc elem -> acc + elem.ToString()) "" parameters.CustomActions
13581390
"@Product.ActionSequences@", Seq.fold(fun acc elem -> acc + elem.ToString()) "" parameters.ActionSequences
1391+
"@Product.Platform@", parameters.Platform.ToString()
13591392
"@Build.number@", parameters.BuildNumber]
13601393
let customReplacements = parameters.CustomReplacements |> Seq.map (fun (key, value) -> ((sprintf "@Custom.%s@" key), value)) |> List.ofSeq
13611394
let replacements = replacements @ customReplacements

0 commit comments

Comments
 (0)