Example #1
1
        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 AutoGenInstanceProductCode()
        {
            string sourceFile = Path.Combine(InstanceTransformTests.TestDataDirectory, @"AutoGenInstanceProductCode\product.wxs");
            string msi = Builder.BuildPackage(sourceFile);

            // Verify that an instance transforms was created
            string transformName = "Instance1.mst";
            string mst = Path.Combine(Path.GetDirectoryName(msi), transformName);

            // Extract the transform
            InstanceTransformTests.ExtractTransform(msi, transformName, mst);

            // Verify that the base product code is the expected value
            Verifier.VerifyQuery(msi, "Select `Value` FROM `Property` WHERE `Property` = 'ProductCode'", "{4014E041-A968-4DE3-B43C-322DF9A19359}");

            // Verify that the transform changes the product code
            using (Database msiDatabase = new Database(msi, DatabaseOpenMode.ReadOnly))
            {
                msiDatabase.ApplyTransform(mst);
                string transformProductCode = null;
                using (View view = msiDatabase.OpenView("Select `Value` FROM `Property` WHERE `Property` = 'ProductCode'"))
                {
                    view.Execute();
                    var record = view.Fetch();

                    if (null != record)
                    {
                        transformProductCode = Convert.ToString(record.GetString(1));
                    }
                }

                Assert.False("{4014E041-A968-4DE3-B43C-322DF9A19359}".Equals(transformProductCode), "The product code was not transformed by the instance transform.");
            }
        }
Example #3
1
 /// <summary>
 /// Get Msi Property
 /// </summary>
 /// <param name="database"></param>
 /// <param name="propertyName"></param>
 /// <returns></returns>
 private static string GetMsiProperty(Database database, string propertyName)
 {
     using (View view = database.OpenView("SELECT Value FROM Property WHERE Property.Property='{0}'", propertyName))
     {
         view.Execute();
         using (Record record = view.Fetch())
         {
             return record[1].ToString();
         }
     }
 }
        public void FileTableRecordAdapted()
        {
            var path = Path.Combine(this.TestContext.DeploymentDirectory, "Example.msi");
            using (var db = new Database(path, DatabaseOpenMode.ReadOnly))
            {
                var query = db.Tables["File"].SqlSelectString;
                using (var view = db.OpenView(query))
                {
                    view.Execute();
                    var columns = ViewManager.GetColumns(view);

                    // Fetch and test a single record.
                    using (var record = view.Fetch())
                    {
                        Assert.IsNotNull(record, "No record was found.");
                        var copy = new Record(record, columns);

                        var adapter = new RecordPropertyAdapter();
                        var properties = adapter.GetProperties(copy);
                        Assert.IsNotNull(properties, "The properties were not adapted.");
                        Assert.AreEqual<int>(8, properties.Count, "The number of columns are incorrect.");

                        var property = adapter.GetProperty(copy, "FileName");
                        var type = typeof(string).FullName;
                        Assert.IsNotNull(property, "The FileName property was not adapted.");
                        Assert.IsTrue(adapter.IsGettable(property), "The FileName property is not gettable.");
                        Assert.AreEqual(type, adapter.GetPropertyTypeName(property), true, "The FileName property type is incorrect.");
                        Assert.AreEqual("product.wxs", RecordPropertyAdapter.GetPropertyValue(property, copy) as string, "The FileName propert value is incorrect.");

                        property = adapter.GetProperty(copy, "Attributes");
                        type = typeof(AttributeColumn).FullName;
                        Assert.IsNotNull(property, "The Attributes property was not adapted.");
                        Assert.AreEqual(type, adapter.GetPropertyTypeName(property), true, "The Attributes property type is incorrect.");
                        Assert.AreEqual<short>(512, Convert.ToInt16(RecordPropertyAdapter.GetPropertyValue(property, copy)), "The Attributes propert value is incorrect.");

                        property = adapter.GetProperty(copy, "Sequence");
                        type = typeof(int).FullName;
                        Assert.IsNotNull(property, "The Sequence property was not adapted.");
                        Assert.AreEqual("System.Int32", adapter.GetPropertyTypeName(property), true, "The Sequence property type is incorrect.");
                        Assert.AreEqual<int>(1, Convert.ToInt32(RecordPropertyAdapter.GetPropertyValue(property, copy)), "The Sequence propert value is incorrect.");
                    }
                }
            }
        }
        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);
                }
            }
        }
