diff options
author | Rob Mensching <rob@firegiant.com> | 2017-10-14 16:12:07 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-10-14 16:12:07 -0700 |
commit | dbde9e7104b907bbbaea17e21247d8cafc8b3a4c (patch) | |
tree | 0f5fbbb6fe12c6b2e5e622a0e18ce4c5b4eb2b96 /src/WixToolset.Core/Bind/Databases/CreateCabinetsCommand.cs | |
parent | fbf986eb97f68396797a89fc7d40dec07b775440 (diff) | |
download | wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.tar.gz wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.tar.bz2 wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.zip |
Massive refactoring to introduce the concept of IBackend
Diffstat (limited to 'src/WixToolset.Core/Bind/Databases/CreateCabinetsCommand.cs')
-rw-r--r-- | src/WixToolset.Core/Bind/Databases/CreateCabinetsCommand.cs | 489 |
1 files changed, 0 insertions, 489 deletions
diff --git a/src/WixToolset.Core/Bind/Databases/CreateCabinetsCommand.cs b/src/WixToolset.Core/Bind/Databases/CreateCabinetsCommand.cs deleted file mode 100644 index 35c8abb4..00000000 --- a/src/WixToolset.Core/Bind/Databases/CreateCabinetsCommand.cs +++ /dev/null | |||
@@ -1,489 +0,0 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Bind.Databases | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Globalization; | ||
8 | using System.IO; | ||
9 | using System.Linq; | ||
10 | using System.Runtime.InteropServices; | ||
11 | using System.Threading; | ||
12 | using WixToolset.Data; | ||
13 | using WixToolset.Data.Rows; | ||
14 | using WixToolset.Extensibility; | ||
15 | |||
16 | /// <summary> | ||
17 | /// Creates cabinet files. | ||
18 | /// </summary> | ||
19 | internal class CreateCabinetsCommand : ICommand | ||
20 | { | ||
21 | private List<FileTransfer> fileTransfers; | ||
22 | |||
23 | private FileSplitCabNamesCallback newCabNamesCallBack; | ||
24 | |||
25 | private Dictionary<string, string> lastCabinetAddedToMediaTable; // Key is First Cabinet Name, Value is Last Cabinet Added in the Split Sequence | ||
26 | |||
27 | public CreateCabinetsCommand() | ||
28 | { | ||
29 | this.fileTransfers = new List<FileTransfer>(); | ||
30 | |||
31 | this.newCabNamesCallBack = NewCabNamesCallBack; | ||
32 | } | ||
33 | |||
34 | /// <summary> | ||
35 | /// Sets the number of threads to use for cabinet creation. | ||
36 | /// </summary> | ||
37 | public int CabbingThreadCount { private get; set; } | ||
38 | |||
39 | public string TempFilesLocation { private get; set; } | ||
40 | |||
41 | /// <summary> | ||
42 | /// Sets the default compression level to use for cabinets | ||
43 | /// that don't have their compression level explicitly set. | ||
44 | /// </summary> | ||
45 | public CompressionLevel DefaultCompressionLevel { private get; set; } | ||
46 | |||
47 | public Output Output { private get; set; } | ||
48 | |||
49 | public IEnumerable<IBinderFileManager> FileManagers { private get; set; } | ||
50 | |||
51 | public string LayoutDirectory { private get; set; } | ||
52 | |||
53 | public bool Compressed { private get; set; } | ||
54 | |||
55 | public Dictionary<MediaRow, IEnumerable<FileFacade>> FileRowsByCabinet { private get; set; } | ||
56 | |||
57 | public Func<MediaRow, string, string, string> ResolveMedia { private get; set; } | ||
58 | |||
59 | public TableDefinitionCollection TableDefinitions { private get; set; } | ||
60 | |||
61 | public Table WixMediaTable { private get; set; } | ||
62 | |||
63 | public IEnumerable<FileTransfer> FileTransfers { get { return this.fileTransfers; } } | ||
64 | |||
65 | /// <param name="output">Output to generate image for.</param> | ||
66 | /// <param name="fileTransfers">Array of files to be transfered.</param> | ||
67 | /// <param name="layoutDirectory">The directory in which the image should be layed out.</param> | ||
68 | /// <param name="compressed">Flag if source image should be compressed.</param> | ||
69 | /// <returns>The uncompressed file rows.</returns> | ||
70 | public void Execute() | ||
71 | { | ||
72 | RowDictionary<WixMediaRow> wixMediaRows = new RowDictionary<WixMediaRow>(this.WixMediaTable); | ||
73 | |||
74 | this.lastCabinetAddedToMediaTable = new Dictionary<string, string>(); | ||
75 | |||
76 | this.SetCabbingThreadCount(); | ||
77 | |||
78 | // Send Binder object to Facilitate NewCabNamesCallBack Callback | ||
79 | CabinetBuilder cabinetBuilder = new CabinetBuilder(this.CabbingThreadCount, Marshal.GetFunctionPointerForDelegate(this.newCabNamesCallBack)); | ||
80 | |||
81 | // Supply Compile MediaTemplate Attributes to Cabinet Builder | ||
82 | int MaximumCabinetSizeForLargeFileSplitting; | ||
83 | int MaximumUncompressedMediaSize; | ||
84 | this.GetMediaTemplateAttributes(out MaximumCabinetSizeForLargeFileSplitting, out MaximumUncompressedMediaSize); | ||
85 | cabinetBuilder.MaximumCabinetSizeForLargeFileSplitting = MaximumCabinetSizeForLargeFileSplitting; | ||
86 | cabinetBuilder.MaximumUncompressedMediaSize = MaximumUncompressedMediaSize; | ||
87 | |||
88 | foreach (var entry in this.FileRowsByCabinet) | ||
89 | { | ||
90 | MediaRow mediaRow = entry.Key; | ||
91 | IEnumerable<FileFacade> files = entry.Value; | ||
92 | CompressionLevel compressionLevel = this.DefaultCompressionLevel; | ||
93 | |||
94 | WixMediaRow wixMediaRow = null; | ||
95 | string mediaLayoutFolder = null; | ||
96 | |||
97 | if (wixMediaRows.TryGetValue(mediaRow.GetKey(), out wixMediaRow)) | ||
98 | { | ||
99 | mediaLayoutFolder = wixMediaRow.Layout; | ||
100 | |||
101 | if (wixMediaRow.CompressionLevel.HasValue) | ||
102 | { | ||
103 | compressionLevel = wixMediaRow.CompressionLevel.Value; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | string cabinetDir = this.ResolveMedia(mediaRow, mediaLayoutFolder, this.LayoutDirectory); | ||
108 | |||
109 | CabinetWorkItem cabinetWorkItem = this.CreateCabinetWorkItem(this.Output, cabinetDir, mediaRow, compressionLevel, files, this.fileTransfers); | ||
110 | if (null != cabinetWorkItem) | ||
111 | { | ||
112 | cabinetBuilder.Enqueue(cabinetWorkItem); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | // stop processing if an error previously occurred | ||
117 | if (Messaging.Instance.EncounteredError) | ||
118 | { | ||
119 | return; | ||
120 | } | ||
121 | |||
122 | // create queued cabinets with multiple threads | ||
123 | cabinetBuilder.CreateQueuedCabinets(); | ||
124 | if (Messaging.Instance.EncounteredError) | ||
125 | { | ||
126 | return; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | /// <summary> | ||
131 | /// Sets the thead count to the number of processors if the current thread count is set to 0. | ||
132 | /// </summary> | ||
133 | /// <remarks>The thread count value must be greater than 0 otherwise and exception will be thrown.</remarks> | ||
134 | private void SetCabbingThreadCount() | ||
135 | { | ||
136 | // default the number of cabbing threads to the number of processors if it wasn't specified | ||
137 | if (0 == this.CabbingThreadCount) | ||
138 | { | ||
139 | string numberOfProcessors = System.Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS"); | ||
140 | |||
141 | try | ||
142 | { | ||
143 | if (null != numberOfProcessors) | ||
144 | { | ||
145 | this.CabbingThreadCount = Convert.ToInt32(numberOfProcessors, CultureInfo.InvariantCulture.NumberFormat); | ||
146 | |||
147 | if (0 >= this.CabbingThreadCount) | ||
148 | { | ||
149 | throw new WixException(WixErrors.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors)); | ||
150 | } | ||
151 | } | ||
152 | else // default to 1 if the environment variable is not set | ||
153 | { | ||
154 | this.CabbingThreadCount = 1; | ||
155 | } | ||
156 | |||
157 | Messaging.Instance.OnMessage(WixVerboses.SetCabbingThreadCount(this.CabbingThreadCount.ToString())); | ||
158 | } | ||
159 | catch (ArgumentException) | ||
160 | { | ||
161 | throw new WixException(WixErrors.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors)); | ||
162 | } | ||
163 | catch (FormatException) | ||
164 | { | ||
165 | throw new WixException(WixErrors.IllegalEnvironmentVariable("NUMBER_OF_PROCESSORS", numberOfProcessors)); | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | |||
171 | /// <summary> | ||
172 | /// Creates a work item to create a cabinet. | ||
173 | /// </summary> | ||
174 | /// <param name="output">Output for the current database.</param> | ||
175 | /// <param name="cabinetDir">Directory to create cabinet in.</param> | ||
176 | /// <param name="mediaRow">MediaRow containing information about the cabinet.</param> | ||
177 | /// <param name="fileFacades">Collection of files in this cabinet.</param> | ||
178 | /// <param name="fileTransfers">Array of files to be transfered.</param> | ||
179 | /// <returns>created CabinetWorkItem object</returns> | ||
180 | private CabinetWorkItem CreateCabinetWorkItem(Output output, string cabinetDir, MediaRow mediaRow, CompressionLevel compressionLevel, IEnumerable<FileFacade> fileFacades, List<FileTransfer> fileTransfers) | ||
181 | { | ||
182 | CabinetWorkItem cabinetWorkItem = null; | ||
183 | string tempCabinetFileX = Path.Combine(this.TempFilesLocation, mediaRow.Cabinet); | ||
184 | |||
185 | // check for an empty cabinet | ||
186 | if (!fileFacades.Any()) | ||
187 | { | ||
188 | string cabinetName = mediaRow.Cabinet; | ||
189 | |||
190 | // remove the leading '#' from the embedded cabinet name to make the warning easier to understand | ||
191 | if (cabinetName.StartsWith("#", StringComparison.Ordinal)) | ||
192 | { | ||
193 | cabinetName = cabinetName.Substring(1); | ||
194 | } | ||
195 | |||
196 | // If building a patch, remind them to run -p for torch. | ||
197 | if (OutputType.Patch == output.Type) | ||
198 | { | ||
199 | Messaging.Instance.OnMessage(WixWarnings.EmptyCabinet(mediaRow.SourceLineNumbers, cabinetName, true)); | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | Messaging.Instance.OnMessage(WixWarnings.EmptyCabinet(mediaRow.SourceLineNumbers, cabinetName)); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | ResolvedCabinet resolvedCabinet = this.ResolveCabinet(tempCabinetFileX, fileFacades); | ||
208 | |||
209 | // create a cabinet work item if it's not being skipped | ||
210 | if (CabinetBuildOption.BuildAndCopy == resolvedCabinet.BuildOption || CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption) | ||
211 | { | ||
212 | int maxThreshold = 0; // default to the threshold for best smartcabbing (makes smallest cabinet). | ||
213 | |||
214 | cabinetWorkItem = new CabinetWorkItem(fileFacades, resolvedCabinet.Path, maxThreshold, compressionLevel/*, this.FileManager*/); | ||
215 | } | ||
216 | else // reuse the cabinet from the cabinet cache. | ||
217 | { | ||
218 | Messaging.Instance.OnMessage(WixVerboses.ReusingCabCache(mediaRow.SourceLineNumbers, mediaRow.Cabinet, resolvedCabinet.Path)); | ||
219 | |||
220 | try | ||
221 | { | ||
222 | // Ensure the cached cabinet timestamp is current to prevent perpetual incremental builds. The | ||
223 | // problematic scenario goes like this. Imagine two cabinets in the cache. Update a file that | ||
224 | // goes into one of the cabinets. One cabinet will get rebuilt, the other will be copied from | ||
225 | // the cache. Now the file (an input) has a newer timestamp than the reused cabient (an output) | ||
226 | // causing the project to look like it perpetually needs a rebuild until all of the reused | ||
227 | // cabinets get newer timestamps. | ||
228 | File.SetLastWriteTime(resolvedCabinet.Path, DateTime.Now); | ||
229 | } | ||
230 | catch (Exception e) | ||
231 | { | ||
232 | Messaging.Instance.OnMessage(WixWarnings.CannotUpdateCabCache(mediaRow.SourceLineNumbers, resolvedCabinet.Path, e.Message)); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if (mediaRow.Cabinet.StartsWith("#", StringComparison.Ordinal)) | ||
237 | { | ||
238 | Table streamsTable = output.EnsureTable(this.TableDefinitions["_Streams"]); | ||
239 | |||
240 | Row streamRow = streamsTable.CreateRow(mediaRow.SourceLineNumbers); | ||
241 | streamRow[0] = mediaRow.Cabinet.Substring(1); | ||
242 | streamRow[1] = resolvedCabinet.Path; | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | string destinationPath = Path.Combine(cabinetDir, mediaRow.Cabinet); | ||
247 | FileTransfer transfer; | ||
248 | if (FileTransfer.TryCreate(resolvedCabinet.Path, destinationPath, CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption, "Cabinet", mediaRow.SourceLineNumbers, out transfer)) | ||
249 | { | ||
250 | transfer.Built = true; | ||
251 | fileTransfers.Add(transfer); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | return cabinetWorkItem; | ||
256 | } | ||
257 | |||
258 | private ResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable<FileFacade> fileFacades) | ||
259 | { | ||
260 | ResolvedCabinet resolved = null; | ||
261 | |||
262 | List<BindFileWithPath> filesWithPath = fileFacades.Select(f => new BindFileWithPath() { Id = f.File.File, Path = f.WixFile.Source }).ToList(); | ||
263 | |||
264 | foreach (IBinderFileManager fileManager in this.FileManagers) | ||
265 | { | ||
266 | resolved = fileManager.ResolveCabinet(cabinetPath, filesWithPath); | ||
267 | if (null != resolved) | ||
268 | { | ||
269 | break; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | return resolved; | ||
274 | } | ||
275 | |||
276 | /// <summary> | ||
277 | /// Delegate for Cabinet Split Callback | ||
278 | /// </summary> | ||
279 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] | ||
280 | internal delegate void FileSplitCabNamesCallback([MarshalAs(UnmanagedType.LPWStr)]string firstCabName, [MarshalAs(UnmanagedType.LPWStr)]string newCabName, [MarshalAs(UnmanagedType.LPWStr)]string fileToken); | ||
281 | |||
282 | /// <summary> | ||
283 | /// Call back to Add File Transfer for new Cab and add new Cab to Media table | ||
284 | /// This callback can come from Multiple Cabinet Builder Threads and so should be thread safe | ||
285 | /// This callback will not be called in case there is no File splitting. i.e. MaximumCabinetSizeForLargeFileSplitting was not authored | ||
286 | /// </summary> | ||
287 | /// <param name="firstCabName">The name of splitting cabinet without extention e.g. "cab1".</param> | ||
288 | /// <param name="newCabName">The name of the new cabinet that would be formed by splitting e.g. "cab1b.cab"</param> | ||
289 | /// <param name="fileToken">The file token of the first file present in the splitting cabinet</param> | ||
290 | internal void NewCabNamesCallBack([MarshalAs(UnmanagedType.LPWStr)]string firstCabName, [MarshalAs(UnmanagedType.LPWStr)]string newCabName, [MarshalAs(UnmanagedType.LPWStr)]string fileToken) | ||
291 | { | ||
292 | // Locking Mutex here as this callback can come from Multiple Cabinet Builder Threads | ||
293 | Mutex mutex = new Mutex(false, "WixCabinetSplitBinderCallback"); | ||
294 | try | ||
295 | { | ||
296 | if (!mutex.WaitOne(0, false)) // Check if you can get the lock | ||
297 | { | ||
298 | // Cound not get the Lock | ||
299 | Messaging.Instance.OnMessage(WixVerboses.CabinetsSplitInParallel()); | ||
300 | mutex.WaitOne(); // Wait on other thread | ||
301 | } | ||
302 | |||
303 | string firstCabinetName = firstCabName + ".cab"; | ||
304 | string newCabinetName = newCabName; | ||
305 | bool transferAdded = false; // Used for Error Handling | ||
306 | |||
307 | // Create File Transfer for new Cabinet using transfer of Base Cabinet | ||
308 | foreach (FileTransfer transfer in this.FileTransfers) | ||
309 | { | ||
310 | if (firstCabinetName.Equals(Path.GetFileName(transfer.Source), StringComparison.InvariantCultureIgnoreCase)) | ||
311 | { | ||
312 | string newCabSourcePath = Path.Combine(Path.GetDirectoryName(transfer.Source), newCabinetName); | ||
313 | string newCabTargetPath = Path.Combine(Path.GetDirectoryName(transfer.Destination), newCabinetName); | ||
314 | |||
315 | FileTransfer newTransfer; | ||
316 | if (FileTransfer.TryCreate(newCabSourcePath, newCabTargetPath, transfer.Move, "Cabinet", transfer.SourceLineNumbers, out newTransfer)) | ||
317 | { | ||
318 | newTransfer.Built = true; | ||
319 | this.fileTransfers.Add(newTransfer); | ||
320 | transferAdded = true; | ||
321 | break; | ||
322 | } | ||
323 | } | ||
324 | } | ||
325 | |||
326 | // Check if File Transfer was added | ||
327 | if (!transferAdded) | ||
328 | { | ||
329 | throw new WixException(WixErrors.SplitCabinetCopyRegistrationFailed(newCabinetName, firstCabinetName)); | ||
330 | } | ||
331 | |||
332 | // Add the new Cabinets to media table using LastSequence of Base Cabinet | ||
333 | Table mediaTable = this.Output.Tables["Media"]; | ||
334 | Table wixFileTable = this.Output.Tables["WixFile"]; | ||
335 | int diskIDForLastSplitCabAdded = 0; // The DiskID value for the first cab in this cabinet split chain | ||
336 | int lastSequenceForLastSplitCabAdded = 0; // The LastSequence value for the first cab in this cabinet split chain | ||
337 | bool lastSplitCabinetFound = false; // Used for Error Handling | ||
338 | |||
339 | string lastCabinetOfThisSequence = String.Empty; | ||
340 | // Get the Value of Last Cabinet Added in this split Sequence from Dictionary | ||
341 | if (!this.lastCabinetAddedToMediaTable.TryGetValue(firstCabinetName, out lastCabinetOfThisSequence)) | ||
342 | { | ||
343 | // If there is no value for this sequence, then use first Cabinet is the last one of this split sequence | ||
344 | lastCabinetOfThisSequence = firstCabinetName; | ||
345 | } | ||
346 | |||
347 | foreach (MediaRow mediaRow in mediaTable.Rows) | ||
348 | { | ||
349 | // Get details for the Last Cabinet Added in this Split Sequence | ||
350 | if ((lastSequenceForLastSplitCabAdded == 0) && lastCabinetOfThisSequence.Equals(mediaRow.Cabinet, StringComparison.InvariantCultureIgnoreCase)) | ||
351 | { | ||
352 | lastSequenceForLastSplitCabAdded = mediaRow.LastSequence; | ||
353 | diskIDForLastSplitCabAdded = mediaRow.DiskId; | ||
354 | lastSplitCabinetFound = true; | ||
355 | } | ||
356 | |||
357 | // Check for Name Collision for the new Cabinet added | ||
358 | if (newCabinetName.Equals(mediaRow.Cabinet, StringComparison.InvariantCultureIgnoreCase)) | ||
359 | { | ||
360 | // Name Collision of generated Split Cabinet Name and user Specified Cab name for current row | ||
361 | throw new WixException(WixErrors.SplitCabinetNameCollision(newCabinetName, firstCabinetName)); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | // Check if the last Split Cabinet was found in the Media Table | ||
366 | if (!lastSplitCabinetFound) | ||
367 | { | ||
368 | throw new WixException(WixErrors.SplitCabinetInsertionFailed(newCabinetName, firstCabinetName, lastCabinetOfThisSequence)); | ||
369 | } | ||
370 | |||
371 | // The new Row has to be inserted just after the last cab in this cabinet split chain according to DiskID Sort | ||
372 | // This is because the FDI Extract requires DiskID of Split Cabinets to be continuous. It Fails otherwise with | ||
373 | // Error 2350 (FDI Server Error) as next DiskID did not have the right split cabinet during extraction | ||
374 | MediaRow newMediaRow = (MediaRow)mediaTable.CreateRow(null); | ||
375 | newMediaRow.Cabinet = newCabinetName; | ||
376 | newMediaRow.DiskId = diskIDForLastSplitCabAdded + 1; // When Sorted with DiskID, this new Cabinet Row is an Insertion | ||
377 | newMediaRow.LastSequence = lastSequenceForLastSplitCabAdded; | ||
378 | |||
379 | // Now increment the DiskID for all rows that come after the newly inserted row to Ensure that DiskId is unique | ||
380 | foreach (MediaRow mediaRow in mediaTable.Rows) | ||
381 | { | ||
382 | // Check if this row comes after inserted row and it is not the new cabinet inserted row | ||
383 | if (mediaRow.DiskId >= newMediaRow.DiskId && !newCabinetName.Equals(mediaRow.Cabinet, StringComparison.InvariantCultureIgnoreCase)) | ||
384 | { | ||
385 | mediaRow.DiskId++; // Increment DiskID | ||
386 | } | ||
387 | } | ||
388 | |||
389 | // Now Increment DiskID for All files Rows so that they refer to the right Media Row | ||
390 | foreach (WixFileRow wixFileRow in wixFileTable.Rows) | ||
391 | { | ||
392 | // Check if this row comes after inserted row and if this row is not the file that has to go into the current cabinet | ||
393 | // This check will work as we have only one large file in every splitting cabinet | ||
394 | // If we want to support splitting cabinet with more large files we need to update this code | ||
395 | if (wixFileRow.DiskId >= newMediaRow.DiskId && !wixFileRow.File.Equals(fileToken, StringComparison.InvariantCultureIgnoreCase)) | ||
396 | { | ||
397 | wixFileRow.DiskId++; // Increment DiskID | ||
398 | } | ||
399 | } | ||
400 | |||
401 | // Update the Last Cabinet Added in the Split Sequence in Dictionary for future callback | ||
402 | this.lastCabinetAddedToMediaTable[firstCabinetName] = newCabinetName; | ||
403 | |||
404 | mediaTable.ValidateRows(); // Valdiates DiskDIs, throws Exception as Wix Error if validation fails | ||
405 | } | ||
406 | finally | ||
407 | { | ||
408 | // Releasing the Mutex here | ||
409 | mutex.ReleaseMutex(); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | |||
414 | /// <summary> | ||
415 | /// Gets Compiler Values of MediaTemplate Attributes governing Maximum Cabinet Size after applying Environment Variable Overrides | ||
416 | /// </summary> | ||
417 | /// <param name="output">Output to generate image for.</param> | ||
418 | /// <param name="fileRows">The indexed file rows.</param> | ||
419 | private void GetMediaTemplateAttributes(out int maxCabSizeForLargeFileSplitting, out int maxUncompressedMediaSize) | ||
420 | { | ||
421 | // Get Environment Variable Overrides for MediaTemplate Attributes governing Maximum Cabinet Size | ||
422 | string mcslfsString = Environment.GetEnvironmentVariable("WIX_MCSLFS"); | ||
423 | string mumsString = Environment.GetEnvironmentVariable("WIX_MUMS"); | ||
424 | int maxCabSizeForLargeFileInMB = 0; | ||
425 | int maxPreCompressedSizeInMB = 0; | ||
426 | ulong testOverFlow = 0; | ||
427 | |||
428 | // Supply Compile MediaTemplate Attributes to Cabinet Builder | ||
429 | Table mediaTemplateTable = this.Output.Tables["WixMediaTemplate"]; | ||
430 | if (mediaTemplateTable != null) | ||
431 | { | ||
432 | WixMediaTemplateRow mediaTemplateRow = (WixMediaTemplateRow)mediaTemplateTable.Rows[0]; | ||
433 | |||
434 | // Get the Value for Max Cab Size for File Splitting | ||
435 | try | ||
436 | { | ||
437 | // Override authored mcslfs value if environment variable is authored. | ||
438 | if (!String.IsNullOrEmpty(mcslfsString)) | ||
439 | { | ||
440 | maxCabSizeForLargeFileInMB = Int32.Parse(mcslfsString); | ||
441 | } | ||
442 | else | ||
443 | { | ||
444 | maxCabSizeForLargeFileInMB = mediaTemplateRow.MaximumCabinetSizeForLargeFileSplitting; | ||
445 | } | ||
446 | testOverFlow = (ulong)maxCabSizeForLargeFileInMB * 1024 * 1024; | ||
447 | } | ||
448 | catch (FormatException) | ||
449 | { | ||
450 | throw new WixException(WixErrors.IllegalEnvironmentVariable("WIX_MCSLFS", mcslfsString)); | ||
451 | } | ||
452 | catch (OverflowException) | ||
453 | { | ||
454 | throw new WixException(WixErrors.MaximumCabinetSizeForLargeFileSplittingTooLarge(null, maxCabSizeForLargeFileInMB, CompilerCore.MaxValueOfMaxCabSizeForLargeFileSplitting)); | ||
455 | } | ||
456 | |||
457 | try | ||
458 | { | ||
459 | // Override authored mums value if environment variable is authored. | ||
460 | if (!String.IsNullOrEmpty(mumsString)) | ||
461 | { | ||
462 | maxPreCompressedSizeInMB = Int32.Parse(mumsString); | ||
463 | } | ||
464 | else | ||
465 | { | ||
466 | maxPreCompressedSizeInMB = mediaTemplateRow.MaximumUncompressedMediaSize; | ||
467 | } | ||
468 | testOverFlow = (ulong)maxPreCompressedSizeInMB * 1024 * 1024; | ||
469 | } | ||
470 | catch (FormatException) | ||
471 | { | ||
472 | throw new WixException(WixErrors.IllegalEnvironmentVariable("WIX_MUMS", mumsString)); | ||
473 | } | ||
474 | catch (OverflowException) | ||
475 | { | ||
476 | throw new WixException(WixErrors.MaximumUncompressedMediaSizeTooLarge(null, maxPreCompressedSizeInMB)); | ||
477 | } | ||
478 | |||
479 | maxCabSizeForLargeFileSplitting = maxCabSizeForLargeFileInMB; | ||
480 | maxUncompressedMediaSize = maxPreCompressedSizeInMB; | ||
481 | } | ||
482 | else | ||
483 | { | ||
484 | maxCabSizeForLargeFileSplitting = 0; | ||
485 | maxUncompressedMediaSize = CompilerCore.DefaultMaximumUncompressedMediaSize; | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | } | ||