예제 #1
0
        /// <summary>
        /// Writes and error to the pipeline.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing the error details.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnError(Deployment.WindowsInstaller.Record record)
        {
            if (null == record)
            {
                return(MessageResult.None);
            }
            else if (0 < record.FieldCount)
            {
                // Ignore certain errors.
                int code = record.GetInteger(1);
                switch (code)
                {
                case 1605:
                    // Continue even if there isn't enough disk space for rollback.
                    return(MessageResult.Ignore);

                case 1704:
                    // Roll back suspended installs so we can continue.
                    return(MessageResult.OK);
                }
            }

            using (var ex = new PSInstallerException(record))
            {
                if (null != ex.ErrorRecord)
                {
                    this.WriteError(ex.ErrorRecord);
                }
            }

            return(MessageResult.OK);
        }
예제 #2
0
            private void TestProgressPhase2()
            {
                // With product name, estimated tick count, generating script.
                using (var rec = new Deployment.WindowsInstaller.Record(4))
                {
                    // CommonData: set CurrentProductName.
                    rec.SetInteger(1, 1);
                    rec.SetString(2, "INSTALL");
                    this.OnMessage(InstallMessage.CommonData, rec);

                    // Progress: master rest.
                    rec.SetInteger(1, 0);  // Master reset.
                    rec.SetInteger(2, 50); // Total; test that 50 is added.
                    rec.SetInteger(3, 0);  // Forward.
                    rec.SetInteger(4, 1);  // Generating script.
                    this.OnMessage(InstallMessage.Progress, rec);

                    // ActionStart: set CurrentAction.
                    rec.FormatString = "Action: [1]: [2]";
                    rec.SetString(1, "Time");
                    rec.SetString(2, "Testing");
                    this.OnMessage(InstallMessage.ActionStart, rec);

                    // Progress: report progress.
                    rec.SetInteger(1, 2);
                    rec.SetInteger(2, 50);
                    this.OnMessage(InstallMessage.Progress, rec);

                    // Progress: expand total.
                    rec.SetInteger(1, 3);
                    rec.SetInteger(2, 50);
                    this.OnMessage(InstallMessage.Progress, rec);
                }
            }
예제 #3
0
        public void DeserializePSInstallerException()
        {
            PSInstallerException ex;
            var formatter = new BinaryFormatter();

            using (var ms = new MemoryStream())
            {
                // Serialize the error record.
                using (var record = new Deployment.WindowsInstaller.Record(2))
                {
                    record.FormatString = "Installed [2]";
                    record.SetInteger(1, 1715);
                    record.SetString(2, "TEST");

                    using (ex = new PSInstallerException(record))
                    {
                        formatter.Serialize(ms, ex);
                    }
                }

                // Reset the position.
                ms.Position = 0;

                // Deserialize the error record.
                using (ex = formatter.Deserialize(ms) as PSInstallerException)
                {
                    Assert.IsNotNull(ex);

                    var error = ex.ErrorRecord;
                    Assert.IsNotNull(error);
                    Assert.AreEqual("Installed TEST", ex.Message, true);
                    Assert.AreEqual("TEST", error.TargetObject as string, true);
                }
            }
        }
예제 #4
0
        public void DeserializePSInstallerException()
        {
            PSInstallerException ex;
            var formatter = new BinaryFormatter();

            using (var ms = new MemoryStream())
            {
                // Serialize the error record.
                using (var record = new Deployment.WindowsInstaller.Record(2))
                {
                    record.FormatString = "Installed [2]";
                    record.SetInteger(1, 1715);
                    record.SetString(2, "TEST");

                    using (ex = new PSInstallerException(record))
                    {
                        formatter.Serialize(ms, ex);
                    }
                }

                // Reset the position.
                ms.Position = 0;

                // Deserialize the error record.
                using (ex = formatter.Deserialize(ms) as PSInstallerException)
                {
                    Assert.IsNotNull(ex);

                    var error = ex.ErrorRecord;
                    Assert.IsNotNull(error);
                    Assert.AreEqual("Installed TEST", ex.Message, true);
                    Assert.AreEqual("TEST", error.TargetObject as string, true);
                }
            }
        }