Example #6
1
        internal TableInfo(Database db, string name)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            this.name = name;

            using (View columnsView = db.OpenView("SELECT * FROM `{0}`", name))
            {
                this.columns = new ColumnCollection(columnsView);
            }

            this.primaryKeys = new ReadOnlyCollection<string>(
                TableInfo.GetTablePrimaryKeys(db, name));
        }
Example #7
1
 /// <summary>
 /// Performs a quick peek inside an MSI to see if it has our two properties.
 /// Hopefully, this will speed up our scanning of files.
 /// </summary>
 /// <param name="path"></param>
 /// <returns></returns>
 internal static bool HasCoAppProperties(string localPackagePath)
 {
     lock (typeof (MSIBase)) {
         try {
             using (var database = new Database(localPackagePath, DatabaseOpenMode.ReadOnly)) {
                 using (var view = database.OpenView("SELECT Value FROM Property WHERE Property='CoAppPackageFeed' OR Property='CoAppCompositionData'")) {
                     view.Execute();
                     return view.Count() == 2;
                 }
             }
         } catch {
             return false;
         }
     }
 }
        private string GetUpgradeCode(string installSource)
        {
            if (File.Exists(installSource))
            {
                try
                {
                    using (var database = new Database(installSource, DatabaseOpenMode.ReadOnly))
                    {
                        using (var view = database.OpenView(database.Tables["Property"].SqlSelectString))
                        {
                            view.Execute();
                            foreach (var rec in view)
                            {
                                if ("UpgradeCode".Equals(rec.GetString("Property"), StringComparison.OrdinalIgnoreCase))
                                {
                                    return rec.GetString("Value");
                                }
                            }
                        }
                    }
                }
                catch(Exception e)
                {
                    Logger.Log(e);
                }
            }
            else
            {
                Logger.Log(string.Format("The {0} doesn't exist, cannot find upgrade code.", installSource));
            }

            return string.Empty;
        }
        public void RecordIsReadOnly()
        {
            var path = Path.Combine(this.TestContext.DeploymentDirectory, "Example.msi");
            using (var db = new Database(path, DatabaseOpenMode.ReadOnly))
            {
                var query = db.Tables["File"].SqlSelectString;
                using (var view = db.OpenView(query))
                {
                    view.Execute();
                    var columns = ViewManager.GetColumns(view);

                    // Fetch and test a single record.
                    using (var record = view.Fetch())
                    {
                        Assert.IsNotNull(record, "No record was found.");
                        var copy = new Record(record, columns);

                        var adapter = new RecordPropertyAdapter();
                        var property = adapter.GetProperty(copy, "FileName");
                        Assert.IsFalse(adapter.IsSettable(property), "The FileName property is settable.");

                        // Throws NotSupportedException.
                        adapter.SetPropertyValue(property, "test.wxs");
                    }
                }
            }
        }
Example #10
1
        /// <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;
        }
