diff options
Diffstat (limited to 'src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs')
-rw-r--r-- | src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs | 425 |
1 files changed, 238 insertions, 187 deletions
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs index 39a71be7..5fcf172f 100644 --- a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs | |||
@@ -3,7 +3,6 @@ | |||
3 | namespace WixToolset.Core.Burn.Bundles | 3 | namespace WixToolset.Core.Burn.Bundles |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections; | ||
7 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
8 | using System.Diagnostics; | 7 | using System.Diagnostics; |
9 | using System.Globalization; | 8 | using System.Globalization; |
@@ -11,47 +10,62 @@ namespace WixToolset.Core.Burn.Bundles | |||
11 | using System.Linq; | 10 | using System.Linq; |
12 | using WixToolset.Data; | 11 | using WixToolset.Data; |
13 | using WixToolset.Extensibility; | 12 | using WixToolset.Extensibility; |
14 | using WixToolset.Core.Native; | ||
15 | using Dtf = WixToolset.Dtf.WindowsInstaller; | 13 | using Dtf = WixToolset.Dtf.WindowsInstaller; |
16 | using WixToolset.Data.Bind; | 14 | using WixToolset.Extensibility.Services; |
15 | using WixToolset.Data.Tuples; | ||
16 | using WixToolset.Data.WindowsInstaller; | ||
17 | using WixToolset.Extensibility.Data; | ||
17 | 18 | ||
18 | /// <summary> | 19 | /// <summary> |
19 | /// Initializes package state from the MSI contents. | 20 | /// Initializes package state from the MSI contents. |
20 | /// </summary> | 21 | /// </summary> |
21 | internal class ProcessMsiPackageCommand | 22 | internal class ProcessMsiPackageCommand |
22 | { | 23 | { |
23 | #if TODO | ||
24 | private const string PropertySqlFormat = "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'"; | 24 | private const string PropertySqlFormat = "SELECT `Value` FROM `Property` WHERE `Property` = '{0}'"; |
25 | 25 | ||
26 | public RowDictionary<WixBundlePayloadRow> AuthoredPayloads { private get; set; } | 26 | public ProcessMsiPackageCommand(IServiceProvider serviceProvider, IEnumerable<IBurnBackendExtension> backendExtensions, IntermediateSection section, PackageFacade facade, Dictionary<string, WixBundlePayloadTuple> payloadTuples) |
27 | { | ||
28 | this.Messaging = serviceProvider.GetService<IMessaging>(); | ||
29 | this.BackendHelper = serviceProvider.GetService<IBackendHelper>(); | ||
30 | this.PathResolver = serviceProvider.GetService<IPathResolver>(); | ||
31 | |||
32 | this.BackendExtensions = backendExtensions; | ||
33 | |||
34 | this.AuthoredPayloads = payloadTuples; | ||
35 | this.Section = section; | ||
36 | this.Facade = facade; | ||
37 | } | ||
38 | |||
39 | private IMessaging Messaging { get; } | ||
27 | 40 | ||
28 | public PackageFacade Facade { private get; set; } | 41 | private IBackendHelper BackendHelper { get; } |
29 | 42 | ||
30 | public IEnumerable<IBurnBackendExtension> BackendExtensions { private get; set; } | 43 | private IPathResolver PathResolver { get; } |
31 | 44 | ||
32 | public Table MsiFeatureTable { private get; set; } | 45 | private IEnumerable<IBurnBackendExtension> BackendExtensions { get; } |
33 | 46 | ||
34 | public Table MsiPropertyTable { private get; set; } | 47 | private Dictionary<string, WixBundlePayloadTuple> AuthoredPayloads { get; } |
35 | 48 | ||
36 | public Table PayloadTable { private get; set; } | 49 | private PackageFacade Facade { get; } |
37 | 50 | ||
38 | public Table RelatedPackageTable { private get; set; } | 51 | private IntermediateSection Section { get; } |
39 | 52 | ||
40 | /// <summary> | 53 | /// <summary> |
41 | /// Processes the MSI packages to add properties and payloads from the MSI packages. | 54 | /// Processes the MSI packages to add properties and payloads from the MSI packages. |
42 | /// </summary> | 55 | /// </summary> |
43 | public void Execute() | 56 | public void Execute() |
44 | { | 57 | { |
45 | WixBundlePayloadRow packagePayload = this.AuthoredPayloads.Get(this.Facade.Package.PackagePayload); | 58 | var packagePayload = this.AuthoredPayloads[this.Facade.PackageTuple.PayloadRef]; |
46 | 59 | ||
47 | string sourcePath = packagePayload.FullFileName; | 60 | var msiPackage = (WixBundleMsiPackageTuple)this.Facade.SpecificPackageTuple; |
48 | bool longNamesInImage = false; | 61 | |
49 | bool compressed = false; | 62 | var sourcePath = packagePayload.SourceFile.Path; |
50 | bool x64 = false; | 63 | var longNamesInImage = false; |
64 | var compressed = false; | ||
51 | try | 65 | try |
52 | { | 66 | { |
53 | // Read data out of the msi database... | 67 | // Read data out of the msi database... |
54 | using (Dtf.SummaryInfo sumInfo = new Dtf.SummaryInfo(sourcePath, false)) | 68 | using (var sumInfo = new Dtf.SummaryInfo(sourcePath, false)) |
55 | { | 69 | { |
56 | // 1 is the Word Count summary information stream bit that means | 70 | // 1 is the Word Count summary information stream bit that means |
57 | // the MSI uses short file names when set. We care about long file | 71 | // the MSI uses short file names when set. We care about long file |
@@ -62,83 +76,84 @@ namespace WixToolset.Core.Burn.Bundles | |||
62 | // files are compressed in the MSI by default when the bit is set. | 76 | // files are compressed in the MSI by default when the bit is set. |
63 | compressed = 2 == (sumInfo.WordCount & 2); | 77 | compressed = 2 == (sumInfo.WordCount & 2); |
64 | 78 | ||
65 | x64 = (sumInfo.Template.Contains("x64") || sumInfo.Template.Contains("Intel64")); | ||
66 | |||
67 | // 8 is the Word Count summary information stream bit that means | 79 | // 8 is the Word Count summary information stream bit that means |
68 | // "Elevated privileges are not required to install this package." | 80 | // "Elevated privileges are not required to install this package." |
69 | // in MSI 4.5 and below, if this bit is 0, elevation is required. | 81 | // in MSI 4.5 and below, if this bit is 0, elevation is required. |
70 | this.Facade.Package.PerMachine = (0 == (sumInfo.WordCount & 8)) ? YesNoDefaultType.Yes : YesNoDefaultType.No; | 82 | var perMachine = (0 == (sumInfo.WordCount & 8)); |
71 | this.Facade.Package.x64 = x64 ? YesNoType.Yes : YesNoType.No; | 83 | var x64 = (sumInfo.Template.Contains("x64") || sumInfo.Template.Contains("Intel64")); |
84 | |||
85 | this.Facade.PackageTuple.PerMachine = perMachine ? YesNoDefaultType.Yes : YesNoDefaultType.No; | ||
86 | this.Facade.PackageTuple.Win64 = x64; | ||
72 | } | 87 | } |
73 | 88 | ||
74 | using (Dtf.Database db = new Dtf.Database(sourcePath)) | 89 | using (var db = new Dtf.Database(sourcePath)) |
75 | { | 90 | { |
76 | this.Facade.MsiPackage.ProductCode = ProcessMsiPackageCommand.GetProperty(db, "ProductCode"); | 91 | msiPackage.ProductCode = ProcessMsiPackageCommand.GetProperty(db, "ProductCode"); |
77 | this.Facade.MsiPackage.UpgradeCode = ProcessMsiPackageCommand.GetProperty(db, "UpgradeCode"); | 92 | msiPackage.UpgradeCode = ProcessMsiPackageCommand.GetProperty(db, "UpgradeCode"); |
78 | this.Facade.MsiPackage.Manufacturer = ProcessMsiPackageCommand.GetProperty(db, "Manufacturer"); | 93 | msiPackage.Manufacturer = ProcessMsiPackageCommand.GetProperty(db, "Manufacturer"); |
79 | this.Facade.MsiPackage.ProductLanguage = Convert.ToInt32(ProcessMsiPackageCommand.GetProperty(db, "ProductLanguage"), CultureInfo.InvariantCulture); | 94 | msiPackage.ProductLanguage = Convert.ToInt32(ProcessMsiPackageCommand.GetProperty(db, "ProductLanguage"), CultureInfo.InvariantCulture); |
80 | this.Facade.MsiPackage.ProductVersion = ProcessMsiPackageCommand.GetProperty(db, "ProductVersion"); | 95 | msiPackage.ProductVersion = ProcessMsiPackageCommand.GetProperty(db, "ProductVersion"); |
81 | 96 | ||
82 | if (!Common.IsValidModuleOrBundleVersion(this.Facade.MsiPackage.ProductVersion)) | 97 | if (!Common.IsValidModuleOrBundleVersion(msiPackage.ProductVersion)) |
83 | { | 98 | { |
84 | // not a proper .NET version (e.g., five fields); can we get a valid four-part version number? | 99 | // not a proper .NET version (e.g., five fields); can we get a valid four-part version number? |
85 | string version = null; | 100 | string version = null; |
86 | string[] versionParts = this.Facade.MsiPackage.ProductVersion.Split('.'); | 101 | string[] versionParts = msiPackage.ProductVersion.Split('.'); |
87 | int count = versionParts.Length; | 102 | var count = versionParts.Length; |
88 | if (0 < count) | 103 | if (0 < count) |
89 | { | 104 | { |
90 | version = versionParts[0]; | 105 | version = versionParts[0]; |
91 | for (int i = 1; i < 4 && i < count; ++i) | 106 | for (var i = 1; i < 4 && i < count; ++i) |
92 | { | 107 | { |
93 | version = String.Concat(version, ".", versionParts[i]); | 108 | version = String.Concat(version, ".", versionParts[i]); |
94 | } | 109 | } |
95 | } | 110 | } |
96 | 111 | ||
97 | if (!String.IsNullOrEmpty(version) && Common.IsValidModuleOrBundleVersion(version)) | 112 | if (!String.IsNullOrEmpty(version) && Common.IsValidModuleOrBundleVersion(version)) |
98 | { | 113 | { |
99 | Messaging.Instance.OnMessage(WixWarnings.VersionTruncated(this.Facade.Package.SourceLineNumbers, this.Facade.MsiPackage.ProductVersion, sourcePath, version)); | 114 | this.Messaging.Write(WarningMessages.VersionTruncated(this.Facade.PackageTuple.SourceLineNumbers, msiPackage.ProductVersion, sourcePath, version)); |
100 | this.Facade.MsiPackage.ProductVersion = version; | 115 | msiPackage.ProductVersion = version; |
101 | } | 116 | } |
102 | else | 117 | else |
103 | { | 118 | { |
104 | Messaging.Instance.OnMessage(WixErrors.InvalidProductVersion(this.Facade.Package.SourceLineNumbers, this.Facade.MsiPackage.ProductVersion, sourcePath)); | 119 | this.Messaging.Write(ErrorMessages.InvalidProductVersion(this.Facade.PackageTuple.SourceLineNumbers, msiPackage.ProductVersion, sourcePath)); |
105 | } | 120 | } |
106 | } | 121 | } |
107 | 122 | ||
108 | if (String.IsNullOrEmpty(this.Facade.Package.CacheId)) | 123 | if (String.IsNullOrEmpty(this.Facade.PackageTuple.CacheId)) |
109 | { | 124 | { |
110 | this.Facade.Package.CacheId = String.Format("{0}v{1}", this.Facade.MsiPackage.ProductCode, this.Facade.MsiPackage.ProductVersion); | 125 | this.Facade.PackageTuple.CacheId = String.Format("{0}v{1}", msiPackage.ProductCode, msiPackage.ProductVersion); |
111 | } | 126 | } |
112 | 127 | ||
113 | if (String.IsNullOrEmpty(this.Facade.Package.DisplayName)) | 128 | if (String.IsNullOrEmpty(this.Facade.PackageTuple.DisplayName)) |
114 | { | 129 | { |
115 | this.Facade.Package.DisplayName = ProcessMsiPackageCommand.GetProperty(db, "ProductName"); | 130 | this.Facade.PackageTuple.DisplayName = ProcessMsiPackageCommand.GetProperty(db, "ProductName"); |
116 | } | 131 | } |
117 | 132 | ||
118 | if (String.IsNullOrEmpty(this.Facade.Package.Description)) | 133 | if (String.IsNullOrEmpty(this.Facade.PackageTuple.Description)) |
119 | { | 134 | { |
120 | this.Facade.Package.Description = ProcessMsiPackageCommand.GetProperty(db, "ARPCOMMENTS"); | 135 | this.Facade.PackageTuple.Description = ProcessMsiPackageCommand.GetProperty(db, "ARPCOMMENTS"); |
121 | } | 136 | } |
122 | 137 | ||
123 | ISet<string> payloadNames = this.GetPayloadTargetNames(); | 138 | var payloadNames = this.GetPayloadTargetNames(packagePayload.Id.Id); |
124 | 139 | ||
125 | ISet<string> msiPropertyNames = this.GetMsiPropertyNames(); | 140 | var msiPropertyNames = this.GetMsiPropertyNames(packagePayload.Id.Id); |
126 | 141 | ||
127 | this.SetPerMachineAppropriately(db, sourcePath); | 142 | this.SetPerMachineAppropriately(db, msiPackage, sourcePath); |
128 | 143 | ||
129 | // Ensure the MSI package is appropriately marked visible or not. | 144 | // Ensure the MSI package is appropriately marked visible or not. |
130 | this.SetPackageVisibility(db, msiPropertyNames); | 145 | this.SetPackageVisibility(db, msiPackage, msiPropertyNames); |
131 | 146 | ||
132 | // Unless the MSI or setup code overrides the default, set MSIFASTINSTALL for best performance. | 147 | // Unless the MSI or setup code overrides the default, set MSIFASTINSTALL for best performance. |
133 | if (!msiPropertyNames.Contains("MSIFASTINSTALL") && !ProcessMsiPackageCommand.HasProperty(db, "MSIFASTINSTALL")) | 148 | if (!msiPropertyNames.Contains("MSIFASTINSTALL") && !ProcessMsiPackageCommand.HasProperty(db, "MSIFASTINSTALL")) |
134 | { | 149 | { |
135 | this.AddMsiProperty("MSIFASTINSTALL", "7"); | 150 | this.AddMsiProperty(msiPackage, "MSIFASTINSTALL", "7"); |
136 | } | 151 | } |
137 | 152 | ||
138 | this.CreateRelatedPackages(db); | 153 | this.CreateRelatedPackages(db); |
139 | 154 | ||
140 | // If feature selection is enabled, represent the Feature table in the manifest. | 155 | // If feature selection is enabled, represent the Feature table in the manifest. |
141 | if (this.Facade.MsiPackage.EnableFeatureSelection) | 156 | if ((msiPackage.Attributes & WixBundleMsiPackageAttributes.EnableFeatureSelection) == WixBundleMsiPackageAttributes.EnableFeatureSelection) |
142 | { | 157 | { |
143 | this.CreateMsiFeatures(db); | 158 | this.CreateMsiFeatures(db); |
144 | } | 159 | } |
@@ -148,90 +163,92 @@ namespace WixToolset.Core.Burn.Bundles | |||
148 | 163 | ||
149 | // Add all external files as package payloads and calculate the total install size as the rollup of | 164 | // Add all external files as package payloads and calculate the total install size as the rollup of |
150 | // File table's sizes. | 165 | // File table's sizes. |
151 | this.Facade.Package.InstallSize = this.ImportExternalFileAsPayloadsAndReturnInstallSize(db, packagePayload, longNamesInImage, compressed, payloadNames); | 166 | this.Facade.PackageTuple.InstallSize = this.ImportExternalFileAsPayloadsAndReturnInstallSize(db, packagePayload, longNamesInImage, compressed, payloadNames); |
152 | 167 | ||
153 | // Add all dependency providers from the MSI. | 168 | // Add all dependency providers from the MSI. |
154 | this.ImportDependencyProviders(db); | 169 | this.ImportDependencyProviders(msiPackage, db); |
155 | } | 170 | } |
156 | } | 171 | } |
157 | catch (Dtf.InstallerException e) | 172 | catch (Dtf.InstallerException e) |
158 | { | 173 | { |
159 | Messaging.Instance.OnMessage(WixErrors.UnableToReadPackageInformation(this.Facade.Package.SourceLineNumbers, sourcePath, e.Message)); | 174 | this.Messaging.Write(ErrorMessages.UnableToReadPackageInformation(this.Facade.PackageTuple.SourceLineNumbers, sourcePath, e.Message)); |
160 | } | 175 | } |
161 | } | 176 | } |
162 | 177 | ||
163 | private ISet<string> GetPayloadTargetNames() | 178 | private ISet<string> GetPayloadTargetNames(string packageId) |
164 | { | 179 | { |
165 | IEnumerable<string> payloadNames = this.PayloadTable.RowsAs<WixBundlePayloadRow>() | 180 | var payloadNames = this.Section.Tuples.OfType<WixBundlePayloadTuple>() |
166 | .Where(r => r.Package == this.Facade.Package.WixChainItemId) | 181 | .Where(p => p.PackageRef == packageId) |
167 | .Select(r => r.Name); | 182 | .Select(p => p.Name); |
168 | 183 | ||
169 | return new HashSet<string>(payloadNames, StringComparer.OrdinalIgnoreCase); | 184 | return new HashSet<string>(payloadNames, StringComparer.OrdinalIgnoreCase); |
170 | } | 185 | } |
171 | 186 | ||
172 | private ISet<string> GetMsiPropertyNames() | 187 | private ISet<string> GetMsiPropertyNames(string packageId) |
173 | { | 188 | { |
174 | IEnumerable<string> properties = this.MsiPropertyTable.RowsAs<WixBundleMsiPropertyRow>() | 189 | var properties = this.Section.Tuples.OfType<WixBundleMsiPropertyTuple>() |
175 | .Where(r => r.ChainPackageId == this.Facade.Package.WixChainItemId) | 190 | .Where(p => p.Id.Id == packageId) |
176 | .Select(r => r.Name); | 191 | .Select(p => p.Name); |
177 | 192 | ||
178 | return new HashSet<string>(properties, StringComparer.Ordinal); | 193 | return new HashSet<string>(properties, StringComparer.Ordinal); |
179 | } | 194 | } |
180 | 195 | ||
181 | private void SetPerMachineAppropriately(Dtf.Database db, string sourcePath) | 196 | private void SetPerMachineAppropriately(Dtf.Database db, WixBundleMsiPackageTuple msiPackage, string sourcePath) |
182 | { | 197 | { |
183 | if (this.Facade.MsiPackage.ForcePerMachine) | 198 | if (msiPackage.ForcePerMachine) |
184 | { | 199 | { |
185 | if (YesNoDefaultType.No == this.Facade.Package.PerMachine) | 200 | if (YesNoDefaultType.No == this.Facade.PackageTuple.PerMachine) |
186 | { | 201 | { |
187 | Messaging.Instance.OnMessage(WixWarnings.PerUserButForcingPerMachine(this.Facade.Package.SourceLineNumbers, sourcePath)); | 202 | this.Messaging.Write(WarningMessages.PerUserButForcingPerMachine(this.Facade.PackageTuple.SourceLineNumbers, sourcePath)); |
188 | this.Facade.Package.PerMachine = YesNoDefaultType.Yes; // ensure that we think the package is per-machine. | 203 | this.Facade.PackageTuple.PerMachine = YesNoDefaultType.Yes; // ensure that we think the package is per-machine. |
189 | } | 204 | } |
190 | 205 | ||
191 | // Force ALLUSERS=1 via the MSI command-line. | 206 | // Force ALLUSERS=1 via the MSI command-line. |
192 | this.AddMsiProperty("ALLUSERS", "1"); | 207 | this.AddMsiProperty(msiPackage, "ALLUSERS", "1"); |
193 | } | 208 | } |
194 | else | 209 | else |
195 | { | 210 | { |
196 | string allusers = ProcessMsiPackageCommand.GetProperty(db, "ALLUSERS"); | 211 | var allusers = ProcessMsiPackageCommand.GetProperty(db, "ALLUSERS"); |
197 | 212 | ||
198 | if (String.IsNullOrEmpty(allusers)) | 213 | if (String.IsNullOrEmpty(allusers)) |
199 | { | 214 | { |
200 | // Not forced per-machine and no ALLUSERS property, flip back to per-user. | 215 | // Not forced per-machine and no ALLUSERS property, flip back to per-user. |
201 | if (YesNoDefaultType.Yes == this.Facade.Package.PerMachine) | 216 | if (YesNoDefaultType.Yes == this.Facade.PackageTuple.PerMachine) |
202 | { | 217 | { |
203 | Messaging.Instance.OnMessage(WixWarnings.ImplicitlyPerUser(this.Facade.Package.SourceLineNumbers, sourcePath)); | 218 | this.Messaging.Write(WarningMessages.ImplicitlyPerUser(this.Facade.PackageTuple.SourceLineNumbers, sourcePath)); |
204 | this.Facade.Package.PerMachine = YesNoDefaultType.No; | 219 | this.Facade.PackageTuple.PerMachine = YesNoDefaultType.No; |
205 | } | 220 | } |
206 | } | 221 | } |
207 | else if (allusers.Equals("1", StringComparison.Ordinal)) | 222 | else if (allusers.Equals("1", StringComparison.Ordinal)) |
208 | { | 223 | { |
209 | if (YesNoDefaultType.No == this.Facade.Package.PerMachine) | 224 | if (YesNoDefaultType.No == this.Facade.PackageTuple.PerMachine) |
210 | { | 225 | { |
211 | Messaging.Instance.OnMessage(WixErrors.PerUserButAllUsersEquals1(this.Facade.Package.SourceLineNumbers, sourcePath)); | 226 | this.Messaging.Write(ErrorMessages.PerUserButAllUsersEquals1(this.Facade.PackageTuple.SourceLineNumbers, sourcePath)); |
212 | } | 227 | } |
213 | } | 228 | } |
214 | else if (allusers.Equals("2", StringComparison.Ordinal)) | 229 | else if (allusers.Equals("2", StringComparison.Ordinal)) |
215 | { | 230 | { |
216 | Messaging.Instance.OnMessage(WixWarnings.DiscouragedAllUsersValue(this.Facade.Package.SourceLineNumbers, sourcePath, (YesNoDefaultType.Yes == this.Facade.Package.PerMachine) ? "machine" : "user")); | 231 | this.Messaging.Write(WarningMessages.DiscouragedAllUsersValue(this.Facade.PackageTuple.SourceLineNumbers, sourcePath, (YesNoDefaultType.Yes == this.Facade.PackageTuple.PerMachine) ? "machine" : "user")); |
217 | } | 232 | } |
218 | else | 233 | else |
219 | { | 234 | { |
220 | Messaging.Instance.OnMessage(WixErrors.UnsupportedAllUsersValue(this.Facade.Package.SourceLineNumbers, sourcePath, allusers)); | 235 | this.Messaging.Write(ErrorMessages.UnsupportedAllUsersValue(this.Facade.PackageTuple.SourceLineNumbers, sourcePath, allusers)); |
221 | } | 236 | } |
222 | } | 237 | } |
223 | } | 238 | } |
224 | 239 | ||
225 | private void SetPackageVisibility(Dtf.Database db, ISet<string> msiPropertyNames) | 240 | private void SetPackageVisibility(Dtf.Database db, WixBundleMsiPackageTuple msiPackage, ISet<string> msiPropertyNames) |
226 | { | 241 | { |
227 | bool alreadyVisible = !ProcessMsiPackageCommand.HasProperty(db, "ARPSYSTEMCOMPONENT"); | 242 | var alreadyVisible = !ProcessMsiPackageCommand.HasProperty(db, "ARPSYSTEMCOMPONENT"); |
243 | var visible = (this.Facade.PackageTuple.Attributes & WixBundlePackageAttributes.Visible) == WixBundlePackageAttributes.Visible; | ||
228 | 244 | ||
229 | if (alreadyVisible != this.Facade.Package.Visible) // if not already set to the correct visibility. | 245 | // If not already set to the correct visibility. |
246 | if (alreadyVisible != visible) | ||
230 | { | 247 | { |
231 | // If the authoring specifically added "ARPSYSTEMCOMPONENT", don't do it again. | 248 | // If the authoring specifically added "ARPSYSTEMCOMPONENT", don't do it again. |
232 | if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT")) | 249 | if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT")) |
233 | { | 250 | { |
234 | this.AddMsiProperty("ARPSYSTEMCOMPONENT", this.Facade.Package.Visible ? String.Empty : "1"); | 251 | this.AddMsiProperty(msiPackage, "ARPSYSTEMCOMPONENT", visible ? String.Empty : "1"); |
235 | } | 252 | } |
236 | } | 253 | } |
237 | } | 254 | } |
@@ -241,30 +258,35 @@ namespace WixToolset.Core.Burn.Bundles | |||
241 | // Represent the Upgrade table as related packages. | 258 | // Represent the Upgrade table as related packages. |
242 | if (db.Tables.Contains("Upgrade")) | 259 | if (db.Tables.Contains("Upgrade")) |
243 | { | 260 | { |
244 | using (Dtf.View view = db.OpenView("SELECT `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes` FROM `Upgrade`")) | 261 | using (var view = db.OpenView("SELECT `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes` FROM `Upgrade`")) |
245 | { | 262 | { |
246 | view.Execute(); | 263 | view.Execute(); |
247 | while (true) | 264 | while (true) |
248 | { | 265 | { |
249 | using (Dtf.Record record = view.Fetch()) | 266 | using (var record = view.Fetch()) |
250 | { | 267 | { |
251 | if (null == record) | 268 | if (null == record) |
252 | { | 269 | { |
253 | break; | 270 | break; |
254 | } | 271 | } |
255 | 272 | ||
256 | WixBundleRelatedPackageRow related = (WixBundleRelatedPackageRow)this.RelatedPackageTable.CreateRow(this.Facade.Package.SourceLineNumbers); | 273 | var recordAttributes = record.GetInteger(5); |
257 | related.ChainPackageId = this.Facade.Package.WixChainItemId; | 274 | |
258 | related.Id = record.GetString(1); | 275 | var attributes = WixBundleRelatedPackageAttributes.None; |
259 | related.MinVersion = record.GetString(2); | 276 | attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect ? WixBundleRelatedPackageAttributes.OnlyDetect : 0; |
260 | related.MaxVersion = record.GetString(3); | 277 | attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive ? WixBundleRelatedPackageAttributes.MinInclusive : 0; |
261 | related.Languages = record.GetString(4); | 278 | attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive ? WixBundleRelatedPackageAttributes.MaxInclusive : 0; |
262 | 279 | attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive ? WixBundleRelatedPackageAttributes.LangInclusive : 0; | |
263 | int attributes = record.GetInteger(5); | 280 | |
264 | related.OnlyDetect = (attributes & MsiInterop.MsidbUpgradeAttributesOnlyDetect) == MsiInterop.MsidbUpgradeAttributesOnlyDetect; | 281 | var related = new WixBundleRelatedPackageTuple(this.Facade.PackageTuple.SourceLineNumbers) |
265 | related.MinInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesVersionMinInclusive) == MsiInterop.MsidbUpgradeAttributesVersionMinInclusive; | 282 | { |
266 | related.MaxInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive) == MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive; | 283 | PackageRef = this.Facade.PackageId, |
267 | related.LangInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesLanguagesExclusive) == 0; | 284 | RelatedId = record.GetString(1), |
285 | MinVersion = record.GetString(2), | ||
286 | MaxVersion = record.GetString(3), | ||
287 | Languages = record.GetString(4), | ||
288 | Attributes = attributes, | ||
289 | }; | ||
268 | } | 290 | } |
269 | } | 291 | } |
270 | } | 292 | } |
@@ -275,26 +297,26 @@ namespace WixToolset.Core.Burn.Bundles | |||
275 | { | 297 | { |
276 | if (db.Tables.Contains("Feature")) | 298 | if (db.Tables.Contains("Feature")) |
277 | { | 299 | { |
278 | using (Dtf.View featureView = db.OpenView("SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = ?")) | 300 | using (var featureView = db.OpenView("SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = ?")) |
279 | using (Dtf.View componentView = db.OpenView("SELECT `FileSize` FROM `File` WHERE `Component_` = ?")) | 301 | using (var componentView = db.OpenView("SELECT `FileSize` FROM `File` WHERE `Component_` = ?")) |
280 | { | 302 | { |
281 | using (Dtf.Record featureRecord = new Dtf.Record(1)) | 303 | using (var featureRecord = new Dtf.Record(1)) |
282 | using (Dtf.Record componentRecord = new Dtf.Record(1)) | 304 | using (var componentRecord = new Dtf.Record(1)) |
283 | { | 305 | { |
284 | using (Dtf.View allFeaturesView = db.OpenView("SELECT * FROM `Feature`")) | 306 | using (var allFeaturesView = db.OpenView("SELECT * FROM `Feature`")) |
285 | { | 307 | { |
286 | allFeaturesView.Execute(); | 308 | allFeaturesView.Execute(); |
287 | 309 | ||
288 | while (true) | 310 | while (true) |
289 | { | 311 | { |
290 | using (Dtf.Record allFeaturesResultRecord = allFeaturesView.Fetch()) | 312 | using (var allFeaturesResultRecord = allFeaturesView.Fetch()) |
291 | { | 313 | { |
292 | if (null == allFeaturesResultRecord) | 314 | if (null == allFeaturesResultRecord) |
293 | { | 315 | { |
294 | break; | 316 | break; |
295 | } | 317 | } |
296 | 318 | ||
297 | string featureName = allFeaturesResultRecord.GetString(1); | 319 | var featureName = allFeaturesResultRecord.GetString(1); |
298 | 320 | ||
299 | // Calculate the Feature size. | 321 | // Calculate the Feature size. |
300 | featureRecord.SetString(1, featureName); | 322 | featureRecord.SetString(1, featureName); |
@@ -304,43 +326,46 @@ namespace WixToolset.Core.Burn.Bundles | |||
304 | long size = 0; | 326 | long size = 0; |
305 | while (true) | 327 | while (true) |
306 | { | 328 | { |
307 | using (Dtf.Record componentResultRecord = featureView.Fetch()) | 329 | using (var componentResultRecord = featureView.Fetch()) |
308 | { | 330 | { |
309 | if (null == componentResultRecord) | 331 | if (null == componentResultRecord) |
310 | { | 332 | { |
311 | break; | 333 | break; |
312 | } | 334 | } |
313 | string component = componentResultRecord.GetString(1); | 335 | |
336 | var component = componentResultRecord.GetString(1); | ||
314 | componentRecord.SetString(1, component); | 337 | componentRecord.SetString(1, component); |
315 | componentView.Execute(componentRecord); | 338 | componentView.Execute(componentRecord); |
316 | 339 | ||
317 | while (true) | 340 | while (true) |
318 | { | 341 | { |
319 | using (Dtf.Record fileResultRecord = componentView.Fetch()) | 342 | using (var fileResultRecord = componentView.Fetch()) |
320 | { | 343 | { |
321 | if (null == fileResultRecord) | 344 | if (null == fileResultRecord) |
322 | { | 345 | { |
323 | break; | 346 | break; |
324 | } | 347 | } |
325 | 348 | ||
326 | string fileSize = fileResultRecord.GetString(1); | 349 | var fileSize = fileResultRecord.GetString(1); |
327 | size += Convert.ToInt32(fileSize, CultureInfo.InvariantCulture.NumberFormat); | 350 | size += Convert.ToInt32(fileSize, CultureInfo.InvariantCulture.NumberFormat); |
328 | } | 351 | } |
329 | } | 352 | } |
330 | } | 353 | } |
331 | } | 354 | } |
332 | 355 | ||
333 | WixBundleMsiFeatureRow feature = (WixBundleMsiFeatureRow)this.MsiFeatureTable.CreateRow(this.Facade.Package.SourceLineNumbers); | 356 | var feature = new WixBundleMsiFeatureTuple(this.Facade.PackageTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, this.Facade.PackageId, featureName)) |
334 | feature.ChainPackageId = this.Facade.Package.WixChainItemId; | 357 | { |
335 | feature.Name = featureName; | 358 | PackageRef = this.Facade.PackageId, |
336 | feature.Parent = allFeaturesResultRecord.GetString(2); | 359 | Name = featureName, |
337 | feature.Title = allFeaturesResultRecord.GetString(3); | 360 | Parent = allFeaturesResultRecord.GetString(2), |
338 | feature.Description = allFeaturesResultRecord.GetString(4); | 361 | Title = allFeaturesResultRecord.GetString(3), |
339 | feature.Display = allFeaturesResultRecord.GetInteger(5); | 362 | Description = allFeaturesResultRecord.GetString(4), |
340 | feature.Level = allFeaturesResultRecord.GetInteger(6); | 363 | Display = allFeaturesResultRecord.GetInteger(5), |
341 | feature.Directory = allFeaturesResultRecord.GetString(7); | 364 | Level = allFeaturesResultRecord.GetInteger(6), |
342 | feature.Attributes = allFeaturesResultRecord.GetInteger(8); | 365 | Directory = allFeaturesResultRecord.GetString(7), |
343 | feature.Size = size; | 366 | Attributes = allFeaturesResultRecord.GetInteger(8), |
367 | Size = size | ||
368 | }; | ||
344 | } | 369 | } |
345 | } | 370 | } |
346 | } | 371 | } |
@@ -349,113 +374,119 @@ namespace WixToolset.Core.Burn.Bundles | |||
349 | } | 374 | } |
350 | } | 375 | } |
351 | 376 | ||
352 | private void ImportExternalCabinetAsPayloads(Dtf.Database db, WixBundlePayloadRow packagePayload, ISet<string> payloadNames) | 377 | private void ImportExternalCabinetAsPayloads(Dtf.Database db, WixBundlePayloadTuple packagePayload, ISet<string> payloadNames) |
353 | { | 378 | { |
354 | if (db.Tables.Contains("Media")) | 379 | if (db.Tables.Contains("Media")) |
355 | { | 380 | { |
356 | foreach (string cabinet in db.ExecuteStringQuery("SELECT `Cabinet` FROM `Media`")) | 381 | foreach (var cabinet in db.ExecuteStringQuery("SELECT `Cabinet` FROM `Media`")) |
357 | { | 382 | { |
358 | if (!String.IsNullOrEmpty(cabinet) && !cabinet.StartsWith("#", StringComparison.Ordinal)) | 383 | if (!String.IsNullOrEmpty(cabinet) && !cabinet.StartsWith("#", StringComparison.Ordinal)) |
359 | { | 384 | { |
360 | // If we didn't find the Payload as an existing child of the package, we need to | 385 | // If we didn't find the Payload as an existing child of the package, we need to |
361 | // add it. We expect the file to exist on-disk in the same relative location as | 386 | // add it. We expect the file to exist on-disk in the same relative location as |
362 | // the MSI expects to find it... | 387 | // the MSI expects to find it... |
363 | string cabinetName = Path.Combine(Path.GetDirectoryName(packagePayload.Name), cabinet); | 388 | var cabinetName = Path.Combine(Path.GetDirectoryName(packagePayload.Name), cabinet); |
364 | 389 | ||
365 | if (!payloadNames.Contains(cabinetName)) | 390 | if (!payloadNames.Contains(cabinetName)) |
366 | { | 391 | { |
367 | string generatedId = Common.GenerateIdentifier("cab", packagePayload.Id, cabinet); | 392 | var generatedId = Common.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet); |
368 | string payloadSourceFile = this.ResolveRelatedFile(packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.Package.SourceLineNumbers, BindStage.Normal); | 393 | var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.PackageTuple.SourceLineNumbers, BindStage.Normal); |
369 | 394 | ||
370 | WixBundlePayloadRow payload = (WixBundlePayloadRow)this.PayloadTable.CreateRow(this.Facade.Package.SourceLineNumbers); | 395 | var tuple = new WixBundlePayloadTuple(this.Facade.PackageTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, generatedId)) |
371 | payload.Id = generatedId; | 396 | { |
372 | payload.Name = cabinetName; | 397 | Name = cabinetName, |
373 | payload.SourceFile = payloadSourceFile; | 398 | SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile }, |
374 | payload.Compressed = packagePayload.Compressed; | 399 | Compressed = packagePayload.Compressed, |
375 | payload.UnresolvedSourceFile = cabinetName; | 400 | UnresolvedSourceFile = cabinetName, |
376 | payload.Package = packagePayload.Package; | 401 | PackageRef = packagePayload.PackageRef, |
377 | payload.Container = packagePayload.Container; | 402 | ContainerRef = packagePayload.ContainerRef, |
378 | payload.ContentFile = true; | 403 | ContentFile = true, |
379 | payload.EnableSignatureValidation = packagePayload.EnableSignatureValidation; | 404 | EnableSignatureValidation = packagePayload.EnableSignatureValidation, |
380 | payload.Packaging = packagePayload.Packaging; | 405 | Packaging = packagePayload.Packaging, |
381 | payload.ParentPackagePayload = packagePayload.Id; | 406 | ParentPackagePayloadRef = packagePayload.Id.Id, |
407 | }; | ||
408 | |||
409 | this.Section.Tuples.Add(tuple); | ||
382 | } | 410 | } |
383 | } | 411 | } |
384 | } | 412 | } |
385 | } | 413 | } |
386 | } | 414 | } |
387 | 415 | ||
388 | private long ImportExternalFileAsPayloadsAndReturnInstallSize(Dtf.Database db, WixBundlePayloadRow packagePayload, bool longNamesInImage, bool compressed, ISet<string> payloadNames) | 416 | private long ImportExternalFileAsPayloadsAndReturnInstallSize(Dtf.Database db, WixBundlePayloadTuple packagePayload, bool longNamesInImage, bool compressed, ISet<string> payloadNames) |
389 | { | 417 | { |
390 | long size = 0; | 418 | long size = 0; |
391 | 419 | ||
392 | if (db.Tables.Contains("Component") && db.Tables.Contains("Directory") && db.Tables.Contains("File")) | 420 | if (db.Tables.Contains("Component") && db.Tables.Contains("Directory") && db.Tables.Contains("File")) |
393 | { | 421 | { |
394 | Hashtable directories = new Hashtable(); | 422 | var directories = new Dictionary<string, IResolvedDirectory>(); |
395 | 423 | ||
396 | // Load up the directory hash table so we will be able to resolve source paths | 424 | // Load up the directory hash table so we will be able to resolve source paths |
397 | // for files in the MSI database. | 425 | // for files in the MSI database. |
398 | using (Dtf.View view = db.OpenView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`")) | 426 | using (var view = db.OpenView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`")) |
399 | { | 427 | { |
400 | view.Execute(); | 428 | view.Execute(); |
401 | while (true) | 429 | while (true) |
402 | { | 430 | { |
403 | using (Dtf.Record record = view.Fetch()) | 431 | using (var record = view.Fetch()) |
404 | { | 432 | { |
405 | if (null == record) | 433 | if (null == record) |
406 | { | 434 | { |
407 | break; | 435 | break; |
408 | } | 436 | } |
409 | 437 | ||
410 | string sourceName = Common.GetName(record.GetString(3), true, longNamesInImage); | 438 | var sourceName = Common.GetName(record.GetString(3), true, longNamesInImage); |
411 | directories.Add(record.GetString(1), new ResolvedDirectory(record.GetString(2), sourceName)); | 439 | |
440 | var resolvedDirectory = this.BackendHelper.CreateResolvedDirectory(record.GetString(2), sourceName); | ||
441 | |||
442 | directories.Add(record.GetString(1), resolvedDirectory); | ||
412 | } | 443 | } |
413 | } | 444 | } |
414 | } | 445 | } |
415 | 446 | ||
416 | // Resolve the source paths to external files and add each file size to the total | 447 | // Resolve the source paths to external files and add each file size to the total |
417 | // install size of the package. | 448 | // install size of the package. |
418 | using (Dtf.View view = db.OpenView("SELECT `Directory_`, `File`, `FileName`, `File`.`Attributes`, `FileSize` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_`")) | 449 | using (var view = db.OpenView("SELECT `Directory_`, `File`, `FileName`, `File`.`Attributes`, `FileSize` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_`")) |
419 | { | 450 | { |
420 | view.Execute(); | 451 | view.Execute(); |
421 | while (true) | 452 | while (true) |
422 | { | 453 | { |
423 | using (Dtf.Record record = view.Fetch()) | 454 | using (var record = view.Fetch()) |
424 | { | 455 | { |
425 | if (null == record) | 456 | if (null == record) |
426 | { | 457 | { |
427 | break; | 458 | break; |
428 | } | 459 | } |
429 | 460 | ||
430 | // Skip adding the loose files as payloads if it was suppressed. | 461 | // If the file is explicitly uncompressed or the MSI is uncompressed and the file is not |
431 | if (!this.Facade.MsiPackage.SuppressLooseFilePayloadGeneration) | 462 | // explicitly marked compressed then this is an external file. |
463 | var compressionBit = record.GetInteger(4); | ||
464 | if (WindowsInstallerConstants.MsidbFileAttributesNoncompressed == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) || | ||
465 | (!compressed && 0 == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesCompressed))) | ||
432 | { | 466 | { |
433 | // If the file is explicitly uncompressed or the MSI is uncompressed and the file is not | 467 | string fileSourcePath = this.PathResolver.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage); |
434 | // explicitly marked compressed then this is an external file. | 468 | var name = Path.Combine(Path.GetDirectoryName(packagePayload.Name), fileSourcePath); |
435 | if (MsiInterop.MsidbFileAttributesNoncompressed == (record.GetInteger(4) & MsiInterop.MsidbFileAttributesNoncompressed) || | 469 | |
436 | (!compressed && 0 == (record.GetInteger(4) & MsiInterop.MsidbFileAttributesCompressed))) | 470 | if (!payloadNames.Contains(name)) |
437 | { | 471 | { |
438 | string fileSourcePath = Binder.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage); | 472 | var generatedId = Common.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2)); |
439 | string name = Path.Combine(Path.GetDirectoryName(packagePayload.Name), fileSourcePath); | 473 | var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.PackageTuple.SourceLineNumbers, BindStage.Normal); |
440 | 474 | ||
441 | if (!payloadNames.Contains(name)) | 475 | var tuple = new WixBundlePayloadTuple(this.Facade.PackageTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, generatedId)) |
442 | { | 476 | { |
443 | string generatedId = Common.GenerateIdentifier("f", packagePayload.Id, record.GetString(2)); | 477 | Name = name, |
444 | string payloadSourceFile = this.ResolveRelatedFile(packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.Package.SourceLineNumbers, BindStage.Normal); | 478 | SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile }, |
445 | 479 | Compressed = packagePayload.Compressed, | |
446 | WixBundlePayloadRow payload = (WixBundlePayloadRow)this.PayloadTable.CreateRow(this.Facade.Package.SourceLineNumbers); | 480 | UnresolvedSourceFile = name, |
447 | payload.Id = generatedId; | 481 | PackageRef = packagePayload.PackageRef, |
448 | payload.Name = name; | 482 | ContainerRef = packagePayload.ContainerRef, |
449 | payload.SourceFile = payloadSourceFile; | 483 | ContentFile = true, |
450 | payload.Compressed = packagePayload.Compressed; | 484 | EnableSignatureValidation = packagePayload.EnableSignatureValidation, |
451 | payload.UnresolvedSourceFile = name; | 485 | Packaging = packagePayload.Packaging, |
452 | payload.Package = packagePayload.Package; | 486 | ParentPackagePayloadRef = packagePayload.Id.Id, |
453 | payload.Container = packagePayload.Container; | 487 | }; |
454 | payload.ContentFile = true; | 488 | |
455 | payload.EnableSignatureValidation = packagePayload.EnableSignatureValidation; | 489 | this.Section.Tuples.Add(tuple); |
456 | payload.Packaging = packagePayload.Packaging; | ||
457 | payload.ParentPackagePayload = packagePayload.Id; | ||
458 | } | ||
459 | } | 490 | } |
460 | } | 491 | } |
461 | 492 | ||
@@ -468,26 +499,30 @@ namespace WixToolset.Core.Burn.Bundles | |||
468 | return size; | 499 | return size; |
469 | } | 500 | } |
470 | 501 | ||
471 | private void AddMsiProperty(string name, string value) | 502 | private void AddMsiProperty(WixBundleMsiPackageTuple msiPackage, string name, string value) |
472 | { | 503 | { |
473 | WixBundleMsiPropertyRow row = (WixBundleMsiPropertyRow)this.MsiPropertyTable.CreateRow(this.Facade.MsiPackage.SourceLineNumbers); | 504 | var tuple = new WixBundleMsiPropertyTuple(msiPackage.SourceLineNumbers, new Identifier(AccessModifier.Private, msiPackage.Id.Id, name)) |
474 | row.ChainPackageId = this.Facade.Package.WixChainItemId; | 505 | { |
475 | row.Name = name; | 506 | PackageRef = msiPackage.Id.Id, |
476 | row.Value = value; | 507 | Name = name, |
508 | Value = value | ||
509 | }; | ||
510 | |||
511 | this.Section.Tuples.Add(tuple); | ||
477 | } | 512 | } |
478 | 513 | ||
479 | private void ImportDependencyProviders(Dtf.Database db) | 514 | private void ImportDependencyProviders(WixBundleMsiPackageTuple msiPackage, Dtf.Database db) |
480 | { | 515 | { |
481 | if (db.Tables.Contains("WixDependencyProvider")) | 516 | if (db.Tables.Contains("WixDependencyProvider")) |
482 | { | 517 | { |
483 | string query = "SELECT `ProviderKey`, `Version`, `DisplayName`, `Attributes` FROM `WixDependencyProvider`"; | 518 | var query = "SELECT `ProviderKey`, `Version`, `DisplayName`, `Attributes` FROM `WixDependencyProvider`"; |
484 | 519 | ||
485 | using (Dtf.View view = db.OpenView(query)) | 520 | using (var view = db.OpenView(query)) |
486 | { | 521 | { |
487 | view.Execute(); | 522 | view.Execute(); |
488 | while (true) | 523 | while (true) |
489 | { | 524 | { |
490 | using (Dtf.Record record = view.Fetch()) | 525 | using (var record = view.Fetch()) |
491 | { | 526 | { |
492 | if (null == record) | 527 | if (null == record) |
493 | { | 528 | { |
@@ -495,34 +530,51 @@ namespace WixToolset.Core.Burn.Bundles | |||
495 | } | 530 | } |
496 | 531 | ||
497 | // Import the provider key and attributes. | 532 | // Import the provider key and attributes. |
498 | string providerKey = record.GetString(1); | 533 | var tuple = new ProvidesDependencyTuple(msiPackage.SourceLineNumbers) |
499 | string version = record.GetString(2) ?? this.Facade.MsiPackage.ProductVersion; | 534 | { |
500 | string displayName = record.GetString(3) ?? this.Facade.Package.DisplayName; | 535 | PackageRef = msiPackage.Id.Id, |
501 | int attributes = record.GetInteger(4); | 536 | Key = record.GetString(1), |
502 | 537 | Version = record.GetString(2) ?? msiPackage.ProductVersion, | |
503 | ProvidesDependency dependency = new ProvidesDependency(providerKey, version, displayName, attributes); | 538 | DisplayName = record.GetString(3) ?? this.Facade.PackageTuple.DisplayName, |
504 | dependency.Imported = true; | 539 | Attributes = record.GetInteger(4), |
505 | 540 | Imported = true | |
506 | this.Facade.Provides.Add(dependency); | 541 | }; |
542 | |||
543 | this.Section.Tuples.Add(tuple); | ||
507 | } | 544 | } |
508 | } | 545 | } |
509 | } | 546 | } |
510 | } | 547 | } |
511 | } | 548 | } |
512 | 549 | ||
513 | private string ResolveRelatedFile(string sourceFile, string relatedSource, string type, SourceLineNumber sourceLineNumbers, BindStage stage) | 550 | private string ResolveRelatedFile(string resolvedSource, string unresolvedSource, string relatedSource, string type, SourceLineNumber sourceLineNumbers, BindStage stage) |
514 | { | 551 | { |
552 | var checkedPaths = new List<string>(); | ||
553 | |||
515 | foreach (var extension in this.BackendExtensions) | 554 | foreach (var extension in this.BackendExtensions) |
516 | { | 555 | { |
517 | var relatedFile = extension.ResolveRelatedFile(sourceFile, relatedSource, type, sourceLineNumbers, stage); | 556 | var resolved = extension.ResolveRelatedFile(unresolvedSource, relatedSource, type, sourceLineNumbers, stage); |
518 | 557 | ||
519 | if (!String.IsNullOrEmpty(relatedFile)) | 558 | if (resolved?.CheckedPaths != null) |
520 | { | 559 | { |
521 | return relatedFile; | 560 | checkedPaths.AddRange(resolved.CheckedPaths); |
561 | } | ||
562 | |||
563 | if (!String.IsNullOrEmpty(resolved?.Path)) | ||
564 | { | ||
565 | return resolved?.Path; | ||
522 | } | 566 | } |
523 | } | 567 | } |
524 | 568 | ||
525 | return null; | 569 | var resolvedPath = Path.Combine(Path.GetDirectoryName(resolvedSource), relatedSource); |
570 | |||
571 | if (!File.Exists(resolvedPath)) | ||
572 | { | ||
573 | checkedPaths.Add(resolvedPath); | ||
574 | this.Messaging.Write(ErrorMessages.FileNotFound(sourceLineNumbers, resolvedPath, type, checkedPaths)); | ||
575 | } | ||
576 | |||
577 | return resolvedPath; | ||
526 | } | 578 | } |
527 | 579 | ||
528 | /// <summary> | 580 | /// <summary> |
@@ -571,6 +623,5 @@ namespace WixToolset.Core.Burn.Bundles | |||
571 | 623 | ||
572 | return String.Format(CultureInfo.InvariantCulture, ProcessMsiPackageCommand.PropertySqlFormat, property); | 624 | return String.Format(CultureInfo.InvariantCulture, ProcessMsiPackageCommand.PropertySqlFormat, property); |
573 | } | 625 | } |
574 | #endif | ||
575 | } | 626 | } |
576 | } | 627 | } |