예제 #5
0
        private MessageResult OnInformation(Deployment.WindowsInstaller.Record record)
        {
            if (null != record)
            {
                string message = record.ToString();
                if (!string.IsNullOrEmpty(message))
                {
                    var ice = new IceMessage(message);
                    var obj = PSObject.AsPSObject(ice);

                    if (!string.IsNullOrEmpty(this.CurrentPath))
                    {
                        ice.Path = this.CurrentPath;

                        // Set the PSPath for cmdlets that would use it.
                        string path = this.SessionState.Path.GetUnresolvedPSPathFromProviderPath(this.CurrentPath);
                        obj.SetPropertyValue <string>("PSPath", path);
                    }

                    var data = new Data(DataType.Information, obj);
                    this.Output.Enqueue(data);
                }
            }

            return(MessageResult.OK);
        }
예제 #6
0
        /// <summary>
        /// Called when an action sends more information.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing additional information.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnActionData(Deployment.WindowsInstaller.Record record)
        {
            if (this.progress.IsValid)
            {
                // Step the current progress completed.
                var current = this.progress.Current;

                if (current.EnableActionData)
                {
                    if (current.Forward)
                    {
                        current.Complete += current.Step;
                    }
                    else
                    {
                        current.Complete -= current.Step;
                    }
                }

                // Set the current action message when executing the script.
                if (null != record && !current.GeneratingScript)
                {
                    if (!string.IsNullOrEmpty(this.progress.CurrentActionTemplate))
                    {
                        record.FormatString = this.progress.CurrentActionTemplate;
                    }

                    this.progress.CurrentActionDetail = record.ToString();
                }

                this.WriteProgress();
            }

            return(MessageResult.OK);
        }
예제 #7
0
 private void TestVerbose()
 {
     using (var verbose = new Deployment.WindowsInstaller.Record(0))
     {
         verbose.FormatString = "verbose";
         this.OnMessage(InstallMessage.Info, verbose);
     }
 }
예제 #8
0
 private void TestWarning()
 {
     using (var warning = new Deployment.WindowsInstaller.Record(0))
     {
         warning.FormatString = "warning";
         this.OnMessage(InstallMessage.Warning, warning);
     }
 }
예제 #9
0
 private void TestError()
 {
     using (var error = new Deployment.WindowsInstaller.Record(2))
     {
         error.SetInteger(1, 1301);
         error.SetString(2, "error");
         this.OnMessage(InstallMessage.Error, error);
     }
 }
예제 #10
0
        /// <summary>
        /// Writes a verbose message to the pipeline.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing the verbose message details.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnVerbose(Deployment.WindowsInstaller.Record record)
        {
            if (null != record)
            {
                string message = record.ToString();
                this.WriteVerbose(message);
            }

            return(MessageResult.OK);
        }
예제 #11
0
 private void TestProgressPhase1()
 {
     // No product name or total tick count yet.
     using (var rec = new Deployment.WindowsInstaller.Record(2))
     {
         rec.SetInteger(1, 2);
         rec.SetInteger(2, 0);
         this.OnMessage(InstallMessage.Progress, rec);
     }
 }
예제 #12
0
        private MessageResult OnWarning(Deployment.WindowsInstaller.Record record)
        {
            if (null != record)
            {
                string message = record.ToString();

                var data = new Data(DataType.Warning, message);
                this.Output.Enqueue(data);
            }

            return(MessageResult.OK);
        }
