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 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); } } } } }
public void SeekRecordThenTryFormatString() { string dbFile = "SeekRecordThenTryFormatString.msi"; using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) { WindowsInstallerUtils.InitializeProductDatabase(db); WindowsInstallerUtils.CreateTestProduct(db); string parameterFormatString = "[1]"; string[] properties = new string[] { "SonGoku", "Over 9000", }; string query = "SELECT `Property`, `Value` FROM `Property`"; using (View view = db.OpenView(query)) { using (Record rec = new Record(2)) { rec[1] = properties[0]; rec[2] = properties[1]; rec.FormatString = parameterFormatString; Console.WriteLine("Record fields before seeking: " + rec[0] + " " + rec[1] + " " + rec[2]); view.Seek(rec); //TODO: Why does view.Seek remove the record fields? Console.WriteLine("Record fields after seeking: " + rec[0] + " " + rec[1] + " " + rec[2]); // After inserting, the format string is invalid. Assert.AreEqual(String.Empty, rec.ToString()); } } } }
/// <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); }
public void DeleteRecord() { string dbFile = "DeleteRecord.msi"; using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) { WindowsInstallerUtils.InitializeProductDatabase(db); WindowsInstallerUtils.CreateTestProduct(db); string query = "SELECT `Property`, `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"; using (View view = db.OpenView(query)) { view.Execute(); Record rec = view.Fetch(); Console.WriteLine("Calling ToString() : " + rec); view.Delete(rec); } Assert.AreEqual(0, db.ExecuteStringQuery(query).Count); } }
public void InstallerViewTables() { string dbFile = "InstallerViewTables.msi"; using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) { WindowsInstallerUtils.InitializeProductDatabase(db); db.Commit(); using (View view1 = db.OpenView("SELECT `Property`, `Value` FROM `Property` WHERE `Value` IS NOT NULL")) { IList <TableInfo> viewTables = view1.Tables; Assert.IsNotNull(viewTables); Assert.AreEqual <int>(1, viewTables.Count); Assert.AreEqual <String>("Property", viewTables[0].Name); } using (View view2 = db.OpenView("INSERT INTO `Property` (`Property`, `Value`) VALUES ('TestViewTables', 1)")) { IList <TableInfo> viewTables = view2.Tables; Assert.IsNotNull(viewTables); Assert.AreEqual <int>(1, viewTables.Count); Assert.AreEqual <String>("Property", viewTables[0].Name); } using (View view3 = db.OpenView("UPDATE `Property` SET `Value` = 2 WHERE `Property` = 'TestViewTables'")) { IList <TableInfo> viewTables = view3.Tables; Assert.IsNotNull(viewTables); Assert.AreEqual <int>(1, viewTables.Count); Assert.AreEqual <String>("Property", viewTables[0].Name); } using (View view4 = db.OpenView("alter table Property hold")) { IList <TableInfo> viewTables = view4.Tables; Assert.IsNotNull(viewTables); Assert.AreEqual <int>(1, viewTables.Count); Assert.AreEqual <String>("Property", viewTables[0].Name); } } }
public void InsertRecordThenTryFormatString() { string dbFile = "InsertRecordThenTryFormatString.msi"; using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect)) { WindowsInstallerUtils.InitializeProductDatabase(db); WindowsInstallerUtils.CreateTestProduct(db); string parameterFormatString = "[1]"; string[] properties = new string[] { "SonGoku", "Over 9000", }; string query = "SELECT `Property`, `Value` FROM `Property`"; using (View view = db.OpenView(query)) { using (Record rec = new Record(2)) { rec[1] = properties[0]; rec[2] = properties[1]; rec.FormatString = parameterFormatString; Console.WriteLine("Format String before inserting: " + rec.FormatString); view.Insert(rec); Console.WriteLine("Format String after inserting: " + rec.FormatString); // After inserting, the format string is invalid. Assert.AreEqual(String.Empty, rec.ToString()); // Setting the format string manually makes it valid again. rec.FormatString = parameterFormatString; Assert.AreEqual(properties[0], rec.ToString()); } } } }
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); }
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 object[][] GetComponentRegistryRows(string productCode, string componentCode, Session session, bool includeComponent) { ArrayList rows = new ArrayList(); string componentPath = new ComponentInstallation(componentCode, productCode).Path; string componentKey = (string)session.Database.ExecuteScalar( "SELECT `Component` FROM `Component` WHERE `ComponentId` = '{0}'", componentCode); if (componentKey == null) { return(null); } int attributes = Convert.ToInt32(session.Database.ExecuteScalar( "SELECT `Attributes` FROM `Component` WHERE `Component` = '{0}'", componentKey)); bool registryKeyPath = (attributes & (int)ComponentAttributes.RegistryKeyPath) != 0; if (!registryKeyPath && componentPath.Length > 0) { componentPath = Path.GetDirectoryName(componentPath); } string keyPath = (string)session.Database.ExecuteScalar( "SELECT `KeyPath` FROM `Component` WHERE `Component` = '{0}'", componentKey); using (View view = session.Database.OpenView("SELECT `Registry`, `Root`, `Key`, `Name`, " + "`Value` FROM `Registry` WHERE `Component_` = '{0}'", componentKey)) { view.Execute(); foreach (Record rec in view) { using (rec) { string regName = (string)rec["Name"]; if (regName == "-") { continue; // Don't list deleted keys } string regTableKey = (string)rec["Registry"]; bool isKey = registryKeyPath && keyPath == regTableKey; string regPath = this.GetRegistryPath(session, (RegistryRoot)Convert.ToInt32(rec["Root"]), (string)rec["Key"], (string)rec["Name"]); string dbValue; using (Record formatRec = new Record(0)) { formatRec[0] = rec["Value"]; dbValue = session.FormatRecord(formatRec); } string installedValue = this.GetRegistryValue(regPath); bool exists = installedValue != null; if (!exists) { installedValue = ""; } bool match = installedValue == dbValue; object[] row; if (includeComponent) { row = new object[] { isKey, regTableKey, regPath, exists, dbValue, installedValue, match, componentCode } } ; else { row = new object[] { isKey, regTableKey, regPath, exists, dbValue, installedValue, match } }; rows.Add(row); } } } return((object[][])rows.ToArray(typeof(object[]))); }
private object[][] GetComponentFilesRows(string productCode, string componentCode, Session session, bool includeComponent) { ArrayList rows = new ArrayList(); string componentPath = new ComponentInstallation(componentCode, productCode).Path; string componentKey = (string)session.Database.ExecuteScalar( "SELECT `Component` FROM `Component` WHERE `ComponentId` = '{0}'", componentCode); if (componentKey == null) { return(null); } int attributes = Convert.ToInt32(session.Database.ExecuteScalar( "SELECT `Attributes` FROM `Component` WHERE `Component` = '{0}'", componentKey)); bool registryKeyPath = (attributes & (int)ComponentAttributes.RegistryKeyPath) != 0; if (!registryKeyPath && componentPath.Length > 0) { componentPath = Path.GetDirectoryName(componentPath); } string keyPath = (string)session.Database.ExecuteScalar( "SELECT `KeyPath` FROM `Component` WHERE `Component` = '{0}'", componentKey); using (View view = session.Database.OpenView("SELECT `File`, `FileName`, `Version`, `Language`, " + "`Attributes` FROM `File` WHERE `Component_` = '{0}'", componentKey)) { view.Execute(); foreach (Record rec in view) { using (rec) { string fileKey = (string)rec["File"]; bool isKey = !registryKeyPath && keyPath == fileKey; string dbVersion = (string)rec["Version"]; bool versionedFile = dbVersion.Length != 0; if (versionedFile) { string language = (string)rec["Language"]; if (language.Length > 0) { dbVersion = dbVersion + " (" + language + ")"; } } else if (session.Database.Tables.Contains("MsiFileHash")) { IList <int> hash = session.Database.ExecuteIntegerQuery("SELECT `HashPart1`, `HashPart2`, " + "`HashPart3`, `HashPart4` FROM `MsiFileHash` WHERE `File_` = '{0}'", fileKey); if (hash != null && hash.Count == 4) { dbVersion = this.GetFileHashString(hash); } } string filePath = GetLongFileName((string)rec["FileName"]); bool exists = false; bool installedMatch = false; string installedVersion = ""; if (!registryKeyPath && componentPath.Length > 0) { filePath = Path.Combine(componentPath, filePath); if (File.Exists(filePath)) { exists = true; if (versionedFile) { installedVersion = Installer.GetFileVersion(filePath); string language = Installer.GetFileLanguage(filePath); if (language.Length > 0) { installedVersion = installedVersion + " (" + language + ")"; } } else { int[] hash = new int[4]; Installer.GetFileHash(filePath, hash); installedVersion = this.GetFileHashString(hash); } installedMatch = installedVersion == dbVersion; } } object[] row; if (includeComponent) { row = new object[] { isKey, fileKey, filePath, exists, dbVersion, installedVersion, installedMatch, componentCode } } ; else { row = new object[] { isKey, fileKey, filePath, exists, dbVersion, installedVersion, installedMatch } }; rows.Add(row); } } } return((object[][])rows.ToArray(typeof(object[]))); }