aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2024-04-04 16:49:16 -0400
committerBob Arnson <github@bobs.org>2024-04-04 17:48:03 -0400
commitf9ae2561ac4a39ba810234db3b562ca2898ccaf4 (patch)
tree4ce3fa09215aff17c98eba2c16c5d574ff13683d
parent289c93dc24ba203903d9c8a6261a68de95d3d911 (diff)
downloadwix-f9ae2561ac4a39ba810234db3b562ca2898ccaf4.tar.gz
wix-f9ae2561ac4a39ba810234db3b562ca2898ccaf4.tar.bz2
wix-f9ae2561ac4a39ba810234db3b562ca2898ccaf4.zip
Prevent source directories from being harvested.
Fixes https://github.com/wixtoolset/issues/issues/8096.
-rw-r--r--src/internal/SetBuildNumber/Directory.Packages.props.pp1
-rw-r--r--src/wix/WixToolset.Core/HarvestFilesCommand.cs4
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs397
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj1
4 files changed, 196 insertions, 207 deletions
diff --git a/src/internal/SetBuildNumber/Directory.Packages.props.pp b/src/internal/SetBuildNumber/Directory.Packages.props.pp
index bb0f96d8..0c4b1dfb 100644
--- a/src/internal/SetBuildNumber/Directory.Packages.props.pp
+++ b/src/internal/SetBuildNumber/Directory.Packages.props.pp
@@ -5,6 +5,7 @@
5 <PackageVersion Include="WixToolset.Dtf.CustomAction" Version="{packageversion}" /> 5 <PackageVersion Include="WixToolset.Dtf.CustomAction" Version="{packageversion}" />
6 <PackageVersion Include="WixToolset.Dtf.Resources" Version="{packageversion}" /> 6 <PackageVersion Include="WixToolset.Dtf.Resources" Version="{packageversion}" />
7 <PackageVersion Include="WixToolset.Dtf.WindowsInstaller" Version="{packageversion}" /> 7 <PackageVersion Include="WixToolset.Dtf.WindowsInstaller" Version="{packageversion}" />
8 <PackageVersion Include="WixToolset.Dtf.WindowsInstaller.Package" Version="{packageversion}" />
8 9
9 <PackageVersion Include="WixInternal.TestSupport" Version="{packageversion}" /> 10 <PackageVersion Include="WixInternal.TestSupport" Version="{packageversion}" />
10 <PackageVersion Include="WixInternal.TestSupport.Native" Version="{packageversion}" /> 11 <PackageVersion Include="WixInternal.TestSupport.Native" Version="{packageversion}" />
diff --git a/src/wix/WixToolset.Core/HarvestFilesCommand.cs b/src/wix/WixToolset.Core/HarvestFilesCommand.cs
index 4f0c2e2a..9d2d0fe8 100644
--- a/src/wix/WixToolset.Core/HarvestFilesCommand.cs
+++ b/src/wix/WixToolset.Core/HarvestFilesCommand.cs
@@ -128,7 +128,7 @@ namespace WixToolset.Core
128 private IEnumerable<WildcardFile> GetWildcardFiles(HarvestFilesSymbol harvestFile, IEnumerable<string> patterns) 128 private IEnumerable<WildcardFile> GetWildcardFiles(HarvestFilesSymbol harvestFile, IEnumerable<string> patterns)
129 { 129 {
130 var sourceLineNumbers = harvestFile.SourceLineNumbers; 130 var sourceLineNumbers = harvestFile.SourceLineNumbers;
131 var sourcePath = harvestFile.SourcePath; 131 var sourcePath = harvestFile.SourcePath?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
132 132
133 var files = new List<WildcardFile>(); 133 var files = new List<WildcardFile>();
134 134
@@ -158,7 +158,7 @@ namespace WixToolset.Core
158 else if (!Path.IsPathRooted(directoryPortion)) 158 else if (!Path.IsPathRooted(directoryPortion))
159 { 159 {
160 directoryPortion = Path.Combine(sourceDirectory, directoryPortion); 160 directoryPortion = Path.Combine(sourceDirectory, directoryPortion);
161 recursiveDirOffset = sourceDirectory.Length + 1; 161 recursiveDirOffset = directoryPortion.Length + 1;
162 } 162 }
163 163
164 var foundFiles = Directory.EnumerateFiles(directoryPortion, filePortion, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); 164 var foundFiles = Directory.EnumerateFiles(directoryPortion, filePortion, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs
index 8bf03ebb..821660ff 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/HarvestFilesFixture.cs
@@ -2,6 +2,7 @@
2 2
3namespace WixToolsetTest.CoreIntegration 3namespace WixToolsetTest.CoreIntegration
4{ 4{
5 using System;
5 using System.Data; 6 using System.Data;
6 using System.IO; 7 using System.IO;
7 using System.Linq; 8 using System.Linq;
@@ -14,257 +15,293 @@ namespace WixToolsetTest.CoreIntegration
14 [Fact] 15 [Fact]
15 public void MustIncludeSomeFiles() 16 public void MustIncludeSomeFiles()
16 { 17 {
17 var messages = BuildAndQueryComponentFileDirectoryTables("BadAuthoring.wxs", isPackage: true, 10); 18 Build("BadAuthoring.wxs", (_, result) =>
18 Assert.Equal(new[]
19 { 19 {
20 "10", 20 var messages = result.Messages.Select(m => m.Id);
21 }, messages); 21 Assert.Equal(new[]
22 {
23 10,
24 }, messages);
25 });
22 } 26 }
23 27
24 [Fact] 28 [Fact]
25 public void ZeroFilesHarvestedIsAWarning() 29 public void ZeroFilesHarvestedIsAWarning()
26 { 30 {
27 var messages = BuildAndQueryComponentFileDirectoryTables("ZeroFiles.wxs", isPackage: true, 8600); 31 Build("ZeroFiles.wxs", (_, result) =>
28 Assert.Equal(new[]
29 { 32 {
30 "8600", 33 var messages = result.Messages.Select(m => m.Id);
31 }, messages); 34 Assert.Equal(new[]
35 {
36 8600,
37 }, messages);
38 });
32 } 39 }
33 40
34 [Fact] 41 [Fact]
35 public void MissingHarvestDirectoryIsAWarning() 42 public void MissingHarvestDirectoryIsAWarning()
36 { 43 {
37 var messages = BuildAndQueryComponentFileDirectoryTables("BadDirectory.wxs", isPackage: true, 8601); 44 Build("BadDirectory.wxs", (_, result) =>
38 Assert.Equal(new[]
39 { 45 {
40 "8601", 46 var messages = result.Messages.Select(m => m.Id);
41 "8601", 47 Assert.Equal(new[]
42 }, messages); 48 {
49 8601,
50 8601,
51 }, messages);
52 });
43 } 53 }
44 54
45 [Fact] 55 [Fact]
46 public void DuplicateFilesSomethingSomething() 56 public void DuplicateFilesSomethingSomething()
47 { 57 {
48 var messages = BuildAndQueryComponentFileDirectoryTables("DuplicateFiles.wxs", isPackage: true, 8602); 58 Build("DuplicateFiles.wxs", (_, result) =>
49 Assert.Equal(new[]
50 { 59 {
51 "8602", 60 var messages = result.Messages.Select(m => m.Id);
52 "8602", 61 Assert.Equal(new[]
53 "8602", 62 {
54 "8602", 63 8602,
55 }, messages); 64 8602,
65 8602,
66 8602,
67 }, messages);
68 });
56 } 69 }
57 70
58 [Fact] 71 [Fact]
59 public void CanHarvestFilesInComponentGroup() 72 public void HarvestedFilesUnderPackageWithAuthoredFeatureAreOrphaned()
60 { 73 {
61 BuildQueryAssertFiles("ComponentGroup.wxs", new[] 74 Build("PackageWithoutDefaultFeature.wxs", (_, result) =>
62 { 75 {
63 "FileName.Extension", 76 var messages = result.Messages.Select(m => m.Id);
64 "test20.txt", 77 Assert.Equal(new[]
65 "test21.txt", 78 {
66 "test3.txt", 79 267,
67 "test4.txt", 80 267,
81 267,
82 267,
83 }, messages);
68 }); 84 });
69 } 85 }
70 86
71 [Fact] 87 [Fact]
88 public void CanHarvestFilesInComponentGroup()
89 {
90 var expected = new[]
91 {
92 @"fls4di7CtiJhJnEwixr8_c5G8k8aNY=PFiles\MsiPackage\test3.txt",
93 @"flsk5E532wcxn9MfpYQYRnrPi3dsOA=PFiles\MsiPackage\test4.txt",
94 @"flsYh0SwdEpJEootWp2keHMLnnpeb4=PFiles\MsiPackage\files2_sub2\test20.txt",
95 @"flsI4uo74epTPY4TLIcWKVaH.HTbVQ=PFiles\MsiPackage\files2_sub2\test21.txt",
96 @"fls5xOtTcUOA9ZDnUsz1D4Arbw7l_A=PFiles\MsiPackage\files2_sub3\FileName.Extension",
97 };
98
99 Build("ComponentGroup.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
100 }
101
102 [Fact]
72 public void CanHarvestFilesInDirectory() 103 public void CanHarvestFilesInDirectory()
73 { 104 {
74 BuildQueryAssertFiles("Directory.wxs", new[] 105 var expected = new[]
75 { 106 {
76 "test10.txt", 107 @"flsD7JQZm.Ts2375WMT.zsTxqCAf.s=PFiles\MsiPackage\files1_sub1\test10.txt",
77 "test120.txt", 108 @"flslrDWblm4pE.4i4jR58_XyYMmR8I=PFiles\MsiPackage\files1_sub1\files1_sub2\test120.txt",
78 "test2.txt", 109 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
79 "test3.txt", 110 @"flsaFu0CvigRX6Psea0ic6ZWevzLmI=PFiles\MsiPackage\test3.txt",
80 "test4.txt", 111 @"flsJBy_HKCNejalUyud4HisGqhd72E=PFiles\MsiPackage\test4.txt",
81 }); 112 };
113
114 Build("Directory.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
82 } 115 }
83 116
84 [Fact] 117 [Fact]
85 public void CanHarvestFilesInDirectoryRef() 118 public void CanHarvestFilesInDirectoryRef()
86 { 119 {
87 BuildQueryAssertFiles("DirectoryRef.wxs", new[] 120 var expected = new[]
88 { 121 {
89 "notatest.txt", 122 @"flsYgiwrDUkZnBEK6iUMkxxaJlD8yQ=PFiles\MsiPackage\test1.txt",
90 "pleasedontincludeme.dat", 123 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
91 "test1.txt", 124 @"flslrDWblm4pE.4i4jR58_XyYMmR8I=PFiles\MsiPackage\files1_sub1\files1_sub2\test120.txt",
92 "test120.txt", 125 @"flsIpBotASYdALXxudRqekdQdKEKdQ=PFiles\MsiPackage\notatest.txt",
93 "test2.txt", 126 @"flsaFu0CvigRX6Psea0ic6ZWevzLmI=PFiles\MsiPackage\test3.txt",
94 "test20.txt", 127 @"flsJBy_HKCNejalUyud4HisGqhd72E=PFiles\MsiPackage\test4.txt",
95 "test21.txt", 128 @"flsLXU67KiOVU00lZL1jaDaBVpg.Dw=PFiles\MsiPackage\files2_sub2\pleasedontincludeme.dat",
96 "test3.txt", 129 @"fls05.yw49T0FVAq3Wvq2ihNp3KWfI=PFiles\MsiPackage\files2_sub2\test20.txt",
97 "test4.txt", 130 @"flsf0falU_gCTJjtbSCNiFpJQ1d8EM=PFiles\MsiPackage\files2_sub2\test21.txt",
98 }); 131 };
132
133 Build("DirectoryRef.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
99 } 134 }
100 135
101 [Fact] 136 [Fact]
102 public void CanHarvestFilesInFeature() 137 public void CanHarvestFilesInFeature()
103 { 138 {
104 var rows = BuildAndQueryComponentFileDirectoryTables("Feature.wxs"); 139 var expected = new[]
140 {
141 @"flsFGp4MRR_h3Qm.CuBFwC0AJo6b6M=PFiles\Example Product\test2.txt",
142 @"flsTCB.ifIor30C7HfezIDjMB3mrdk=PFiles\Example Product\Assets\test3.txt",
143 @"flsTIP5QnXmYzSzwEM2casYcyn1eR4=PFiles\Example Product\Assets\test4.txt",
144 };
105 145
106 AssertFileComponentIds(3, rows); 146 Build("Feature.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
107 } 147 }
108 148
109 [Fact] 149 [Fact]
110 public void CanHarvestFilesInFeatureGroup() 150 public void CanHarvestFilesInFeatureGroup()
111 { 151 {
112 BuildQueryAssertFiles("FeatureGroup.wxs", new[] 152 var expected = new[]
113 { 153 {
114 "FileName.Extension", 154 @"flsYgiwrDUkZnBEK6iUMkxxaJlD8yQ=PFiles\MsiPackage\test1.txt",
115 "notatest.txt", 155 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
116 "pleasedontincludeme.dat", 156 @"flsXCzqPnLIc2S0BUeTH_BHeaHJgbw=PFiles\MsiPackage\assets\notatest.txt",
117 "test1.txt", 157 @"flsiPGfLix0PMEZQ.BGdIfMp43g0m0=PFiles\MsiPackage\assets\test3.txt",
118 "test2.txt", 158 @"flsQp7vl8wg1R6a9pWOuj0y8X9tFdk=PFiles\MsiPackage\assets\test4.txt",
119 "test20.txt", 159 @"flsROfaiHyEp8AGBy4ZIkz26B8x0QE=PFiles\MsiPackage\assets\files2_sub2\pleasedontincludeme.dat",
120 "test21.txt", 160 @"flsR7cMdABXp6bHg2a89trPLf9NuKU=PFiles\MsiPackage\assets\files2_sub2\test20.txt",
121 "test3.txt", 161 @"flse0V.F.q.LFFjytlCECxjK5io7g0=PFiles\MsiPackage\assets\files2_sub2\test21.txt",
122 "test4.txt", 162 @"flsQk6.O4lkg78pGc4Ye64mosdl3hY=PFiles\MsiPackage\assets\files2_sub3\FileName.Extension",
123 }); 163 };
164
165 Build("FeatureGroup.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
124 } 166 }
125 167
126 [Fact] 168 [Fact]
127 public void CanHarvestFilesInStraightAndCrookedTrees() 169 public void CanHarvestFilesInStraightAndCrookedTrees()
128 { 170 {
129 var rows = BuildAndQueryComponentFileDirectoryTables("CrookedTree.wxs"); 171 var expected = new[]
130 var directoryRows = rows.Where(row => row.StartsWith("Directory:")).Select(d => d.Substring(10)).ToArray();
131
132 var rootDirectoryId = directoryRows.Single(r => r.EndsWith("\troot")).Split('\t')[0];
133
134 foreach (var ch in new[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'z' })
135 { 172 {
136 var directoryRow = directoryRows.Single(r => r.EndsWith($"\t{ch}")); 173 @"flsKwXKj_Znab7ED_V5tgmdm6I35Mk=PFiles\root\a\file.ext",
137 var parentDirectory = directoryRow.Split('\t')[1]; 174 @"flsG_e554dKs4hJ6VckjXfvHVbrQ_c=PFiles\root\b\file.ext",
138 Assert.Equal(rootDirectoryId, parentDirectory); 175 @"fls6QPA6Lio8i18jzGOvfZpb2vxh9M=PFiles\root\c\file.ext",
139 } 176 @"flsfPnakkQEQynhlS0Z9wVZMXLjKx4=PFiles\root\d\file.ext",
177 @"fls9z8lqK0ZvjlnUEzCDIE7bF01zXU=PFiles\root\e\file.ext",
178 @"flsFqGICaLl5ZLPsdJY.Z2m6xC2Khs=PFiles\root\f\file.ext",
179 @"flsUT96SVd6kTNE4X7vBFL7r3Zl4sM=PFiles\root\g\file.ext",
180 @"fls.i3qm35eVOQoWBJFaj3c9792GKc=PFiles\root\h\file.ext",
181 @"flsgKGasxQIkFWfpTA6kQurqEL4Afg=PFiles\root\file.ext",
182 @"flsZGaHZm_l9M8jaQS8XSgxnlykcKI=PFiles\root\z\y\x\w\v\u\t\s\r\q\file.ext",
183 };
184
185 Build("CrookedTree.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
140 } 186 }
141 187
142 [Fact] 188 [Fact]
143 public void CanHarvestFilesInFeatureRef() 189 public void CanHarvestFilesInFeatureRef()
144 { 190 {
145 BuildQueryAssertFiles("FeatureRef.wxs", new[] 191 var expected = new[]
146 { 192 {
147 "FileName.Extension", 193 @"flsYgiwrDUkZnBEK6iUMkxxaJlD8yQ=PFiles\MsiPackage\test1.txt",
148 "notatest.txt", 194 @"flsj.cb0sFWqIPHPFSKJSEEaPDuAQ4=PFiles\MsiPackage\test2.txt",
149 "pleasedontincludeme.dat", 195 @"flsXCzqPnLIc2S0BUeTH_BHeaHJgbw=PFiles\MsiPackage\assets\notatest.txt",
150 "test1.txt", 196 @"flsiPGfLix0PMEZQ.BGdIfMp43g0m0=PFiles\MsiPackage\assets\test3.txt",
151 "test2.txt", 197 @"flsQp7vl8wg1R6a9pWOuj0y8X9tFdk=PFiles\MsiPackage\assets\test4.txt",
152 "test20.txt", 198 @"flsROfaiHyEp8AGBy4ZIkz26B8x0QE=PFiles\MsiPackage\assets\files2_sub2\pleasedontincludeme.dat",
153 "test21.txt", 199 @"flsR7cMdABXp6bHg2a89trPLf9NuKU=PFiles\MsiPackage\assets\files2_sub2\test20.txt",
154 "test3.txt", 200 @"flse0V.F.q.LFFjytlCECxjK5io7g0=PFiles\MsiPackage\assets\files2_sub2\test21.txt",
155 "test4.txt", 201 @"flsQk6.O4lkg78pGc4Ye64mosdl3hY=PFiles\MsiPackage\assets\files2_sub3\FileName.Extension",
156 }); 202 };
203
204 Build("FeatureRef.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
157 } 205 }
158 206
159 [Fact] 207 [Fact]
160 public void CanHarvestFilesInFragments() 208 public void CanHarvestFilesInFragments()
161 { 209 {
162 BuildQueryAssertFiles("Fragment.wxs", new[] 210 var expected = new[]
163 { 211 {
164 "notatest.txt", 212 @"flsOQDmBHyBKZnyRziE3.z5HjmBv4k=PFiles\MsiPackage\test1.txt",
165 "test1.txt", 213 @"flsHjzoVbTTY2jQbthZHKG7Rn4yMZo=PFiles\MsiPackage\test2.txt",
166 "test2.txt", 214 @"flsPLx4KqFVkbnYyg3Uo4QdiRLFbL8=PFiles\MsiPackage\notatest.txt",
167 "test3.txt", 215 @"fls4di7CtiJhJnEwixr8_c5G8k8aNY=PFiles\MsiPackage\test3.txt",
168 "test4.txt", 216 @"flsk5E532wcxn9MfpYQYRnrPi3dsOA=PFiles\MsiPackage\test4.txt",
169 }); 217 };
218
219 Build("Fragment.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
170 } 220 }
171 221
172 [Fact] 222 [Fact]
173 public void CanHarvestFilesInModules() 223 public void CanHarvestFilesInModules()
174 { 224 {
175 BuildQueryAssertFiles("Module.wxs", new[] 225 var expected = new[]
176 { 226 {
177 "notatest.txt", 227 @"flsgrgAVAsCQ8tCCxfnbBNis66623c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test1.txt",
178 "test1.txt", 228 @"flsDBWSWjpVSU3Zs33bREsJa2ygSQM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test2.txt",
179 "test2.txt", 229 @"flsehdwEdXusUijRShuTszSxwf8joA.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test3.txt",
180 "test3.txt", 230 @"flsBvxG729t7hKBa4KOmfvNMPptZkM.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\test4.txt",
181 "test4.txt", 231 @"flskqOUVMfAE13k2h.ZkPhurwO4Y1c.E535B765_1019_4A4F_B3EA_AE28870E6D73=PFiles\MergeModule\notatest.txt",
182 }, isPackage: false); 232 };
233
234 Build("Module.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected), isPackage: false);
183 } 235 }
184 236
185 [Fact] 237 [Fact]
186 public void CanHarvestFilesWithBindPaths() 238 public void CanHarvestFilesWithBindPaths()
187 { 239 {
188 BuildQueryAssertFiles("BindPaths.wxs", new[] 240 var expected = new[]
189 { 241 {
190 "FileName.Extension", 242 @"flsNNsTNrgmjASmTBbP.45J1F50dEc=PFiles\HarvestedFiles\test1.txt",
191 "test1.txt", 243 @"flsASLR5pHQzLmWRE.Snra7ndH7sIA=PFiles\HarvestedFiles\test2.txt",
192 "test10.txt", 244 @"flsTZFPiMHb.qfUxdGKQYrnXOhZ.8M=PFiles\HarvestedFiles\files1_sub1\test10.txt",
193 "test120.txt", 245 @"flsLGcTTZPIU3ELiWybqnm.PQ0Ih_g=PFiles\HarvestedFiles\files1_sub1\files1_sub2\test120.txt",
194 "test2.txt", 246 @"fls1Jx2Y9Vea_.WZBH_h2e79arvDRU=PFiles\HarvestedFiles\test3.txt",
195 "test20.txt", 247 @"flsJ9gNxWaau2X3ufphQuCV9WwAgcw=PFiles\HarvestedFiles\test4.txt",
196 "test21.txt", 248 @"flswcmX9dpMQytmD_5QA5aJ5szoQVA=PFiles\HarvestedFiles\files2_sub2\test20.txt",
197 "test3.txt", 249 @"flskKeCKFUtCYMuvw564rgPLJmyBx0=PFiles\HarvestedFiles\files2_sub2\test21.txt",
198 "test4.txt", 250 @"fls2agLZFnQwjoijShwT9Z0RwHyGrI=PFiles\HarvestedFiles\files2_sub3\FileName.Extension",
199 }); 251 };
200 } 252
201 253 Build("BindPaths.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
202 [Fact]
203 public void HarvestedFilesUnderPackageWithAuthoredFeatureAreOrphaned()
204 {
205 var messages = BuildAndQueryComponentFileDirectoryTables("PackageWithoutDefaultFeature.wxs", isPackage: true, 267);
206 Assert.Equal(new[]
207 {
208 "267",
209 "267",
210 "267",
211 "267",
212 }, messages);
213 } 254 }
214 255
215 [Fact] 256 [Fact]
216 public void CanHarvestFilesInStandardDirectory() 257 public void CanHarvestFilesInStandardDirectory()
217 { 258 {
218 BuildQueryAssertFiles("StandardDirectory.wxs", new[] 259 var expected = new[]
219 { 260 {
220 "FileName.Extension", 261 @"flsxKKnXWKGChnZD8KSNY4Mwb48nHc=PFiles\MsiPackage\test1.txt",
221 "notatest.txt", 262 @"flsVa.JZ23qQ1vXrc1jjOLIyJMyuqM=PFiles\MsiPackage\test2.txt",
222 "pleasedontincludeme.dat", 263 @"fls4_TTxMCivlzpVJiyNHQRa2eU2ZA=PFiles\MsiPackage\files1_sub1\test10.txt",
223 "test1.txt", 264 @"flsBQqnyJp3XnmzomCYT_1qJqKLeSA=PFiles\MsiPackage\files1_sub1\files1_sub2\test120.txt",
224 "test10.txt", 265 @"flsbr7Ii_L1MRmxOImvY3N7np5FqAU=PFiles\MsiPackage\notatest.txt",
225 "test120.txt", 266 @"fls5VacfuX4Iub..BmTvssAOUcUI1o=PFiles\MsiPackage\test3.txt",
226 "test2.txt", 267 @"flsTtxen6j9kDjhKw2rnKSlYn5e2_k=PFiles\MsiPackage\test4.txt",
227 "test20.txt", 268 @"flsKEAYr7hAov7KfiRTjHg1VBg6T38=PFiles\MsiPackage\files2_sub2\pleasedontincludeme.dat",
228 "test21.txt", 269 @"flsvw4WMs4foeBokT9VUN3qjPDg8jc=PFiles\MsiPackage\files2_sub2\test20.txt",
229 "test3.txt", 270 @"flspraz8bfD0UXdCBW9CS2jr49hl1k=PFiles\MsiPackage\files2_sub2\test21.txt",
230 "test4.txt", 271 @"flsCgt3Noa1VJHlHG5HOVjD5vdJm5Q=PFiles\MsiPackage\files2_sub3\FileName.Extension",
231 }); 272 };
273
274 Build("StandardDirectory.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
232 } 275 }
233 276
234 [Fact] 277 [Fact]
235 public void CanHarvestFilesInFiveLines() 278 public void CanHarvestFilesInFiveLines()
236 { 279 {
237 BuildQueryAssertFiles("PackageFiveLiner.wxs", new[] 280 var expected = new[]
238 { 281 {
239 "FileName.Extension", 282 @"flsIpBotASYdALXxudRqekdQdKEKdQ=PFiles\Example Corporation MsiPackage\notatest.txt",
240 "notatest.txt", 283 @"flsaFu0CvigRX6Psea0ic6ZWevzLmI=PFiles\Example Corporation MsiPackage\test3.txt",
241 "pleasedontincludeme.dat", 284 @"flsJBy_HKCNejalUyud4HisGqhd72E=PFiles\Example Corporation MsiPackage\test4.txt",
242 "test20.txt", 285 @"flsLXU67KiOVU00lZL1jaDaBVpg.Dw=PFiles\Example Corporation MsiPackage\files2_sub2\pleasedontincludeme.dat",
243 "test21.txt", 286 @"fls05.yw49T0FVAq3Wvq2ihNp3KWfI=PFiles\Example Corporation MsiPackage\files2_sub2\test20.txt",
244 "test3.txt", 287 @"flsf0falU_gCTJjtbSCNiFpJQ1d8EM=PFiles\Example Corporation MsiPackage\files2_sub2\test21.txt",
245 "test4.txt", 288 @"fls6Dd0lNq_VzYLYjK7ty5WxNy5KCs=PFiles\Example Corporation MsiPackage\files2_sub3\FileName.Extension",
246 }); 289 };
290
291 Build("PackageFiveLiner.wxs", (msiPath, _) => AssertFileIdsAndTargetPaths(msiPath, expected));
247 } 292 }
248 293
249 private static void BuildQueryAssertFiles(string file, string[] expectedFileNames, bool isPackage = true, int? exitCode = null) 294 private static void AssertFileIdsAndTargetPaths(string msiPath, string[] expected)
250 { 295 {
251 var rows = BuildAndQueryComponentFileDirectoryTables(file, isPackage, exitCode); 296 var pkg = new WixToolset.Dtf.WindowsInstaller.Package.InstallPackage(msiPath,
297 WixToolset.Dtf.WindowsInstaller.DatabaseOpenMode.ReadOnly);
298 var sortedExpected = expected.OrderBy(s => s);
299 var actual = pkg.Files.OrderBy(kvp => kvp.Key).Select(kvp => $"{kvp.Key}={kvp.Value.TargetPath}");
252 300
253 var fileNames = AssertFileComponentIds(expectedFileNames.Length, rows); 301 Assert.Equal(sortedExpected, actual);
254
255 Assert.Equal(expectedFileNames, fileNames);
256 } 302 }
257 303
258 private static void BuildQueryDirectoryComponent(string file, string[] expectedFileNames, bool isPackage = true, int? exitCode = null) 304 private static void Build(string file, Action<string, WixRunnerResult> tester, bool isPackage = true)
259 {
260 var rows = BuildAndQueryComponentFileDirectoryTables(file, isPackage, exitCode);
261
262 var fileNames = AssertFileComponentIds(expectedFileNames.Length, rows);
263
264 Assert.Equal(expectedFileNames, fileNames);
265 }
266
267 private static string[] BuildAndQueryComponentFileDirectoryTables(string file, bool isPackage = true, int? exitCode = null)
268 { 305 {
269 var folder = TestData.Get("TestData", "HarvestFiles"); 306 var folder = TestData.Get("TestData", "HarvestFiles");
270 307
@@ -288,57 +325,7 @@ namespace WixToolsetTest.CoreIntegration
288 325
289 var result = WixRunner.Execute(arguments); 326 var result = WixRunner.Execute(arguments);
290 327
291 if (exitCode.HasValue) 328 tester(msiPath, result);
292 {
293 Assert.Equal(exitCode.Value, result.ExitCode);
294
295 return result.Messages.Select(m => m.Id.ToString()).ToArray();
296 }
297 else
298 {
299 result.AssertSuccess();
300
301 return Query.QueryDatabase(msiPath, new[] { "Component", "File", "Directory" })
302 .OrderBy(s => s)
303 .ToArray();
304 }
305 }
306 }
307
308 private static string[] AssertFileComponentIds(int fileCount, string[] rows)
309 {
310 var componentRows = rows.Where(row => row.StartsWith("Component:")).ToArray();
311 var fileRows = rows.Where(row => row.StartsWith("File:")).ToArray();
312
313 Assert.Equal(componentRows.Length, fileRows.Length);
314
315 // Component id == Component keypath == File id
316 foreach (var componentRow in componentRows)
317 {
318 var columns = componentRow.Split(':', '\t');
319 Assert.Equal(columns[1], columns[6]);
320 }
321
322 foreach (var fileRow in fileRows)
323 {
324 var columns = fileRow.Split(':', '\t');
325 Assert.Equal(columns[1], columns[2]);
326 }
327
328 Assert.Equal(fileCount, componentRows.Length);
329
330 var files = fileRows.Select(row => row.Split('\t')[2]);
331 var lfns = files.Select(name => name.Split('|'));
332
333 return fileRows
334 .Select(row => row.Split('\t')[2])
335 .Select(GetLFN)
336 .OrderBy(name => name).ToArray();
337
338 static string GetLFN(string possibleSfnLfnPair)
339 {
340 var parts = possibleSfnLfnPair.Split('|');
341 return parts[parts.Length - 1];
342 } 329 }
343 } 330 }
344 } 331 }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj b/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
index 7d7c9a0c..e0b5afd4 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
@@ -22,5 +22,6 @@
22 22
23 <ItemGroup> 23 <ItemGroup>
24 <PackageReference Include="WixInternal.TestSupport" /> 24 <PackageReference Include="WixInternal.TestSupport" />
25 <PackageReference Include="WixToolset.Dtf.WindowsInstaller.Package" />
25 </ItemGroup> 26 </ItemGroup>
26</Project> 27</Project>