/// <summary> /// Binds an output. /// </summary> /// <param name="output">The output to bind.</param> /// <param name="file">The Windows Installer file to create.</param> /// <remarks>The Binder.DeleteTempFiles method should be called after calling this method.</remarks> /// <returns>true if binding completed successfully; false otherwise</returns> public override bool Bind(Output output, string file) { // Need output object handle for NewCabNamesCallBack callback this.output = output; // ensure the cabinet cache path exists if we are going to use it if (null != this.cabCachePath && !Directory.Exists(this.cabCachePath)) { Directory.CreateDirectory(this.cabCachePath); } // tell the binder about the validator if validation isn't suppressed if (!this.suppressValidation && (OutputType.Module == output.Type || OutputType.Product == output.Type)) { if (String.IsNullOrEmpty(this.validator.TempFilesLocation)) { this.validator.TempFilesLocation = Environment.GetEnvironmentVariable("WIX_TEMP"); } // set the default cube file Assembly lightAssembly = Assembly.GetExecutingAssembly(); string lightDirectory = Path.GetDirectoryName(lightAssembly.Location); if (OutputType.Module == output.Type) { this.validator.AddCubeFile(Path.Combine(lightDirectory, "mergemod.cub")); } else // product { this.validator.AddCubeFile(Path.Combine(lightDirectory, "darice.cub")); } // by default, disable ICEs that have equivalent-or-better checks in WiX this.suppressICEs.Add("ICE08"); this.suppressICEs.Add("ICE33"); this.suppressICEs.Add("ICE47"); this.suppressICEs.Add("ICE66"); // set the ICEs string[] iceArray = new string[this.ices.Count]; this.ices.CopyTo(iceArray, 0); this.validator.ICEs = iceArray; // set the suppressed ICEs string[] suppressICEArray = new string[this.suppressICEs.Count]; this.suppressICEs.CopyTo(suppressICEArray, 0); this.validator.SuppressedICEs = suppressICEArray; } else { this.validator = null; } this.core = new BinderCore(this.MessageHandler); this.FileManager.MessageHandler = this.core; // Add properties we need to pass to other classes. if (this.suppressPatchSequenceData) { // Avoid unnecessary boxing if false. this.core.SetProperty(Binder.PARAM_SPSD_NAME, true); } this.core.SetProperty(BinderCore.OutputPath, file); if (!String.IsNullOrEmpty(this.outputsFile)) { this.core.SetProperty(BinderCore.IntermediateFolder, Path.GetDirectoryName(this.outputsFile)); } else if (!String.IsNullOrEmpty(this.contentsFile)) { this.core.SetProperty(BinderCore.IntermediateFolder, Path.GetDirectoryName(this.contentsFile)); } else if (!String.IsNullOrEmpty(this.builtOutputsFile)) { this.core.SetProperty(BinderCore.IntermediateFolder, Path.GetDirectoryName(this.builtOutputsFile)); } foreach (BinderExtension extension in this.extensions) { extension.Core = this.core; } if (null == output) { throw new ArgumentNullException("output"); } this.core.EncounteredError = false; switch (output.Type) { case OutputType.Bundle: return this.BindBundle(output, file); case OutputType.Transform: return this.BindTransform(output, file); default: return this.BindDatabase(output, file); } }
/// <summary> /// Creates an MSI binder. /// </summary> public Binder() { this.defaultCompressionLevel = Cab.CompressionLevel.Mszip; this.suppressICEs = new StringCollection(); this.ices = new StringCollection(); this.invalidArgs = new StringCollection(); this.validator = new Validator(); // Need fileTransfers handle for NewCabNamesCallBack callback this.fileTransfers = new ArrayList(); this.newCabNamesCallBack = NewCabNamesCallBack; this.lastCabinetAddedToMediaTable = new Dictionary<string, string>(); this.nonEmptyProductCodes = new StringCollection(); this.nonEmptyTransformNames = new StringCollection(); this.emptyTransformNames = new StringCollection(); }