Example #11
0
        protected bool GetSummaryInfoDiff(Database db1, Database db2, string[] options, TextWriter diffOutput, string linePrefix, IDiffEngineFactory diffFactory)
        {
            bool difference = false;

            SummaryInfo summInfo1 = db1.SummaryInfo;
            SummaryInfo summInfo2 = db2.SummaryInfo;
            if(summInfo1.Title          != summInfo2.Title         ) { diffOutput.WriteLine("{0}SummaryInformation.Title {{{1}}}->{{{2}}}", linePrefix, summInfo1.Title, summInfo2.Title); difference = true; }
            if(summInfo1.Subject        != summInfo2.Subject       ) { diffOutput.WriteLine("{0}SummaryInformation.Subject {{{1}}}->{{{2}}}", linePrefix, summInfo1.Subject, summInfo2.Subject); difference = true; }
            if(summInfo1.Author         != summInfo2.Author        ) { diffOutput.WriteLine("{0}SummaryInformation.Author {{{1}}}->{{{2}}}", linePrefix, summInfo1.Author, summInfo2.Author); difference = true; }
            if(summInfo1.Keywords       != summInfo2.Keywords      ) { diffOutput.WriteLine("{0}SummaryInformation.Keywords {{{1}}}->{{{2}}}", linePrefix, summInfo1.Keywords, summInfo2.Keywords); difference = true; }
            if(summInfo1.Comments       != summInfo2.Comments      ) { diffOutput.WriteLine("{0}SummaryInformation.Comments {{{1}}}->{{{2}}}", linePrefix, summInfo1.Comments, summInfo2.Comments); difference = true; }
            if(summInfo1.Template       != summInfo2.Template      ) { diffOutput.WriteLine("{0}SummaryInformation.Template {{{1}}}->{{{2}}}", linePrefix, summInfo1.Template, summInfo2.Template); difference = true; }
            if(summInfo1.LastSavedBy    != summInfo2.LastSavedBy   ) { diffOutput.WriteLine("{0}SummaryInformation.LastSavedBy {{{1}}}->{{{2}}}", linePrefix, summInfo1.LastSavedBy, summInfo2.LastSavedBy); difference = true; }
            if(summInfo1.RevisionNumber != summInfo2.RevisionNumber) { diffOutput.WriteLine("{0}SummaryInformation.RevisionNumber {{{1}}}->{{{2}}}", linePrefix, summInfo1.RevisionNumber, summInfo2.RevisionNumber); difference = true; }
            if(summInfo1.CreatingApp    != summInfo2.CreatingApp   ) { diffOutput.WriteLine("{0}SummaryInformation.CreatingApp {{{1}}}->{{{2}}}", linePrefix, summInfo1.CreatingApp, summInfo2.CreatingApp); difference = true; }
            if(summInfo1.LastPrintTime  != summInfo2.LastPrintTime ) { diffOutput.WriteLine("{0}SummaryInformation.LastPrintTime {{{1}}}->{{{2}}}", linePrefix, summInfo1.LastPrintTime, summInfo2.LastPrintTime); difference = true; }
            if(summInfo1.CreateTime     != summInfo2.CreateTime    ) { diffOutput.WriteLine("{0}SummaryInformation.CreateTime {{{1}}}->{{{2}}}", linePrefix, summInfo1.CreateTime, summInfo2.CreateTime); difference = true; }
            if(summInfo1.LastSaveTime   != summInfo2.LastSaveTime  ) { diffOutput.WriteLine("{0}SummaryInformation.LastSaveTime {{{1}}}->{{{2}}}", linePrefix, summInfo1.LastSaveTime, summInfo2.LastSaveTime); difference = true; }
            if(summInfo1.CodePage       != summInfo2.CodePage      ) { diffOutput.WriteLine("{0}SummaryInformation.Codepage {{{1}}}->{{{2}}}", linePrefix, summInfo1.CodePage, summInfo2.CodePage); difference = true; }
            if(summInfo1.PageCount      != summInfo2.PageCount     ) { diffOutput.WriteLine("{0}SummaryInformation.PageCount {{{1}}}->{{{2}}}", linePrefix, summInfo1.PageCount, summInfo2.PageCount); difference = true; }
            if(summInfo1.WordCount      != summInfo2.WordCount     ) { diffOutput.WriteLine("{0}SummaryInformation.WordCount {{{1}}}->{{{2}}}", linePrefix, summInfo1.WordCount, summInfo2.WordCount); difference = true; }
            if(summInfo1.CharacterCount != summInfo2.CharacterCount) { diffOutput.WriteLine("{0}SummaryInformation.CharacterCount {{{1}}}->{{{2}}}", linePrefix, summInfo1.CharacterCount, summInfo2.CharacterCount); difference = true; }
            if(summInfo1.Security       != summInfo2.Security      ) { diffOutput.WriteLine("{0}SummaryInformation.Security {{{1}}}->{{{2}}}", linePrefix, summInfo1.Security, summInfo2.Security); difference = true; }
            summInfo1.Close();
            summInfo2.Close();

            return difference;
        }
        public static void InitializeProductDatabase(Database db, bool sixtyFourBit)
        {
            db.SummaryInfo.CodePage = (short) Encoding.Default.CodePage;
            db.SummaryInfo.Title = "Windows Installer Test";
            db.SummaryInfo.Subject = db.SummaryInfo.Title;
            db.SummaryInfo.Author = typeof(WindowsInstallerUtils).Assembly.FullName;
            db.SummaryInfo.CreatingApp = db.SummaryInfo.Author;
            db.SummaryInfo.Comments = typeof(WindowsInstallerUtils).FullName + ".CreateBasicDatabase()";
            db.SummaryInfo.Keywords = "Installer,MSI,Database";
            db.SummaryInfo.PageCount = 300;
            db.SummaryInfo.WordCount = 0;
            db.SummaryInfo.RevisionNumber = Guid.NewGuid().ToString("B").ToUpper();
            db.SummaryInfo.Template = (sixtyFourBit ? "x64" : "Intel") + ";0";

            foreach (TableInfo tableInfo in Schema.Tables)
            {
                db.Execute(tableInfo.SqlCreateString);
            }

            db.Execute("INSERT INTO `Directory` (`Directory`, `DefaultDir`) VALUES ('TARGETDIR', 'SourceDir')");
            db.Execute("INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) VALUES ('ProgramFilesFolder', 'TARGETDIR', '.')");

            foreach (Action action in Sequence.InstallExecute)
            {
                db.Execute("INSERT INTO `InstallExecuteSequence` (`Action`, `Sequence`) VALUES ('{0}', {1})",
                    action.Name, action.Sequence);
            }
        }
