@joebigelow / wix-1 / commits / 85a5fecd

Remove partial WixPdb support.

Not as useful as intended and I'd rather remove it than potentially have to support something as weird as this.

Bob Arnson committed Apr 11, 2020 at 19:35 UTC 85a5fecdef50f18af8c8a87d270b6d55a02165d2
2 files changed +219 -276
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+219 -232
@@ -22,7 +22,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
22 // As outlined in RFC 4122, this is our namespace for generating name-based (version 3) UUIDs.
23 internal static readonly Guid WixComponentGuidNamespace = new Guid("{3064E5C6-FB63-4FE9-AC49-E446A792EFA5}");
24
25 - public BindDatabaseCommand(IBindContext context, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtension, Validator validator):this(context, backendExtension, null, validator)
25 + public BindDatabaseCommand(IBindContext context, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtension, Validator validator) : this(context, backendExtension, null, validator)
26 {
27 }
28
@@ -225,167 +225,155 @@ namespace WixToolset.Core.WindowsInstaller.Bind
225 }
226
227 WindowsInstallerData output;
228 - if (this.PdbType == PdbType.Partial)
228 + this.Intermediate.UpdateLevel(Data.WindowsInstaller.IntermediateLevels.FullyBound);
229 + this.Messaging.Write(VerboseMessages.UpdatingFileInformation());
230 +
231 + // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules).
232 {
230 - // Time to create the output object, since we're bypassing everything that touches files.
231 - this.Intermediate.UpdateLevel(Data.WindowsInstaller.IntermediateLevels.PartiallyBound);
233 + var command = new ExtractEmbeddedFilesCommand(this.ExpectedEmbeddedFiles);
234 + command.Execute();
235 + }
236
233 - var command = new CreateOutputFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions);
237 + // This must occur after all variables and source paths have been resolved.
238 + List<FileFacade> fileFacades;
239 + {
240 + var command = new GetFileFacadesCommand(section);
241 command.Execute();
242
236 - output = command.Output;
243 + fileFacades = command.FileFacades;
244 }
238 - else
245 +
246 + // Retrieve file information from merge modules.
247 + if (SectionType.Product == section.Type)
248 {
240 - this.Intermediate.UpdateLevel(Data.WindowsInstaller.IntermediateLevels.FullyBound);
241 - this.Messaging.Write(VerboseMessages.UpdatingFileInformation());
249 + var wixMergeTuples = section.Tuples.OfType<WixMergeTuple>().ToList();
250
243 - // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules).
251 + if (wixMergeTuples.Any())
252 {
245 - var command = new ExtractEmbeddedFilesCommand(this.ExpectedEmbeddedFiles);
246 - command.Execute();
247 - }
253 + containsMergeModules = true;
254
249 - // This must occur after all variables and source paths have been resolved.
250 - List<FileFacade> fileFacades;
251 - {
252 - var command = new GetFileFacadesCommand(section);
255 + var command = new ExtractMergeModuleFilesCommand(this.Messaging, section, wixMergeTuples);
256 + command.FileFacades = fileFacades;
257 + command.OutputInstallerVersion = installerVersion;
258 + command.SuppressLayout = this.SuppressLayout;
259 + command.IntermediateFolder = this.IntermediateFolder;
260 command.Execute();
261
255 - fileFacades = command.FileFacades;
262 + fileFacades.AddRange(command.MergeModulesFileFacades);
263 }
264 + }
265 + else if (SectionType.Patch == section.Type)
266 + {
267 + // Merge transform data into the output object.
268 + //IEnumerable<FileFacade> filesFromTransform = this.CopyFromTransformData(this.Output);
269 +
270 + //var command = new CopyTransformDataCommand(this.Messaging, /*output*/this.SubStorages, tableDefinitions, copyOutFileRows: true);
271 + //command.Output = output;
272 + //command.TableDefinitions = this.TableDefinitions;
273 + //command.CopyOutFileRows = true;
274 + var command = new GetFileFacadesFromTransforms(this.Messaging, this.SubStorages, tableDefinitions);
275 + command.Execute();
276 + var filesFromTransforms = command.FileFacades;
277
258 - // Retrieve file information from merge modules.
259 - if (SectionType.Product == section.Type)
260 - {
261 - var wixMergeTuples = section.Tuples.OfType<WixMergeTuple>().ToList();
262 -
263 - if (wixMergeTuples.Any())
264 - {
265 - containsMergeModules = true;
266 -
267 - var command = new ExtractMergeModuleFilesCommand(this.Messaging, section, wixMergeTuples);
268 - command.FileFacades = fileFacades;
269 - command.OutputInstallerVersion = installerVersion;
270 - command.SuppressLayout = this.SuppressLayout;
271 - command.IntermediateFolder = this.IntermediateFolder;
272 - command.Execute();
273 -
274 - fileFacades.AddRange(command.MergeModulesFileFacades);
275 - }
276 - }
277 - else if (SectionType.Patch == section.Type)
278 - {
279 - // Merge transform data into the output object.
280 - //IEnumerable<FileFacade> filesFromTransform = this.CopyFromTransformData(this.Output);
281 -
282 - //var command = new CopyTransformDataCommand(this.Messaging, /*output*/this.SubStorages, tableDefinitions, copyOutFileRows: true);
283 - //command.Output = output;
284 - //command.TableDefinitions = this.TableDefinitions;
285 - //command.CopyOutFileRows = true;
286 - var command = new GetFileFacadesFromTransforms(this.Messaging, this.SubStorages, tableDefinitions);
287 - command.Execute();
288 - var filesFromTransforms = command.FileFacades;
289 -
290 - fileFacades.AddRange(filesFromTransforms);
291 - }
278 + fileFacades.AddRange(filesFromTransforms);
279 + }
280
293 - // stop processing if an error previously occurred
294 - if (this.Messaging.EncounteredError)
295 - {
296 - return null;
297 - }
281 + // stop processing if an error previously occurred
282 + if (this.Messaging.EncounteredError)
283 + {
284 + return null;
285 + }
286
299 - // Gather information about files that do not come from merge modules.
300 - {
301 - var command = new UpdateFileFacadesCommand(this.Messaging, section);
302 - command.FileFacades = fileFacades;
303 - command.UpdateFileFacades = fileFacades.Where(f => !f.FromModule);
304 - command.OverwriteHash = true;
305 - command.TableDefinitions = tableDefinitions;
306 - command.VariableCache = variableCache;
307 - command.Execute();
308 - }
287 + // Gather information about files that do not come from merge modules.
288 + {
289 + var command = new UpdateFileFacadesCommand(this.Messaging, section);
290 + command.FileFacades = fileFacades;
291 + command.UpdateFileFacades = fileFacades.Where(f => !f.FromModule);
292 + command.OverwriteHash = true;
293 + command.TableDefinitions = tableDefinitions;
294 + command.VariableCache = variableCache;
295 + command.Execute();
296 + }
297
310 - // Assign files to media.
311 - Dictionary<int, MediaTuple> assignedMediaRows;
312 - Dictionary<MediaTuple, IEnumerable<FileFacade>> filesByCabinetMedia;
313 - IEnumerable<FileFacade> uncompressedFiles;
314 - {
315 - var command = new AssignMediaCommand(section, this.Messaging);
316 - command.FileFacades = fileFacades;
317 - command.FilesCompressed = compressed;
318 - command.Execute();
298 + // Assign files to media.
299 + Dictionary<int, MediaTuple> assignedMediaRows;
300 + Dictionary<MediaTuple, IEnumerable<FileFacade>> filesByCabinetMedia;
301 + IEnumerable<FileFacade> uncompressedFiles;
302 + {
303 + var command = new AssignMediaCommand(section, this.Messaging);
304 + command.FileFacades = fileFacades;
305 + command.FilesCompressed = compressed;
306 + command.Execute();
307
320 - assignedMediaRows = command.MediaRows;
321 - filesByCabinetMedia = command.FileFacadesByCabinetMedia;
322 - uncompressedFiles = command.UncompressedFileFacades;
323 - }
308 + assignedMediaRows = command.MediaRows;
309 + filesByCabinetMedia = command.FileFacadesByCabinetMedia;
310 + uncompressedFiles = command.UncompressedFileFacades;
311 + }
312
325 - // stop processing if an error previously occurred
326 - if (this.Messaging.EncounteredError)
327 - {
328 - return null;
329 - }
313 + // stop processing if an error previously occurred
314 + if (this.Messaging.EncounteredError)
315 + {
316 + return null;
317 + }
318
331 - // Now that the variable cache is populated, resolve any delayed fields.
332 - if (this.DelayedFields.Any())
333 - {
334 - var command = new ResolveDelayedFieldsCommand(this.Messaging, this.DelayedFields, variableCache);
335 - command.Execute();
336 - }
319 + // Now that the variable cache is populated, resolve any delayed fields.
320 + if (this.DelayedFields.Any())
321 + {
322 + var command = new ResolveDelayedFieldsCommand(this.Messaging, this.DelayedFields, variableCache);
323 + command.Execute();
324 + }
325
338 - // Set generated component guids.
339 - {
340 - var command = new CalculateComponentGuids(this.Messaging, this.BackendHelper, this.PathResolver, section);
341 - command.Execute();
342 - }
326 + // Set generated component guids.
327 + {
328 + var command = new CalculateComponentGuids(this.Messaging, this.BackendHelper, this.PathResolver, section);
329 + command.Execute();
330 + }
331
344 - // Add missing CreateFolder tuples to null-keypath components.
345 - {
346 - var command = new AddCreateFoldersCommand(section);
347 - command.Execute();
348 - }
332 + // Add missing CreateFolder tuples to null-keypath components.
333 + {
334 + var command = new AddCreateFoldersCommand(section);
335 + command.Execute();
336 + }
337
350 - // stop processing if an error previously occurred
351 - if (this.Messaging.EncounteredError)
352 - {
353 - return null;
354 - }
338 + // stop processing if an error previously occurred
339 + if (this.Messaging.EncounteredError)
340 + {
341 + return null;
342 + }
343
356 - // Time to create the output object. Try to put as much above here as possible, updating the IR is better.
357 - {
358 - var command = new CreateOutputFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions);
359 - command.Execute();
344 + // Time to create the output object. Try to put as much above here as possible, updating the IR is better.
345 + {
346 + var command = new CreateOutputFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions);
347 + command.Execute();
348
361 - output = command.Output;
362 - }
349 + output = command.Output;
350 + }
351
364 - // Update file sequence.
365 - {
366 - var command = new UpdateMediaSequencesCommand(output, fileFacades);
367 - command.Execute();
368 - }
352 + // Update file sequence.
353 + {
354 + var command = new UpdateMediaSequencesCommand(output, fileFacades);
355 + command.Execute();
356 + }
357
370 - // Modularize identifiers.
371 - if (OutputType.Module == output.Type)
372 - {
373 - var command = new ModularizeCommand(output, modularizationGuid, section.Tuples.OfType<WixSuppressModularizationTuple>());
374 - command.Execute();
375 - }
376 - else if (output.Type == OutputType.Patch)
358 + // Modularize identifiers.
359 + if (OutputType.Module == output.Type)
360 + {
361 + var command = new ModularizeCommand(output, modularizationGuid, section.Tuples.OfType<WixSuppressModularizationTuple>());
362 + command.Execute();
363 + }
364 + else if (output.Type == OutputType.Patch)
365 + {
366 + foreach (var storage in this.SubStorages)
367 {
378 - foreach (var storage in this.SubStorages)
379 - {
380 - output.SubStorages.Add(storage);
381 - }
368 + output.SubStorages.Add(storage);
369 }
383 - else // we can create instance transforms since Component Guids are set.
384 - {
370 + }
371 + else // we can create instance transforms since Component Guids are set.
372 + {
373 #if TODO_FIX_INSTANCE_TRANSFORM
374 this.CreateInstanceTransforms(this.Output);
375 #endif
388 - }
376 + }
377
378 #if TODO_FINISH_UPDATE
379 // Extended binder extensions can be called now that fields are resolved.
@@ -423,48 +411,48 @@ namespace WixToolset.Core.WindowsInstaller.Bind
411 }
412 #endif
413
426 - this.ValidateComponentGuids(output);
414 + this.ValidateComponentGuids(output);
415
428 - // Stop processing if an error previously occurred.
429 - if (this.Messaging.EncounteredError)
430 - {
431 - return null;
432 - }
416 + // Stop processing if an error previously occurred.
417 + if (this.Messaging.EncounteredError)
418 + {
419 + return null;
420 + }
421
434 - // Ensure the intermediate folder is created since delta patches will be
435 - // created there.
436 - Directory.CreateDirectory(this.IntermediateFolder);
422 + // Ensure the intermediate folder is created since delta patches will be
423 + // created there.
424 + Directory.CreateDirectory(this.IntermediateFolder);
425
438 - if (SectionType.Patch == section.Type && this.DeltaBinaryPatch)
439 - {
440 - var command = new CreateDeltaPatchesCommand(fileFacades, this.IntermediateFolder, section.Tuples.OfType<WixPatchIdTuple>().FirstOrDefault());
441 - command.Execute();
442 - }
426 + if (SectionType.Patch == section.Type && this.DeltaBinaryPatch)
427 + {
428 + var command = new CreateDeltaPatchesCommand(fileFacades, this.IntermediateFolder, section.Tuples.OfType<WixPatchIdTuple>().FirstOrDefault());
429 + command.Execute();
430 + }
431
444 - // create cabinet files and process uncompressed files
445 - var layoutDirectory = Path.GetDirectoryName(this.OutputPath);
446 - if (!this.SuppressLayout || OutputType.Module == output.Type)
447 - {
448 - this.Messaging.Write(VerboseMessages.CreatingCabinetFiles());
449 -
450 - var command = new CreateCabinetsCommand(this.ServiceProvider, this.BackendHelper);
451 - command.CabbingThreadCount = this.CabbingThreadCount;
452 - command.CabCachePath = this.CabCachePath;
453 - command.DefaultCompressionLevel = this.DefaultCompressionLevel;
454 - command.Output = output;
455 - command.Messaging = this.Messaging;
456 - command.BackendExtensions = this.BackendExtensions;
457 - command.LayoutDirectory = layoutDirectory;
458 - command.Compressed = compressed;
459 - command.FileRowsByCabinet = filesByCabinetMedia;
460 - command.ResolveMedia = this.ResolveMedia;
461 - command.TableDefinitions = tableDefinitions;
462 - command.TempFilesLocation = this.IntermediateFolder;
463 - command.Execute();
432 + // create cabinet files and process uncompressed files
433 + var layoutDirectory = Path.GetDirectoryName(this.OutputPath);
434 + if (!this.SuppressLayout || OutputType.Module == output.Type)
435 + {
436 + this.Messaging.Write(VerboseMessages.CreatingCabinetFiles());
437 +
438 + var command = new CreateCabinetsCommand(this.ServiceProvider, this.BackendHelper);
439 + command.CabbingThreadCount = this.CabbingThreadCount;
440 + command.CabCachePath = this.CabCachePath;
441 + command.DefaultCompressionLevel = this.DefaultCompressionLevel;
442 + command.Output = output;
443 + command.Messaging = this.Messaging;
444 + command.BackendExtensions = this.BackendExtensions;
445 + command.LayoutDirectory = layoutDirectory;
446 + command.Compressed = compressed;
447 + command.FileRowsByCabinet = filesByCabinetMedia;
448 + command.ResolveMedia = this.ResolveMedia;
449 + command.TableDefinitions = tableDefinitions;
450 + command.TempFilesLocation = this.IntermediateFolder;
451 + command.Execute();
452
465 - fileTransfers.AddRange(command.FileTransfers);
466 - trackedFiles.AddRange(command.TrackedFiles);
467 - }
453 + fileTransfers.AddRange(command.FileTransfers);
454 + trackedFiles.AddRange(command.TrackedFiles);
455 + }
456
457 #if DELETE
458 if (OutputType.Patch == output.Type)
@@ -479,65 +467,65 @@ namespace WixToolset.Core.WindowsInstaller.Bind
467 }
468 #endif
469
482 - // stop processing if an error previously occurred
483 - if (this.Messaging.EncounteredError)
484 - {
485 - return null;
486 - }
470 + // stop processing if an error previously occurred
471 + if (this.Messaging.EncounteredError)
472 + {
473 + return null;
474 + }
475
488 - // Generate database file.
489 - this.Messaging.Write(VerboseMessages.GeneratingDatabase());
476 + // Generate database file.
477 + this.Messaging.Write(VerboseMessages.GeneratingDatabase());
478
491 - {
492 - var trackMsi = this.BackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final);
493 - trackedFiles.Add(trackMsi);
479 + {
480 + var trackMsi = this.BackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final);
481 + trackedFiles.Add(trackMsi);
482
495 - var temporaryFiles = this.GenerateDatabase(output, tableDefinitions, trackMsi.Path, false, false);
496 - trackedFiles.AddRange(temporaryFiles);
497 - }
483 + var temporaryFiles = this.GenerateDatabase(output, tableDefinitions, trackMsi.Path, false, false);
484 + trackedFiles.AddRange(temporaryFiles);
485 + }
486
499 - // Stop processing if an error previously occurred.
500 - if (this.Messaging.EncounteredError)
501 - {
502 - return null;
503 - }
487 + // Stop processing if an error previously occurred.
488 + if (this.Messaging.EncounteredError)
489 + {
490 + return null;
491 + }
492 +
493 + // Merge modules.
494 + if (containsMergeModules)
495 + {
496 + this.Messaging.Write(VerboseMessages.MergingModules());
497
505 - // Merge modules.
506 - if (containsMergeModules)
498 + // Add back possibly suppressed sequence tables since all sequence tables must be present
499 + // for the merge process to work. We'll drop the suppressed sequence tables again as
500 + // necessary.
501 + foreach (SequenceTable sequence in Enum.GetValues(typeof(SequenceTable)))
502 {
508 - this.Messaging.Write(VerboseMessages.MergingModules());
503 + var sequenceTableName = sequence.ToString();
504 + var sequenceTable = output.Tables[sequenceTableName];
505
510 - // Add back possibly suppressed sequence tables since all sequence tables must be present
511 - // for the merge process to work. We'll drop the suppressed sequence tables again as
512 - // necessary.
513 - foreach (SequenceTable sequence in Enum.GetValues(typeof(SequenceTable)))
506 + if (null == sequenceTable)
507 {
515 - var sequenceTableName = sequence.ToString();
516 - var sequenceTable = output.Tables[sequenceTableName];
517 -
518 - if (null == sequenceTable)
519 - {
520 - sequenceTable = output.EnsureTable(tableDefinitions[sequenceTableName]);
521 - }
522 -
523 - if (0 == sequenceTable.Rows.Count)
524 - {
525 - suppressedTableNames.Add(sequenceTableName);
526 - }
508 + sequenceTable = output.EnsureTable(tableDefinitions[sequenceTableName]);
509 }
510
529 - var command = new MergeModulesCommand();
530 - command.FileFacades = fileFacades;
531 - command.Output = output;
532 - command.OutputPath = this.OutputPath;
533 - command.SuppressedTableNames = suppressedTableNames;
534 - command.Execute();
511 + if (0 == sequenceTable.Rows.Count)
512 + {
513 + suppressedTableNames.Add(sequenceTableName);
514 + }
515 }
516
537 - if (this.Messaging.EncounteredError)
538 - {
539 - return null;
540 - }
517 + var command = new MergeModulesCommand();
518 + command.FileFacades = fileFacades;
519 + command.Output = output;
520 + command.OutputPath = this.OutputPath;
521 + command.SuppressedTableNames = suppressedTableNames;
522 + command.Execute();
523 + }
524 +
525 + if (this.Messaging.EncounteredError)
526 + {
527 + return null;
528 + }
529
530 #if TODO_FINISH_VALIDATION
531 // Validate the output if there is an MSI validator.
@@ -563,26 +551,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind
551 }
552 #endif
553
566 - // Process uncompressed files.
567 - if (!this.Messaging.EncounteredError && !this.SuppressLayout && uncompressedFiles.Any())
568 - {
569 - var command = new ProcessUncompressedFilesCommand(section, this.BackendHelper, this.PathResolver);
570 - command.Compressed = compressed;
571 - command.FileFacades = uncompressedFiles;
572 - command.LayoutDirectory = layoutDirectory;
573 - command.LongNamesInImage = longNames;
574 - command.ResolveMedia = this.ResolveMedia;
575 - command.DatabasePath = this.OutputPath;
576 - command.Execute();
577 -
578 - fileTransfers.AddRange(command.FileTransfers);
579 - trackedFiles.AddRange(command.TrackedFiles);
580 - }
554 + // Process uncompressed files.
555 + if (!this.Messaging.EncounteredError && !this.SuppressLayout && uncompressedFiles.Any())
556 + {
557 + var command = new ProcessUncompressedFilesCommand(section, this.BackendHelper, this.PathResolver);
558 + command.Compressed = compressed;
559 + command.FileFacades = uncompressedFiles;
560 + command.LayoutDirectory = layoutDirectory;
561 + command.LongNamesInImage = longNames;
562 + command.ResolveMedia = this.ResolveMedia;
563 + command.DatabasePath = this.OutputPath;
564 + command.Execute();
565
582 - // TODO: this is not sufficient to collect all Input files (for example, it misses Binary and Icon tables).
583 - trackedFiles.AddRange(fileFacades.Select(f => this.BackendHelper.TrackFile(f.SourcePath, TrackedFileType.Input, f.SourceLineNumber)));
566 + fileTransfers.AddRange(command.FileTransfers);
567 + trackedFiles.AddRange(command.TrackedFiles);
568 }
569
570 + // TODO: this is not sufficient to collect all Input files (for example, it misses Binary and Icon tables).
571 + trackedFiles.AddRange(fileFacades.Select(f => this.BackendHelper.TrackFile(f.SourcePath, TrackedFileType.Input, f.SourceLineNumber)));
572 +
573 var result = this.ServiceProvider.GetService<IBindResult>();
574 result.FileTransfers = fileTransfers;
575 result.TrackedFiles = trackedFiles;
src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
-44
@@ -435,50 +435,6 @@ namespace WixToolsetTest.CoreIntegration
435 }
436 }
437
438 - [Fact]
439 - public void CanBuildWithPartialWixpdbInput()
440 - {
441 - var folder = TestData.Get(@"TestData\SingleFile");
442 -
443 - using (var fs = new DisposableFileSystem())
444 - {
445 - var baseFolder = fs.GetFolder();
446 - var intermediateFolder = Path.Combine(baseFolder, "obj");
447 - var wixpdbPath = Path.Combine(baseFolder, @"partial\test.wixpdb");
448 -
449 - var result = WixRunner.Execute(new[]
450 - {
451 - "build",
452 - Path.Combine(folder, "Package.wxs"),
453 - Path.Combine(folder, "PackageComponents.wxs"),
454 - "-loc", Path.Combine(folder, "Package.en-us.wxl"),
455 - "-bindpath", Path.Combine(folder, "data"),
456 - "-intermediateFolder", intermediateFolder,
457 - //"-o", Path.Combine(baseFolder, @"partial\test.msi"),
458 - "-pdb", wixpdbPath,
459 - "-pdbtype", "Partial",
460 - }, out var messages);
461 - Assert.Equal(0, result);
462 -
463 - result = WixRunner.Execute(new[]
464 - {
465 - "build",
466 - wixpdbPath,
467 - "-loc", Path.Combine(folder, "Package.en-us.wxl"),
468 - "-bindpath", Path.Combine(folder, "data"),
469 - "-intermediateFolder", intermediateFolder,
470 - "-o", Path.Combine(baseFolder, @"bin\test.msi"),
471 - }, out messages);
472 - Assert.Equal(0, result);
473 -
474 - var builtFiles = Directory.GetFiles(Path.Combine(baseFolder, @"bin"));
475 - Assert.Equal(new[]{
476 - "test.msi",
477 - "test.wixpdb",
478 - }, builtFiles.Select(Path.GetFileName).ToArray());
479 - }
480 - }
481 -
438 [Fact]
439 public void CanBuildWixlib()
440 {