예제 #13
0
        private static ErrorCategory GetErrorCategory(Deployment.WindowsInstaller.Record record, out string resource)
        {
            resource = null;

            if (1 < record.FieldCount)
            {
                int code = record.GetInteger(1);
                if (1000 <= code && code < 25000)
                {
                    // Specifically handle common errors.
                    switch (code)
                    {
                    case 1301:
                    case 1304:
                        resource = record.GetString(2);
                        return(ErrorCategory.WriteError);

                    case 1303:
                    case 1306:
                    case 1718:
                        resource = record.GetString(2);
                        return(ErrorCategory.PermissionDenied);

                    case 1305:
                        resource = record.GetString(2);
                        return(ErrorCategory.ReadError);

                    case 1308:
                    case 1334:
                        resource = record.GetString(2);
                        return(ErrorCategory.ResourceUnavailable);

                    case 1706:
                        resource = record.GetString(2);
                        return(ErrorCategory.ResourceUnavailable);

                    case 1715:
                    case 1716:
                    case 1717:
                        resource = record.GetString(2);
                        return(ErrorCategory.NotSpecified);

                    case 1935:
                    case 1937:
                        resource = record.GetString(6);
                        return(ErrorCategory.InvalidData);
                    }
                }
            }

            return(ErrorCategory.NotSpecified);
        }
예제 #14
0
        private MessageResult OnError(Deployment.WindowsInstaller.Record record)
        {
            if (null != record)
            {
                using (var ex = new PSInstallerException(record))
                {
                    if (null != ex.ErrorRecord)
                    {
                        var data = new Data(DataType.Error, ex.ErrorRecord);
                        this.Output.Enqueue(data);
                    }
                }
            }

            return(MessageResult.OK);
        }
예제 #15
0
        private MessageResult OnMessage(InstallMessage messageType, Deployment.WindowsInstaller.Record messageRecord, MessageButtons buttons, MessageIcon icon, MessageDefaultButton defaultButton)
        {
            switch (messageType)
            {
            case InstallMessage.FatalExit:
            case InstallMessage.Error:
                return(this.OnError(messageRecord));

            case InstallMessage.Warning:
                return(this.OnWarning(messageRecord));

            case InstallMessage.User:
                return(this.OnInformation(messageRecord));

            default:
                return(MessageResult.None);
            }
        }
예제 #16
0
        public void ValidateErrorRecordOpenError()
        {
            using (var record = new Deployment.WindowsInstaller.Record(2))
            {
                record.SetInteger(1, 1301);
                record.SetString(2, @"C:\test.txt");

                using (var ex = new PSInstallerException(record))
                {
                    var error = ex.ErrorRecord;
                    Assert.IsNotNull(error);
                    Assert.AreEqual(@"C:\test.txt", error.TargetObject as string, true);

                    var info = error.CategoryInfo;
                    Assert.IsNotNull(info);
                    Assert.AreEqual(ErrorCategory.WriteError, info.Category);
                }
            }
        }
예제 #17
0
파일: Record.cs 프로젝트: skyhoshi/psmsi
        private static byte[] CopyStream(Deployment.WindowsInstaller.Record record, int index)
        {
            using (var ms = new MemoryStream())
            {
                var buffer = new byte[4096];
                int read   = 0;
                var stream = record.GetStream(index);

                do
                {
                    read = stream.Read(buffer, 0, buffer.Length);
                    if (0 < read)
                    {
                        ms.Write(buffer, 0, read);
                    }
                }while (0 < read);

                return(ms.ToArray());
            }
        }