Example #13
0
 public static void AddFileComponent(Database db,
     string featureName, string compName, string compId,
     string fileKey, string fileName)
 {
     db.Execute(
         "INSERT INTO `Component` " +
             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " +
             "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')",
         compName,
         compId,
         "TestDir",
         (int) ComponentAttributes.None,
         fileKey);
     db.Execute(
         "INSERT INTO `File` " +
             "(`File`, `Component_`, `FileName`, `FileSize`, `Attributes`, `Sequence`) " +
             "VALUES ('{0}', '{1}', '{2}', 1, 0, 1)",
         fileKey,
         compName,
         fileName);
     db.Execute(
         "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')",
         featureName,
         compName);
 }
Example #14
0
 public static void AddRegistryComponent(Database db,
     string featureName, string compName, string compId,
     string keyName, string keyValueName, string value)
 {
     db.Execute(
         "INSERT INTO `Component` " +
             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) " +
             "VALUES ('{0}', '{1}', '{2}', {3}, '{4}')",
         compName,
         compId,
         "TestDir",
         (int) ComponentAttributes.RegistryKeyPath,
         compName + "Reg1");
     db.Execute(
         "INSERT INTO `Registry` (`Registry`, `Root`, `Key`, `Name`, `Value`, `Component_`) VALUES ('{0}', {1}, '{2}', '{3}', '{4}', '{5}')",
         compName + "Reg1",
         -1,
         @"Software\Microsoft\Windows Installer Test\" + keyName,
         keyValueName,
         value,
         compName);
     db.Execute(
         "INSERT INTO `FeatureComponents` (`Feature_`, `Component_`) VALUES ('{0}', '{1}')",
         featureName,
         compName);
 }
Example #15
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);
        }
Example #16
0
        public void CreateTransformSummaryInfo(
            Database referenceDatabase,
            string transformFile,
            TransformErrors errors,
            TransformValidations validations)
        {
            if (referenceDatabase == null)
            {
                throw new ArgumentNullException("referenceDatabase");
            }

            if (String.IsNullOrEmpty(transformFile))
            {
                throw new ArgumentNullException("transformFile");
            }

            uint ret = NativeMethods.MsiCreateTransformSummaryInfo(
                (int) this.Handle,
                (int) referenceDatabase.Handle,
                transformFile,
                (int) errors,
                (int) validations);
            if (ret != 0)
            {
                throw InstallerException.ExceptionFromReturnCode(ret);
            }
        }
        public void InstallerDatabaseSchema()
        {
            string dbFile = "InstallerDatabaseSchema.msi";

            using (Database db = new Database(dbFile, DatabaseOpenMode.CreateDirect))
            {
                WindowsInstallerUtils.InitializeProductDatabase(db);
                db.Commit();
            }

            Assert.IsTrue(File.Exists(dbFile), "Checking whether created database file " + dbFile + " exists.");

            using (Database db = new Database(dbFile, DatabaseOpenMode.ReadOnly))
            {
                TableCollection tables = db.Tables;
                Assert.AreEqual<int>(Schema.Tables.Count, tables.Count, "Counting tables.");
                Assert.AreEqual<int>(Schema.Property.Columns.Count, tables["Property"].Columns.Count, "Counting columns in Property table.");

                foreach (TableInfo tableInfo in tables)
                {
                    Console.WriteLine(tableInfo.Name);
                    foreach (ColumnInfo columnInfo in tableInfo.Columns)
                    {
                        Console.WriteLine("\t{0} {1}", columnInfo.Name, columnInfo.ColumnDefinitionString);
                    }
                }
            }
        }
