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());
                    }
                }
            }
        }
Beispiel #4
0
        /// <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[])));
        }