예제 #18
0
        /// <summary>
        /// Called when a new action starts.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing additional information.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnActionStart(Deployment.WindowsInstaller.Record record)
        {
            if (this.progress.IsValid)
            {
                var current = this.progress.Current;

                if (current.EnableActionData)
                {
                    current.EnableActionData = false;
                }

                if (current.GeneratingScript)
                {
                    this.progress.CurrentAction = Resources.Action_GeneratingScript;
                }
                else if (null != record && 2 < record.FieldCount)
                {
                    var action = record.GetString(1);
                    Debug.Assert(!string.IsNullOrEmpty(action), "Action should not be null at this point");

                    this.progress.CurrentAction         = record.GetString(2);
                    this.progress.CurrentActionTemplate = record.GetString(3);

                    // Use current culture resources if ActionText is missing or doesn't match the current culture.
                    var culture = this.progress.CurrentCulture ?? CultureInfo.InvariantCulture;
                    if (string.IsNullOrEmpty(this.progress.CurrentAction) || !culture.Equals(CultureInfo.CurrentCulture))
                    {
                        this.progress.CurrentAction = ActionText.GetActionText(action) ?? string.Empty;
                    }

                    if (string.IsNullOrEmpty(this.progress.CurrentActionTemplate) || !culture.Equals(CultureInfo.CurrentCulture))
                    {
                        this.progress.CurrentActionTemplate = ActionText.GetActionData(action);
                    }
                }
            }

            return(MessageResult.OK);
        }
예제 #19
0
        /// <summary>
        /// Provides information about the install session.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing common details.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnCommonData(Deployment.WindowsInstaller.Record record)
        {
            // Get the current session language and Windows Installer-generated caption.
            if (1 < record.FieldCount)
            {
                var subtype = record.GetInteger(1);
                if (0 == subtype)
                {
                    var langId = record.GetInteger(2);
                    if (0 != langId)
                    {
                        this.progress.CurrentCulture = CultureInfo.GetCultureInfo(langId);
                    }
                }
                else if (1 == subtype)
                {
                    this.progress.CurrentName = record.GetString(2);
                }
            }

            return(MessageResult.OK);
        }
예제 #20
0
        private PSInstallerException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            // ErrorRecord is cache only.
            this.errorRecord = null;

            int fieldCount = (int)info.GetValue(PSInstallerException.FieldCount, typeof(int));
            if (0 < fieldCount)
            {
                this.record = new Deployment.WindowsInstaller.Record(fieldCount);
                for (int i = 0; i <= fieldCount; ++i)
                {
                    string name = PSInstallerException.FieldPrefix + i.ToString(CultureInfo.InvariantCulture);
                    string value = (string)info.GetValue(name, typeof(string));

                    this.record.SetString(i, value);
                }
            }
            else
            {
                this.record = null;
            }
        }
예제 #21
0
        public void ValidateErrorRecordForFusion()
        {
            using (var record = new Deployment.WindowsInstaller.Record(6))
            {
                record.SetInteger(1, 1935);
                record.SetString(2, "TestComponent");
                record.SetInteger(3, unchecked ((int)0x80070005));
                record.SetString(4, "ITestInterface");
                record.SetString(5, "TestFunction");
                record.SetString(6, "TestAssembly");

                using (var ex = new PSInstallerException(record))
                {
                    var error = ex.ErrorRecord;
                    Assert.IsNotNull(error);
                    Assert.AreEqual("TestAssembly", error.TargetObject as string, true);

                    var info = error.CategoryInfo;
                    Assert.IsNotNull(info);
                    Assert.AreEqual(ErrorCategory.InvalidData, info.Category);
                }
            }
        }
예제 #22
0
        private PSInstallerException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
            // ErrorRecord is cache only.
            this.errorRecord = null;

            int fieldCount = (int)info.GetValue(PSInstallerException.FieldCount, typeof(int));

            if (0 < fieldCount)
            {
                this.record = new Deployment.WindowsInstaller.Record(fieldCount);
                for (int i = 0; i <= fieldCount; ++i)
                {
                    string name  = PSInstallerException.FieldPrefix + i.ToString(CultureInfo.InvariantCulture);
                    string value = (string)info.GetValue(name, typeof(string));

                    this.record.SetString(i, value);
                }
            }
            else
            {
                this.record = null;
            }
        }