Example #18
0
 public static void AddFeature(Database db, string featureName)
 {
     db.Execute(
         "INSERT INTO `Feature` (`Feature`, `Title`, `Level`, `Attributes`) VALUES ('{0}', '{1}', {2}, {3})",
         featureName,
         featureName,
         1,
         (int) FeatureAttributes.None);
 }
Example #19
0
 public string GetMsiProductCode(string msiFilePath)
 {
     if (string.IsNullOrEmpty(msiFilePath)) throw new ArgumentNullException("msiFilePath");
     if (!File.Exists(msiFilePath)) throw new FileNotFoundException("msi file not found", msiFilePath);
     using (var database = new Database(msiFilePath, DatabaseOpenMode.ReadOnly))
     {
         return GetMsiProperty(database, "ProductCode");
     }
 }
Example #20
0
        /// <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);
        }
        protected override void ProcessRecord() {
#if USING_RESTABLE_CMDLET
            if(Remote) {
                ProcessRecordViaRest();
                return;
            }
#endif

            var wc = new WebClient();
            var tmp = "coapp.tools.powershell.msi".GenerateTemporaryFilename();
            if(Development) {
                wc.DownloadFile(@"http://downloads.coapp.org/files/Development.CoApp.Tools.Powershell.msi", tmp);
            } else if (Beta) {
                wc.DownloadFile(@"http://downloads.coapp.org/files/Beta.CoApp.Tools.Powershell.msi", tmp);
            } else {
                wc.DownloadFile(@"http://downloads.coapp.org/files/CoApp.Tools.Powershell.msi", tmp);
            }   

            
            FourPartVersion ver = FileVersionInfo.GetVersionInfo(tmp);

            if (ver == 0) {
                using (Database db = new Database(tmp)) {
                    ver = db.ExecuteScalar("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductVersion'") as string;
                }
            }

            FourPartVersion thisVer = this.Assembly().Version();
            if (ver < thisVer) {
                WriteObject("The current version {0} is newer than the version on the web {1}.".format( thisVer, ver));
                return;
            }

            if(ver == thisVer) {
                WriteObject("The current version {0} is the current version.".format(thisVer, ver));
                return;
            }

            WriteObject("The current version {0} will be replaced with the newer than the version from the web {1}.".format(thisVer, ver));

            using (dynamic ps = Runspace.DefaultRunspace.Dynamic()) {
                ps.InvokeExpression(@"msiexec.exe /i ""{0}""".format(tmp));
            }

            if (!KillPowershells) {
                WriteObject("FYI, the installer can't actually update without killing all the powershell tasks.");
                WriteObject("If you are running as admin, you can do this automatically with the -KillPowershells switch on this command.");
            } else {
                using (var ps = Runspace.DefaultRunspace.Dynamic()) {
                    ps.StopProcess(name: "powershell");
                }
            }

        }
Example #22
0
        public virtual bool GetDiff(string diffInput1, string diffInput2, string[] options, TextWriter diffOutput, string linePrefix, IDiffEngineFactory diffFactory)
        {
            bool difference = false;
            Database db1 = new Database(diffInput1, DatabaseOpenMode.ReadOnly);
            Database db2 = new Database(diffInput2, DatabaseOpenMode.ReadOnly);

            if(GetSummaryInfoDiff(db1, db2, options, diffOutput, linePrefix, diffFactory)) difference = true;
            if(GetDatabaseDiff(db1, db2, options, diffOutput, linePrefix, diffFactory)) difference = true;
            if(GetStreamsDiff(db1, db2, options, diffOutput, linePrefix, diffFactory)) difference = true;

            db1.Close();
            db2.Close();
            return difference;
        }
