private void ImportDependencyProviders(Dtf.Database db) { if (db.Tables.Contains("WixDependencyProvider")) { string query = "SELECT `ProviderKey`, `Version`, `DisplayName`, `Attributes` FROM `WixDependencyProvider`"; using (Dtf.View view = db.OpenView(query)) { view.Execute(); while (true) { using (Dtf.Record record = view.Fetch()) { if (null == record) { break; } // Import the provider key and attributes. string providerKey = record.GetString(1); string version = record.GetString(2) ?? this.Facade.MsiPackage.ProductVersion; string displayName = record.GetString(3) ?? this.Facade.Package.DisplayName; int attributes = record.GetInteger(4); ProvidesDependency dependency = new ProvidesDependency(providerKey, version, displayName, attributes); dependency.Imported = true; this.Facade.Provides.Add(dependency); } } } } }
/// <summary> /// Query an MSI table for all records /// </summary> /// <param name="msi">The path to an MSI</param> /// <param name="sql">An MSI query</param> /// <returns>A list of records is returned</returns> /// <remarks>Uses DTF</remarks> public static List <DTF.Record> QueryAllRecords(string msi, string query) { List <DTF.Record> result = new List <DTF.Record>(); using (DTF.Database database = new DTF.Database(msi, DTF.DatabaseOpenMode.ReadOnly)) { using (DTF.View view = database.OpenView(query, null)) { view.Execute(); DTF.Record record = null; while (null != (record = view.Fetch())) { // Copy record created by Fetch to record created manually to remove View reference DTF.Record copyRecord = new DTF.Record(record.FieldCount); for (int i = 0; i <= record.FieldCount; i++) { copyRecord[i] = record[i]; } record.Close(); result.Add(copyRecord); } } } return(result); }
private void CreateRelatedPackages(Dtf.Database db) { // Represent the Upgrade table as related packages. if (db.Tables.Contains("Upgrade")) { using (Dtf.View view = db.OpenView("SELECT `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes` FROM `Upgrade`")) { view.Execute(); while (true) { using (Dtf.Record record = view.Fetch()) { if (null == record) { break; } WixBundleRelatedPackageRow related = (WixBundleRelatedPackageRow)this.RelatedPackageTable.CreateRow(this.Facade.Package.SourceLineNumbers); related.ChainPackageId = this.Facade.Package.WixChainItemId; related.Id = record.GetString(1); related.MinVersion = record.GetString(2); related.MaxVersion = record.GetString(3); related.Languages = record.GetString(4); int attributes = record.GetInteger(5); related.OnlyDetect = (attributes & MsiInterop.MsidbUpgradeAttributesOnlyDetect) == MsiInterop.MsidbUpgradeAttributesOnlyDetect; related.MinInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesVersionMinInclusive) == MsiInterop.MsidbUpgradeAttributesVersionMinInclusive; related.MaxInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive) == MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive; related.LangInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesLanguagesExclusive) == 0; } } } } }
private void ImportExternalCabinetAsPayloads(Dtf.Database db, WixBundlePayloadRow packagePayload, ISet <string> payloadNames) { if (db.Tables.Contains("Media")) { foreach (string cabinet in db.ExecuteStringQuery("SELECT `Cabinet` FROM `Media`")) { if (!String.IsNullOrEmpty(cabinet) && !cabinet.StartsWith("#", StringComparison.Ordinal)) { // If we didn't find the Payload as an existing child of the package, we need to // add it. We expect the file to exist on-disk in the same relative location as // the MSI expects to find it... string cabinetName = Path.Combine(Path.GetDirectoryName(packagePayload.Name), cabinet); if (!payloadNames.Contains(cabinetName)) { string generatedId = Common.GenerateIdentifier("cab", packagePayload.Id, cabinet); string payloadSourceFile = FileManager.ResolveRelatedFile(packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.Package.SourceLineNumbers, BindStage.Normal); WixBundlePayloadRow payload = (WixBundlePayloadRow)this.PayloadTable.CreateRow(this.Facade.Package.SourceLineNumbers); payload.Id = generatedId; payload.Name = cabinetName; payload.SourceFile = payloadSourceFile; payload.Compressed = packagePayload.Compressed; payload.UnresolvedSourceFile = cabinetName; payload.Package = packagePayload.Package; payload.Container = packagePayload.Container; payload.ContentFile = true; payload.EnableSignatureValidation = packagePayload.EnableSignatureValidation; payload.Packaging = packagePayload.Packaging; payload.ParentPackagePayload = packagePayload.Id; } } } } }
private void ImportDependencyProviders(WixBundleMsiPackageSymbol msiPackage, Dtf.Database db) { if (db.Tables.Contains("WixDependencyProvider")) { var query = "SELECT `ProviderKey`, `Version`, `DisplayName`, `Attributes` FROM `WixDependencyProvider`"; using (var view = db.OpenView(query)) { view.Execute(); while (true) { using (var record = view.Fetch()) { if (null == record) { break; } // Import the provider key and attributes. this.Section.AddSymbol(new ProvidesDependencySymbol(msiPackage.SourceLineNumbers) { PackageRef = msiPackage.Id.Id, Key = record.GetString(1), Version = record.GetString(2) ?? msiPackage.ProductVersion, DisplayName = record.GetString(3) ?? this.Facade.PackageSymbol.DisplayName, Attributes = record.GetInteger(4), Imported = true }); } } } } }
/// <summary> /// Checks if a given table exists in the msi /// </summary> /// <param name="msi">The MSI to verify</param> /// <param name="tableName">The Name of the table to check for</param> /// <returns>True if the table exists in the msi, false otherwise</returns> public static bool CheckTableExists(string msi, string tableName) { bool tableExists = false; using (DTF.Database database = new DTF.Database(msi, DTF.DatabaseOpenMode.ReadOnly)) { tableExists = database.Tables.Contains(tableName); } return(tableExists); }
/// <summary> /// Queries a Windows Installer database for a Property value. /// </summary> /// <param name="db">Database to query.</param> /// <param name="property">Property to examine.</param> /// <returns>String value for result or null if query doesn't match a single result.</returns> private static string GetProperty(Dtf.Database db, string property) { try { return(db.ExecuteScalar(PropertyQuery(property)).ToString()); } catch (Dtf.InstallerException) { } return(null); }
/// <summary> /// Queries a Windows Installer database to determine if one or more rows exist in the Property table. /// </summary> /// <param name="db">Database to query.</param> /// <param name="property">Property to examine.</param> /// <returns>True if query matches at least one result.</returns> private static bool HasProperty(Dtf.Database db, string property) { try { return(0 < db.ExecuteQuery(PropertyQuery(property)).Count); } catch (Dtf.InstallerException) { } return(false); }
private void SetPackageVisibility(Dtf.Database db, ISet <string> msiPropertyNames) { bool alreadyVisible = !ProcessMsiPackageCommand.HasProperty(db, "ARPSYSTEMCOMPONENT"); if (alreadyVisible != this.Facade.Package.Visible) // if not already set to the correct visibility. { // If the authoring specifically added "ARPSYSTEMCOMPONENT", don't do it again. if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT")) { this.AddMsiProperty("ARPSYSTEMCOMPONENT", this.Facade.Package.Visible ? String.Empty : "1"); } } }
private void SetPackageVisibility(Dtf.Database db, WixBundleMsiPackageSymbol msiPackage, ISet <string> msiPropertyNames) { var alreadyVisible = !ProcessMsiPackageCommand.HasProperty(db, "ARPSYSTEMCOMPONENT"); var visible = (this.Facade.PackageSymbol.Attributes & WixBundlePackageAttributes.Visible) == WixBundlePackageAttributes.Visible; // If not already set to the correct visibility. if (alreadyVisible != visible) { // If the authoring specifically added "ARPSYSTEMCOMPONENT", don't do it again. if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT")) { this.AddMsiProperty(msiPackage, "ARPSYSTEMCOMPONENT", visible ? String.Empty : "1"); } } }
/// <summary> /// Processes the Msp packages to add properties and payloads from the Msp packages. /// </summary> public void Execute() { var packagePayload = this.AuthoredPayloads[this.Facade.PackageSymbol.PayloadRef]; var mspPackage = (WixBundleMspPackageSymbol)this.Facade.SpecificPackageSymbol; var sourcePath = packagePayload.SourceFile.Path; try { // Read data out of the msp database... using (var sumInfo = new Dtf.SummaryInfo(sourcePath, false)) { mspPackage.PatchCode = sumInfo.RevisionNumber.Substring(0, 38); } using (var db = new Dtf.Database(sourcePath)) { if (String.IsNullOrEmpty(this.Facade.PackageSymbol.DisplayName)) { this.Facade.PackageSymbol.DisplayName = ProcessMspPackageCommand.GetPatchMetadataProperty(db, "DisplayName"); } if (String.IsNullOrEmpty(this.Facade.PackageSymbol.Description)) { this.Facade.PackageSymbol.Description = ProcessMspPackageCommand.GetPatchMetadataProperty(db, "Description"); } mspPackage.Manufacturer = ProcessMspPackageCommand.GetPatchMetadataProperty(db, "ManufacturerName"); } this.ProcessPatchXml(packagePayload, mspPackage, sourcePath); } catch (Dtf.InstallerException e) { this.Messaging.Write(ErrorMessages.UnableToReadPackageInformation(packagePayload.SourceLineNumbers, sourcePath, e.Message)); return; } if (String.IsNullOrEmpty(this.Facade.PackageSymbol.CacheId)) { this.Facade.PackageSymbol.CacheId = mspPackage.PatchCode; } }
private void SetPerMachineAppropriately(Dtf.Database db, string sourcePath) { if (this.Facade.MsiPackage.ForcePerMachine) { if (YesNoDefaultType.No == this.Facade.Package.PerMachine) { Messaging.Instance.OnMessage(WixWarnings.PerUserButForcingPerMachine(this.Facade.Package.SourceLineNumbers, sourcePath)); this.Facade.Package.PerMachine = YesNoDefaultType.Yes; // ensure that we think the package is per-machine. } // Force ALLUSERS=1 via the MSI command-line. this.AddMsiProperty("ALLUSERS", "1"); } else { string allusers = ProcessMsiPackageCommand.GetProperty(db, "ALLUSERS"); if (String.IsNullOrEmpty(allusers)) { // Not forced per-machine and no ALLUSERS property, flip back to per-user. if (YesNoDefaultType.Yes == this.Facade.Package.PerMachine) { Messaging.Instance.OnMessage(WixWarnings.ImplicitlyPerUser(this.Facade.Package.SourceLineNumbers, sourcePath)); this.Facade.Package.PerMachine = YesNoDefaultType.No; } } else if (allusers.Equals("1", StringComparison.Ordinal)) { if (YesNoDefaultType.No == this.Facade.Package.PerMachine) { Messaging.Instance.OnMessage(WixErrors.PerUserButAllUsersEquals1(this.Facade.Package.SourceLineNumbers, sourcePath)); } } else if (allusers.Equals("2", StringComparison.Ordinal)) { Messaging.Instance.OnMessage(WixWarnings.DiscouragedAllUsersValue(this.Facade.Package.SourceLineNumbers, sourcePath, (YesNoDefaultType.Yes == this.Facade.Package.PerMachine) ? "machine" : "user")); } else { Messaging.Instance.OnMessage(WixErrors.UnsupportedAllUsersValue(this.Facade.Package.SourceLineNumbers, sourcePath, allusers)); } } }
/// <summary> /// Processes the Msp packages to add properties and payloads from the Msp packages. /// </summary> public void Execute() { WixBundlePayloadRow packagePayload = this.AuthoredPayloads.Get(this.Facade.Package.PackagePayload); string sourcePath = packagePayload.FullFileName; try { // Read data out of the msp database... using (Dtf.SummaryInfo sumInfo = new Dtf.SummaryInfo(sourcePath, false)) { this.Facade.MspPackage.PatchCode = sumInfo.RevisionNumber.Substring(0, 38); } using (Dtf.Database db = new Dtf.Database(sourcePath)) { if (String.IsNullOrEmpty(this.Facade.Package.DisplayName)) { this.Facade.Package.DisplayName = ProcessMspPackageCommand.GetPatchMetadataProperty(db, "DisplayName"); } if (String.IsNullOrEmpty(this.Facade.Package.Description)) { this.Facade.Package.Description = ProcessMspPackageCommand.GetPatchMetadataProperty(db, "Description"); } this.Facade.MspPackage.Manufacturer = ProcessMspPackageCommand.GetPatchMetadataProperty(db, "ManufacturerName"); } this.ProcessPatchXml(packagePayload, sourcePath); } catch (Dtf.InstallerException e) { Messaging.Instance.OnMessage(WixErrors.UnableToReadPackageInformation(packagePayload.SourceLineNumbers, sourcePath, e.Message)); return; } if (String.IsNullOrEmpty(this.Facade.Package.CacheId)) { this.Facade.Package.CacheId = this.Facade.MspPackage.PatchCode; } }
private void CreateRelatedPackages(Dtf.Database db) { // Represent the Upgrade table as related packages. if (db.Tables.Contains("Upgrade")) { using (var view = db.OpenView("SELECT `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes` FROM `Upgrade`")) { view.Execute(); while (true) { using (var record = view.Fetch()) { if (null == record) { break; } var recordAttributes = record.GetInteger(5); var attributes = WixBundleRelatedPackageAttributes.None; attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect) == WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect ? WixBundleRelatedPackageAttributes.OnlyDetect : 0; attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive ? WixBundleRelatedPackageAttributes.MinInclusive : 0; attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive ? WixBundleRelatedPackageAttributes.MaxInclusive : 0; attributes |= (recordAttributes & WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive) == WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive ? WixBundleRelatedPackageAttributes.LangInclusive : 0; this.Section.AddSymbol(new WixBundleRelatedPackageSymbol(this.Facade.PackageSymbol.SourceLineNumbers) { PackageRef = this.Facade.PackageId, RelatedId = record.GetString(1), MinVersion = record.GetString(2), MaxVersion = record.GetString(3), Languages = record.GetString(4), Attributes = attributes, }); } } } } }
private void ImportExternalCabinetAsPayloads(Dtf.Database db, WixBundlePayloadSymbol packagePayload, ISet <string> payloadNames) { if (db.Tables.Contains("Media")) { foreach (var cabinet in db.ExecuteStringQuery("SELECT `Cabinet` FROM `Media`")) { if (!String.IsNullOrEmpty(cabinet) && !cabinet.StartsWith("#", StringComparison.Ordinal)) { // If we didn't find the Payload as an existing child of the package, we need to // add it. We expect the file to exist on-disk in the same relative location as // the MSI expects to find it... var cabinetName = Path.Combine(Path.GetDirectoryName(packagePayload.Name), cabinet); if (!payloadNames.Contains(cabinetName)) { var generatedId = Common.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet); var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.PackageSymbol.SourceLineNumbers, BindStage.Normal); this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Private, generatedId)) { Name = cabinetName, SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile }, Compressed = packagePayload.Compressed, UnresolvedSourceFile = cabinetName, PackageRef = packagePayload.PackageRef, ContainerRef = packagePayload.ContainerRef, ContentFile = true, EnableSignatureValidation = packagePayload.EnableSignatureValidation, Packaging = packagePayload.Packaging, ParentPackagePayloadRef = packagePayload.Id.Id, }); } } } } }
/// <summary> /// Processes the MSI packages to add properties and payloads from the MSI packages. /// </summary> public void Execute() { WixBundlePayloadRow packagePayload = this.AuthoredPayloads.Get(this.Facade.Package.PackagePayload); string sourcePath = packagePayload.FullFileName; bool longNamesInImage = false; bool compressed = false; bool x64 = false; try { // Read data out of the msi database... using (Dtf.SummaryInfo sumInfo = new Dtf.SummaryInfo(sourcePath, false)) { // 1 is the Word Count summary information stream bit that means // the MSI uses short file names when set. We care about long file // names so check when the bit is not set. longNamesInImage = 0 == (sumInfo.WordCount & 1); // 2 is the Word Count summary information stream bit that means // files are compressed in the MSI by default when the bit is set. compressed = 2 == (sumInfo.WordCount & 2); x64 = (sumInfo.Template.Contains("x64") || sumInfo.Template.Contains("Intel64")); // 8 is the Word Count summary information stream bit that means // "Elevated privileges are not required to install this package." // in MSI 4.5 and below, if this bit is 0, elevation is required. this.Facade.Package.PerMachine = (0 == (sumInfo.WordCount & 8)) ? YesNoDefaultType.Yes : YesNoDefaultType.No; this.Facade.Package.x64 = x64 ? YesNoType.Yes : YesNoType.No; } using (Dtf.Database db = new Dtf.Database(sourcePath)) { this.Facade.MsiPackage.ProductCode = ProcessMsiPackageCommand.GetProperty(db, "ProductCode"); this.Facade.MsiPackage.UpgradeCode = ProcessMsiPackageCommand.GetProperty(db, "UpgradeCode"); this.Facade.MsiPackage.Manufacturer = ProcessMsiPackageCommand.GetProperty(db, "Manufacturer"); this.Facade.MsiPackage.ProductLanguage = Convert.ToInt32(ProcessMsiPackageCommand.GetProperty(db, "ProductLanguage"), CultureInfo.InvariantCulture); this.Facade.MsiPackage.ProductVersion = ProcessMsiPackageCommand.GetProperty(db, "ProductVersion"); if (!Common.IsValidModuleOrBundleVersion(this.Facade.MsiPackage.ProductVersion)) { // not a proper .NET version (e.g., five fields); can we get a valid four-part version number? string version = null; string[] versionParts = this.Facade.MsiPackage.ProductVersion.Split('.'); int count = versionParts.Length; if (0 < count) { version = versionParts[0]; for (int i = 1; i < 4 && i < count; ++i) { version = String.Concat(version, ".", versionParts[i]); } } if (!String.IsNullOrEmpty(version) && Common.IsValidModuleOrBundleVersion(version)) { Messaging.Instance.OnMessage(WixWarnings.VersionTruncated(this.Facade.Package.SourceLineNumbers, this.Facade.MsiPackage.ProductVersion, sourcePath, version)); this.Facade.MsiPackage.ProductVersion = version; } else { Messaging.Instance.OnMessage(WixErrors.InvalidProductVersion(this.Facade.Package.SourceLineNumbers, this.Facade.MsiPackage.ProductVersion, sourcePath)); } } if (String.IsNullOrEmpty(this.Facade.Package.CacheId)) { this.Facade.Package.CacheId = String.Format("{0}v{1}", this.Facade.MsiPackage.ProductCode, this.Facade.MsiPackage.ProductVersion); } if (String.IsNullOrEmpty(this.Facade.Package.DisplayName)) { this.Facade.Package.DisplayName = ProcessMsiPackageCommand.GetProperty(db, "ProductName"); } if (String.IsNullOrEmpty(this.Facade.Package.Description)) { this.Facade.Package.Description = ProcessMsiPackageCommand.GetProperty(db, "ARPCOMMENTS"); } ISet <string> payloadNames = this.GetPayloadTargetNames(); ISet <string> msiPropertyNames = this.GetMsiPropertyNames(); this.SetPerMachineAppropriately(db, sourcePath); // Ensure the MSI package is appropriately marked visible or not. this.SetPackageVisibility(db, msiPropertyNames); // Unless the MSI or setup code overrides the default, set MSIFASTINSTALL for best performance. if (!msiPropertyNames.Contains("MSIFASTINSTALL") && !ProcessMsiPackageCommand.HasProperty(db, "MSIFASTINSTALL")) { this.AddMsiProperty("MSIFASTINSTALL", "7"); } this.CreateRelatedPackages(db); // If feature selection is enabled, represent the Feature table in the manifest. if (this.Facade.MsiPackage.EnableFeatureSelection) { this.CreateMsiFeatures(db); } // Add all external cabinets as package payloads. this.ImportExternalCabinetAsPayloads(db, packagePayload, payloadNames); // Add all external files as package payloads and calculate the total install size as the rollup of // File table's sizes. this.Facade.Package.InstallSize = this.ImportExternalFileAsPayloadsAndReturnInstallSize(db, packagePayload, longNamesInImage, compressed, payloadNames); // Add all dependency providers from the MSI. this.ImportDependencyProviders(db); } } catch (Dtf.InstallerException e) { Messaging.Instance.OnMessage(WixErrors.UnableToReadPackageInformation(this.Facade.Package.SourceLineNumbers, sourcePath, e.Message)); } }
private void CreateMsiFeatures(Dtf.Database db) { if (db.Tables.Contains("Feature")) { using (var featureView = db.OpenView("SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = ?")) using (var componentView = db.OpenView("SELECT `FileSize` FROM `File` WHERE `Component_` = ?")) { using (var featureRecord = new Dtf.Record(1)) using (var componentRecord = new Dtf.Record(1)) { using (var allFeaturesView = db.OpenView("SELECT * FROM `Feature`")) { allFeaturesView.Execute(); while (true) { using (var allFeaturesResultRecord = allFeaturesView.Fetch()) { if (null == allFeaturesResultRecord) { break; } var featureName = allFeaturesResultRecord.GetString(1); // Calculate the Feature size. featureRecord.SetString(1, featureName); featureView.Execute(featureRecord); // Loop over all the components for the feature to calculate the size of the feature. long size = 0; while (true) { using (var componentResultRecord = featureView.Fetch()) { if (null == componentResultRecord) { break; } var component = componentResultRecord.GetString(1); componentRecord.SetString(1, component); componentView.Execute(componentRecord); while (true) { using (var fileResultRecord = componentView.Fetch()) { if (null == fileResultRecord) { break; } var fileSize = fileResultRecord.GetString(1); size += Convert.ToInt32(fileSize, CultureInfo.InvariantCulture.NumberFormat); } } } } this.Section.AddSymbol(new WixBundleMsiFeatureSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, this.Facade.PackageId, featureName)) { PackageRef = this.Facade.PackageId, Name = featureName, Parent = allFeaturesResultRecord.GetString(2), Title = allFeaturesResultRecord.GetString(3), Description = allFeaturesResultRecord.GetString(4), Display = allFeaturesResultRecord.GetInteger(5), Level = allFeaturesResultRecord.GetInteger(6), Directory = allFeaturesResultRecord.GetString(7), Attributes = allFeaturesResultRecord.GetInteger(8), Size = size }); } } } } } } }
private void CreateMsiFeatures(Dtf.Database db) { if (db.Tables.Contains("Feature")) { using (Dtf.View featureView = db.OpenView("SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = ?")) using (Dtf.View componentView = db.OpenView("SELECT `FileSize` FROM `File` WHERE `Component_` = ?")) { using (Dtf.Record featureRecord = new Dtf.Record(1)) using (Dtf.Record componentRecord = new Dtf.Record(1)) { using (Dtf.View allFeaturesView = db.OpenView("SELECT * FROM `Feature`")) { allFeaturesView.Execute(); while (true) { using (Dtf.Record allFeaturesResultRecord = allFeaturesView.Fetch()) { if (null == allFeaturesResultRecord) { break; } string featureName = allFeaturesResultRecord.GetString(1); // Calculate the Feature size. featureRecord.SetString(1, featureName); featureView.Execute(featureRecord); // Loop over all the components for the feature to calculate the size of the feature. long size = 0; while (true) { using (Dtf.Record componentResultRecord = featureView.Fetch()) { if (null == componentResultRecord) { break; } string component = componentResultRecord.GetString(1); componentRecord.SetString(1, component); componentView.Execute(componentRecord); while (true) { using (Dtf.Record fileResultRecord = componentView.Fetch()) { if (null == fileResultRecord) { break; } string fileSize = fileResultRecord.GetString(1); size += Convert.ToInt32(fileSize, CultureInfo.InvariantCulture.NumberFormat); } } } } WixBundleMsiFeatureRow feature = (WixBundleMsiFeatureRow)this.MsiFeatureTable.CreateRow(this.Facade.Package.SourceLineNumbers); feature.ChainPackageId = this.Facade.Package.WixChainItemId; feature.Name = featureName; feature.Parent = allFeaturesResultRecord.GetString(2); feature.Title = allFeaturesResultRecord.GetString(3); feature.Description = allFeaturesResultRecord.GetString(4); feature.Display = allFeaturesResultRecord.GetInteger(5); feature.Level = allFeaturesResultRecord.GetInteger(6); feature.Directory = allFeaturesResultRecord.GetString(7); feature.Attributes = allFeaturesResultRecord.GetInteger(8); feature.Size = size; } } } } } } }
private long ImportExternalFileAsPayloadsAndReturnInstallSize(Dtf.Database db, WixBundlePayloadSymbol packagePayload, bool longNamesInImage, bool compressed, ISet <string> payloadNames) { long size = 0; if (db.Tables.Contains("Component") && db.Tables.Contains("Directory") && db.Tables.Contains("File")) { var directories = new Dictionary <string, IResolvedDirectory>(); // Load up the directory hash table so we will be able to resolve source paths // for files in the MSI database. using (var view = db.OpenView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`")) { view.Execute(); while (true) { using (var record = view.Fetch()) { if (null == record) { break; } var sourceName = Common.GetName(record.GetString(3), true, longNamesInImage); var resolvedDirectory = this.BackendHelper.CreateResolvedDirectory(record.GetString(2), sourceName); directories.Add(record.GetString(1), resolvedDirectory); } } } // Resolve the source paths to external files and add each file size to the total // install size of the package. using (var view = db.OpenView("SELECT `Directory_`, `File`, `FileName`, `File`.`Attributes`, `FileSize` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_`")) { view.Execute(); while (true) { using (var record = view.Fetch()) { if (null == record) { break; } // If the file is explicitly uncompressed or the MSI is uncompressed and the file is not // explicitly marked compressed then this is an external file. var compressionBit = record.GetInteger(4); if (WindowsInstallerConstants.MsidbFileAttributesNoncompressed == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) || (!compressed && 0 == (compressionBit & WindowsInstallerConstants.MsidbFileAttributesCompressed))) { string fileSourcePath = this.PathResolver.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage); var name = Path.Combine(Path.GetDirectoryName(packagePayload.Name), fileSourcePath); if (!payloadNames.Contains(name)) { var generatedId = Common.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2)); var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.PackageSymbol.SourceLineNumbers); this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) { Name = name, SourceFile = new IntermediateFieldPathValue { Path = payloadSourceFile }, Compressed = packagePayload.Compressed, UnresolvedSourceFile = name, PackageRef = packagePayload.PackageRef, ContainerRef = packagePayload.ContainerRef, ContentFile = true, Packaging = packagePayload.Packaging, ParentPackagePayloadRef = packagePayload.Id.Id, }); } } size += record.GetInteger(5); } } } } return(size); }
private long ImportExternalFileAsPayloadsAndReturnInstallSize(Dtf.Database db, WixBundlePayloadRow packagePayload, bool longNamesInImage, bool compressed, ISet <string> payloadNames) { long size = 0; if (db.Tables.Contains("Component") && db.Tables.Contains("Directory") && db.Tables.Contains("File")) { Hashtable directories = new Hashtable(); // Load up the directory hash table so we will be able to resolve source paths // for files in the MSI database. using (Dtf.View view = db.OpenView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`")) { view.Execute(); while (true) { using (Dtf.Record record = view.Fetch()) { if (null == record) { break; } string sourceName = Installer.GetName(record.GetString(3), true, longNamesInImage); directories.Add(record.GetString(1), new ResolvedDirectory(record.GetString(2), sourceName)); } } } // Resolve the source paths to external files and add each file size to the total // install size of the package. using (Dtf.View view = db.OpenView("SELECT `Directory_`, `File`, `FileName`, `File`.`Attributes`, `FileSize` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_`")) { view.Execute(); while (true) { using (Dtf.Record record = view.Fetch()) { if (null == record) { break; } // Skip adding the loose files as payloads if it was suppressed. if (!this.Facade.MsiPackage.SuppressLooseFilePayloadGeneration) { // If the file is explicitly uncompressed or the MSI is uncompressed and the file is not // explicitly marked compressed then this is an external file. if (MsiInterop.MsidbFileAttributesNoncompressed == (record.GetInteger(4) & MsiInterop.MsidbFileAttributesNoncompressed) || (!compressed && 0 == (record.GetInteger(4) & MsiInterop.MsidbFileAttributesCompressed))) { string fileSourcePath = Binder.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage); string name = Path.Combine(Path.GetDirectoryName(packagePayload.Name), fileSourcePath); if (!payloadNames.Contains(name)) { string generatedId = Common.GenerateIdentifier("f", packagePayload.Id, record.GetString(2)); string payloadSourceFile = FileManager.ResolveRelatedFile(packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.Package.SourceLineNumbers, BindStage.Normal); WixBundlePayloadRow payload = (WixBundlePayloadRow)this.PayloadTable.CreateRow(this.Facade.Package.SourceLineNumbers); payload.Id = generatedId; payload.Name = name; payload.SourceFile = payloadSourceFile; payload.Compressed = packagePayload.Compressed; payload.UnresolvedSourceFile = name; payload.Package = packagePayload.Package; payload.Container = packagePayload.Container; payload.ContentFile = true; payload.EnableSignatureValidation = packagePayload.EnableSignatureValidation; payload.Packaging = packagePayload.Packaging; payload.ParentPackagePayload = packagePayload.Id; } } } size += record.GetInteger(5); } } } } return(size); }