예제 #23
0
        /// <summary>
        /// Handles a message <see cref="Deployment.WindowsInstaller.Record"/> from Windows Installer.
        /// </summary>
        /// <param name="messageType">The <see cref="InstallMessage"/> type of the message.</param>
        /// <param name="messageRecord">The <see cref="Deployment.WindowsInstaller.Record"/> containing more information.</param>
        /// <param name="buttons">the <see cref="MessageButtons"/> to display.</param>
        /// <param name="icon">The <see cref="MessageIcon"/> to display.</param>
        /// <param name="defaultButton">The <see cref="MessageDefaultButton"/> to display.</param>
        /// <returns>The <see cref="MessageResult"/> that informs Windows Installer was action to take in response to the message.</returns>
        protected MessageResult OnMessage(InstallMessage messageType, Deployment.WindowsInstaller.Record messageRecord, MessageButtons buttons, MessageIcon icon, MessageDefaultButton defaultButton)
        {
            // Log all messages in debug mode.
            this.WriteMessage(messageType, messageRecord);

            switch (messageType)
            {
            case InstallMessage.Initialize:
                return(this.OnInitialize(messageRecord));

            case InstallMessage.ActionStart:
                return(this.OnActionStart(messageRecord));

            case InstallMessage.ActionData:
                return(this.OnActionData(messageRecord));

            case InstallMessage.Error:
            case InstallMessage.FatalExit:
            case InstallMessage.OutOfDiskSpace:
                return(this.OnError(messageRecord));

            case InstallMessage.Warning:
                return(this.OnWarning(messageRecord));

            case InstallMessage.Info:
            case InstallMessage.User:
                return(this.OnVerbose(messageRecord));

            case InstallMessage.Progress:
                return(this.OnProgress(messageRecord));

            case InstallMessage.CommonData:
                return(this.OnCommonData(messageRecord));
            }

            return(MessageResult.None);
        }
예제 #24
0
            private void TestProgressPhase3()
            {
                // With product name, estimated tick count, executing script.
                using (var rec = new Deployment.WindowsInstaller.Record(4))
                {
                    // CommonData: set CurrentProductName.
                    rec.SetInteger(1, 1);
                    rec.SetString(2, "INSTALL");
                    this.OnMessage(InstallMessage.CommonData, rec);

                    // Progress: master reset.
                    rec.SetInteger(1, 0);   // Master reset.
                    rec.SetInteger(2, 100); // Total.
                    rec.SetInteger(3, 0);   // Forward.
                    rec.SetInteger(4, 0);   // Executing script.
                    this.OnMessage(InstallMessage.Progress, rec);

                    // ActionStart: set CurrentAction.
                    rec.FormatString = "Action: [1]: [2]";
                    rec.SetString(1, "Time");
                    rec.SetString(2, "Testing");
                    rec.SetString(3, null);
                    this.OnMessage(InstallMessage.ActionStart, rec);

                    // Progress: update progress.
                    rec.SetInteger(1, 1);  // update progress.
                    rec.SetInteger(2, 50); // Step.
                    rec.SetInteger(3, 1);  // Enable ActionData.
                    this.OnMessage(InstallMessage.Progress, rec);

                    // ActionData: set CurrentActionDetail and step progress.
                    rec.FormatString = "Testing: [1]";
                    rec.SetString(1, "ActionData");
                    this.OnMessage(InstallMessage.ActionData, rec);
                }
            }
예제 #25
0
        private void WriteMessage(InstallMessage type, Deployment.WindowsInstaller.Record record)
        {
            var sb = new StringBuilder();

            sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ({0:d})", type);

            if (null != record)
            {
                sb.Append(": ");

                // Show field 0 (format string) as well.
                for (int i = 0; i <= record.FieldCount; ++i)
                {
                    if (0 != i)
                    {
                        sb.Append(", ");
                    }

                    sb.AppendFormat(CultureInfo.InvariantCulture, "{0}: {1}", i, record.GetString(i));
                }
            }

            this.WriteDebug(sb.ToString());
        }
예제 #26
0
 /// <summary>
 /// Creates a <see cref="PSInstallerException"/> from the given <paramref name="record"/>.
 /// </summary>
 /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing error details.</param>
 public PSInstallerException(Deployment.WindowsInstaller.Record record)
 {
     this.errorRecord = null;
     this.record = record;
 }