Example #23
0
        protected bool GetDatabaseDiff(Database db1, Database db2, string[] options, TextWriter diffOutput, string linePrefix, IDiffEngineFactory diffFactory)
        {
            bool difference = false;

            string tempFile = Path.GetTempFileName();
            if(db2.GenerateTransform(db1, tempFile))
            {
                difference = true;

                Database db = db1;
                db.ViewTransform(tempFile);

                string row, column, change;
                using (View view = db.OpenView("SELECT `Table`, `Column`, `Row`, `Data`, `Current` " +
                    "FROM `_TransformView` ORDER BY `Table`, `Row`"))
                {
                    view.Execute();

                    foreach (Record rec in view) using (rec)
                    {
                        column = String.Format("{0} {1}", rec[1], rec[2]);
                        change = "";
                        if (rec.IsNull(3))
                        {
                            row = "<DDL>";
                            if (!rec.IsNull(4))
                            {
                                change = "[" + rec[5] + "]: " + DecodeColDef(rec.GetInteger(4));
                            }
                        }
                        else
                        {
                            row = "[" + String.Join(",", rec.GetString(3).Split('\t')) + "]";
                            if (rec.GetString(2) != "INSERT" && rec.GetString(2) != "DELETE")
                            {
                                column = String.Format("{0}.{1}", rec[1], rec[2]);
                                change = "{" + rec[5] + "}->{" + rec[4] + "}";
                            }
                        }

                        diffOutput.WriteLine("{0}{1,-25} {2} {3}", linePrefix, column, row, change);
                    }
                }
            }
            File.Delete(tempFile);

            return difference;
        }
Example #24
0
        public void DatabaseAsQueryable()
        {
            using (Database db = new Database("testlinq.msi", DatabaseOpenMode.Create))
            {
                WindowsInstallerUtils.InitializeProductDatabase(db);
                WindowsInstallerUtils.CreateTestProduct(db);

                var comps = from c in db.AsQueryable().Components
                            select c;

                int count = 0;
                foreach (var c in comps)
                {
                    Console.WriteLine(c);
                    count++;
                }

                Assert.AreEqual<int>(1, count);
            }
        }
Example #25
0
        public static DataSet GetMSIData(string localPackagePath)
        {
            localPackagePath = localPackagePath.ToLower();

            if (MSIData.ContainsKey(localPackagePath)) {
                return MSIData[localPackagePath];
            }

            try {
                using (var database = new Database(localPackagePath, DatabaseOpenMode.ReadOnly)) {
                    var dataSet = new DataSet(localPackagePath) {EnforceConstraints = false};

                    foreach (var t in database.Tables) {
                        try {
                            if (!t.Columns[0].IsTemporary) {
                                if (SignificantTables.Any(tn => t.Name.IsWildcardMatch(tn))) {
                                    using (var dr = new MSIDataReader(database, t)) {
                                        dataSet.Tables.Add(t.Name).Load(dr);
                                    }
                                }
                            }
                        }
                        catch (Exception) {
                            // some tables not play nice.
                        }
                    }

                    //  GS01: this seems hinkey too... the local package is sometimes getting added twice. prollly a race condition somewhere.
                    if (MSIData.ContainsKey(localPackagePath)) {
                        return MSIData[localPackagePath];
                    }

                    MSIData.Add(localPackagePath, dataSet);
                    return dataSet;
                }
            }
            catch (InstallerException) {
                throw new InvalidPackageException(InvalidReason.NotValidMSI, localPackagePath);
            }
        }
Example #26
0
        public bool GenerateTransform(Database referenceDatabase, string transformFile)
        {
            if (referenceDatabase == null)
            {
                throw new ArgumentNullException("referenceDatabase");
            }

            if (String.IsNullOrEmpty(transformFile))
            {
                throw new ArgumentNullException("transformFile");
            }

            uint ret = NativeMethods.MsiDatabaseGenerateTransform((int) this.Handle, (int) referenceDatabase.Handle, transformFile, 0, 0);
            if (ret == (uint) NativeMethods.Error.NO_DATA)
            {
                return false;
            }
            else if (ret != 0)
            {
                throw InstallerException.ExceptionFromReturnCode(ret);
            }
            return true;
        }