예제 #27
0
 /// <summary>
 /// Creates a <see cref="PSInstallerException"/> from the given <paramref name="record"/>.
 /// </summary>
 /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing error details.</param>
 public PSInstallerException(Deployment.WindowsInstaller.Record record)
 {
     this.errorRecord = null;
     this.record      = record;
 }
예제 #28
0
 /// <summary>
 /// Creates a <see cref="PSInstallerException"/> from the given inner exception.
 /// </summary>
 /// <param name="innerException">The <see cref="InstallerException"/> containing error details.</param>
 public PSInstallerException(InstallerException innerException) : base(null, innerException)
 {
     this.errorRecord = null;
     this.record      = null;
 }
예제 #29
0
        public void ValidateErrorRecordForFusion()
        {
            using (var record = new Deployment.WindowsInstaller.Record(6))
            {
                record.SetInteger(1, 1935);
                record.SetString(2, "TestComponent");
                record.SetInteger(3, unchecked((int)0x80070005));
                record.SetString(4, "ITestInterface");
                record.SetString(5, "TestFunction");
                record.SetString(6, "TestAssembly");

                using (var ex = new PSInstallerException(record))
                {
                    var error = ex.ErrorRecord;
                    Assert.IsNotNull(error);
                    Assert.AreEqual("TestAssembly", error.TargetObject as string, true);

                    var info = error.CategoryInfo;
                    Assert.IsNotNull(info);
                    Assert.AreEqual(ErrorCategory.InvalidData, info.Category);
                }
            }
        }
예제 #30
0
        public void ValidateErrorRecordOpenError()
        {
            using (var record = new Deployment.WindowsInstaller.Record(2))
            {
                record.SetInteger(1, 1301);
                record.SetString(2, @"C:\test.txt");

                using (var ex = new PSInstallerException(record))
                {
                    var error = ex.ErrorRecord;
                    Assert.IsNotNull(error);
                    Assert.AreEqual(@"C:\test.txt", error.TargetObject as string, true);

                    var info = error.CategoryInfo;
                    Assert.IsNotNull(info);
                    Assert.AreEqual(ErrorCategory.WriteError, info.Category);
                }
            }
        }
예제 #31
0
 /// <summary>
 /// Creates a <see cref="PSInstallerException"/> from the given inner exception.
 /// </summary>
 /// <param name="innerException">The <see cref="InstallerException"/> containing error details.</param>
 public PSInstallerException(InstallerException innerException)
     : base(null, innerException)
 {
     this.errorRecord = null;
     this.record = null;
 }
예제 #32
0
 private void OnMessage(InstallMessage type, Deployment.WindowsInstaller.Record record = null)
 {
     this.OnMessage(type, record, MessageButtons.OKCancel, MessageIcon.None, MessageDefaultButton.Button1);
 }
예제 #33
0
파일: Record.cs 프로젝트: skyhoshi/psmsi
        /// <summary>
        /// Initializes a new instance of the <see cref="Record"/> class.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> from which to copy values.</param>
        /// <param name="columns">The <see cref="ColumnCollection"/> for a <see cref="Deployment.WindowsInstaller.View"/>.</param>
        /// <param name="transform">The <see cref="TransformView"/> containing information about operations performed on this record.</param>
        /// <param name="path">The path to the package that contains the record.</param>
        internal Record(Deployment.WindowsInstaller.Record record, ColumnCollection columns, TransformView transform = null, string path = null)
        {
            // Internal constructor will assume valid parameters.

            // Shared reference to the column collection.
            this.Columns = columns;

            this.Path = path;

            // Cache the data from the record.
            var primaryKeys = new List <string>();

            this.Data = new List <object>(columns.Count);
            for (int i = 0; i < columns.Count; ++i)
            {
                // Windows Installer uses 1-based indices.
                var offset = i + 1;

                var type = columns[i].Type;
                if (type.IsEnum)
                {
                    var value = record.GetNullableInteger(offset);
                    this.Data.Add(new AttributeColumn(type, value));

                    if (columns[i].IsPrimaryKey)
                    {
                        primaryKeys.Add(null != value ? value.Value.ToString(CultureInfo.InvariantCulture) : string.Empty);
                    }
                }
                else if (typeof(Stream) == type)
                {
                    var buffer = CopyStream(record, offset);
                    this.Data.Add(buffer);

                    // Binary column types cannot be primary keys.
                }
                else
                {
                    var data = record[offset];
                    this.Data.Add(data);

                    if (columns[i].IsPrimaryKey)
                    {
                        primaryKeys.Add(null != data ? data.ToString() : string.Empty);
                    }
                }
            }

            if (0 < primaryKeys.Count)
            {
                this.PrimaryKey = primaryKeys.Join(Record.KeySeparator);
            }

            // Can only reliably get row operations performed on rows in a single table.
            if (null != transform && 1 == columns.TableNames.Count())
            {
                var tableName = columns.TableNames[0];
                this.Operation = transform.GetRowOperation(tableName, this.PrimaryKey);
            }
            else
            {
                this.Operation = RowOperation.None;
            }
        }
예제 #34
0
        /// <summary>
        /// Writes progress information.
        /// </summary>
        /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing the progress details.</param>
        /// <returns>The result code indicating how Windows Installer should proceed.</returns>
        protected MessageResult OnProgress(Deployment.WindowsInstaller.Record record)
        {
            if (null == record || 2 > record.FieldCount)
            {
                return(MessageResult.None);
            }

            switch (record.GetInteger(1))
            {
            // Add a new phase of progress information.
            case 0:
                if (4 > record.FieldCount)
                {
                    // Invalid message.
                    break;
                }

                // Add a new phase of progress.
                var current = this.progress.Add();

                current.Forward          = 0 == record.GetInteger(3);
                current.Total            = record.GetInteger(2);
                current.Complete         = current.Forward ? 0 : current.Total;
                current.EnableActionData = false;
                current.GeneratingScript = 1 == record.GetInteger(4);

                // Windows Installer team advises to add ~50 ticks to script generation.
                if (0 == this.progress.CurrentIndex)
                {
                    current.Total += 50;
                }

                break;

            // Update progress information.
            case 1:
                if (3 > record.FieldCount)
                {
                    // Invalid message.
                    break;
                }
                else if (!this.progress.IsValid)
                {
                    // Progress not initialized.
                    break;
                }

                if (0 == record.GetInteger(3))
                {
                    this.progress.Current.EnableActionData = false;
                }
                else
                {
                    this.progress.Current.EnableActionData = true;
                    this.progress.Current.Step             = record.GetInteger(2);
                }

                break;

            // Report progress information.
            case 2:
                if (!this.progress.IsValid || 0 == this.progress.Current.Total)
                {
                    // Progress not initialized.
                    break;
                }

                // Adjust the current progress.
                if (this.progress.Current.Forward)
                {
                    this.progress.Current.Complete += record.GetInteger(2);
                }
                else
                {
                    this.progress.Current.Complete -= record.GetInteger(2);
                }

                break;

            // Expand the total.
            case 3:
                if (!this.progress.IsValid)
                {
                    // Progress not initialized.
                    break;
                }

                // Expand the progress maximum.
                this.progress.Current.Total += record.GetInteger(2);
                break;

            default:
                return(MessageResult.None);
            }

            this.WriteProgress();
            return(MessageResult.OK);
        }
예제 #35
0
 /// <summary>
 /// Initializes the execution state.
 /// </summary>
 /// <param name="record">The <see cref="Deployment.WindowsInstaller.Record"/> containing additional information.</param>
 /// <returns>The result code indicating how Windows Installer should proceed.</returns>
 protected MessageResult OnInitialize(Deployment.WindowsInstaller.Record record)
 {
     this.Reset();
     return(MessageResult.OK);
 }