Example #27
0
        /// <summary>
        /// Gets a complete list of external cabs referenced by the given installer database file.
        /// </summary>
        /// <returns>True upon completion of the task execution.</returns>
        public override bool Execute()
        {
            string databaseFile = this.database.ItemSpec;
            Object []args = { };
            System.Collections.Generic.List<ITaskItem> cabNames = new System.Collections.Generic.List<ITaskItem>();

            // If the file doesn't exist, no cabs to return, so exit now
            if (!File.Exists(databaseFile))
            {
                return true;
            }

            using (Database database = new Database(databaseFile))
            {
                // If the media table doesn't exist, no cabs to return, so exit now
                if (null == database.Tables["Media"])
                {
                    return true;
                }

                System.Collections.IList records = database.ExecuteQuery("SELECT `Cabinet` FROM `Media`", args);

                foreach (string cabName in records)
                {
                    if (String.IsNullOrEmpty(cabName) || cabName.StartsWith("#", StringComparison.Ordinal))
                    {
                        continue;
                    }

                    cabNames.Add(new TaskItem(Path.Combine(Path.GetDirectoryName(databaseFile), cabName)));
                }
            }

            this.cabList = cabNames.ToArray();

            return true;
        }
Example #28
0
        /// <summary>
        /// Prepares to extract a Windows Installer MSI package contained in a stream.
        /// </summary>
        /// <param name="path">The path of the Windows Installer MSI package to be extracted.</param>
        /// <param name="target">The path to the directory to extract into.</param>
        /// <exception cref="IOException">The package is damaged.</exception>
        internal MsiExtractor([NotNull] string path, [NotNull] string target)
            : base(target)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
            #endregion

            try
            {
                _database = new Database(path, DatabaseOpenMode.ReadOnly);
                ReadDirectories();
                ReadFiles();
                ReadCabinets();

                UnitsTotal = _files.Values.Sum(x => x.Size);
            }
                #region Error handling
            catch (InstallerException ex)
            {
                // Wrap exception since only certain exception types are allowed
                throw new IOException(Resources.ArchiveInvalid, ex);
            }
            #endregion
        }
Example #29
0
        /// <summary>
        /// Gets the weight of a package given its path.
        /// </summary>
        /// <param name="path">The path to the package.</param>
        /// <returns>The weight of a package given its path or 0 if the package is missing.</returns>
        internal static long GetWeightFromPath(string path)
        {
            if (File.Exists(path))
            {
                var weight = 0L;

                using (var db = new Database(path, DatabaseOpenMode.ReadOnly))
                {
                    // Get the total size of all files in the package.
                    if (null != db.Tables["File"])
                    {
                        weight += db.ExecuteIntegerQuery(PackageInfo.FileSizeQuery).Sum(i => i);
                    }

                    // TODO: Should the weight of the registry be taken into account?
                    // Storage isn't documented but it's probably a safe assumption value names and string data are double byte.

                    // Sum up reserve costs for local installs (source installs are uncommon).
                    if (null != db.Tables["ReserveCost"])
                    {
                        weight += db.ExecuteIntegerQuery(PackageInfo.ReserveCostSizeQuery).Sum(i => i);
                    }
                }

                // Use weight of package. May include just custom actions.
                if (0 >= weight)
                {
                    var file = new FileInfo(path);
                    weight = file.Length;
                }

                return weight;
            }

            return 0;
        }
        public void InstallerTransactTwoProducts()
        {
            string dbFile1 = "InstallerTransactProduct1.msi";
            string dbFile2 = "InstallerTransactProduct2.msi";
            string productCode1;
            string productCode2;

            using (Database db1 = new Database(dbFile1, DatabaseOpenMode.CreateDirect))
            {
                WindowsInstallerUtils.InitializeProductDatabase(db1);
                WindowsInstallerUtils.CreateTestProduct(db1);

                productCode1 = db1.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];

                db1.Commit();
            }

            using (Database db2 = new Database(dbFile2, DatabaseOpenMode.CreateDirect))
            {
                WindowsInstallerUtils.InitializeProductDatabase(db2);
                WindowsInstallerUtils.CreateTestProduct(db2);

                productCode2 = db2.ExecuteStringQuery("SELECT `Value` FROM `Property` WHERE `Property` = 'ProductCode'")[0];

                db2.Commit();
            }

            ProductInstallation installation1 = new ProductInstallation(productCode1);
            ProductInstallation installation2 = new ProductInstallation(productCode2);
            Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed before starting.");
            Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed before starting.");

            Installer.SetInternalUI(InstallUIOptions.Silent);
            ExternalUIHandler prevHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUILogger,
                InstallLogModes.FatalExit |
                InstallLogModes.Error |
                InstallLogModes.Warning |
                InstallLogModes.User |
                InstallLogModes.Info |
                InstallLogModes.ResolveSource |
                InstallLogModes.OutOfDiskSpace |
                InstallLogModes.ActionStart |
                InstallLogModes.ActionData |
                InstallLogModes.CommonData |
                InstallLogModes.Progress |
                InstallLogModes.Initialize |
                InstallLogModes.Terminate |
                InstallLogModes.ShowDialog);
            Assert.IsNull(prevHandler, "Checking that returned previous UI handler is null.");

            Transaction transaction = new Transaction("TestInstallTransaction", TransactionAttributes.None);

            Exception caughtEx = null;
            try
            {
                Installer.InstallProduct(dbFile1, String.Empty);
            }
            catch (Exception ex) { caughtEx = ex; }
            Assert.IsNull(caughtEx, "Exception thrown while installing product 1: " + caughtEx);

            Console.WriteLine();
            Console.WriteLine("===================================================================");
            Console.WriteLine();

            try
            {
                Installer.InstallProduct(dbFile2, String.Empty);
            }
            catch (Exception ex) { caughtEx = ex; }
            Assert.IsNull(caughtEx, "Exception thrown while installing product 2: " + caughtEx);

            transaction.Commit();
            transaction.Close();

            prevHandler = Installer.SetExternalUI(prevHandler, InstallLogModes.None);
            Assert.AreEqual<ExternalUIHandler>(WindowsInstallerTest.ExternalUILogger, prevHandler, "Checking that previously-set UI handler is returned.");

            Assert.IsTrue(installation1.IsInstalled, "Checking that product 1 is installed.");
            Assert.IsTrue(installation2.IsInstalled, "Checking that product 2 is installed.");

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("===================================================================");
            Console.WriteLine("===================================================================");
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();

            ExternalUIRecordHandler prevRecHandler = Installer.SetExternalUI(WindowsInstallerTest.ExternalUIRecordLogger,
                InstallLogModes.FatalExit |
                InstallLogModes.Error |
                InstallLogModes.Warning |
                InstallLogModes.User |
                InstallLogModes.Info |
                InstallLogModes.ResolveSource |
                InstallLogModes.OutOfDiskSpace |
                InstallLogModes.ActionStart |
                InstallLogModes.ActionData |
                InstallLogModes.CommonData |
                InstallLogModes.Progress |
                InstallLogModes.Initialize |
                InstallLogModes.Terminate |
                InstallLogModes.ShowDialog);
            Assert.IsNull(prevRecHandler, "Checking that returned previous UI record handler is null.");

            transaction = new Transaction("TestUninstallTransaction", TransactionAttributes.None);

            try
            {
                Installer.InstallProduct(dbFile1, "REMOVE=All");
            }
            catch (Exception ex) { caughtEx = ex; }
            Assert.IsNull(caughtEx, "Exception thrown while removing product 1: " + caughtEx);

            try
            {
                Installer.InstallProduct(dbFile2, "REMOVE=All");
            }
            catch (Exception ex) { caughtEx = ex; }
            Assert.IsNull(caughtEx, "Exception thrown while removing product 2: " + caughtEx);

            transaction.Commit();
            transaction.Close();

            Assert.IsFalse(installation1.IsInstalled, "Checking that product 1 is not installed after removing.");
            Assert.IsFalse(installation2.IsInstalled, "Checking that product 2 is not installed after removing.");

            prevRecHandler = Installer.SetExternalUI(prevRecHandler, InstallLogModes.None);
            Assert.AreEqual<ExternalUIRecordHandler>(WindowsInstallerTest.ExternalUIRecordLogger, prevRecHandler, "Checking that previously-set UI record handler is returned.");
        }
Example #31
0
        /// <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;
        }
Example #32
0
    public static Session OpenPackage(Database database, bool ignoreMachineState)
    {
        if (database == null)
        {
            throw new ArgumentNullException("database");
        }

        return Installer.OpenPackage(
            String.Format(CultureInfo.InvariantCulture, "#{0}", database.Handle),
            ignoreMachineState);
    }