程序运行时未调用Wix PlanAction方法

时间:2016-04-09 14:17:01

标签: wpf mvvm wix prism bootstrapper

我使用Wix编写了一个bootstrapper安装程序。但是当我运行应用程序时,安装程​​序始终停留在"正在初始化"州。因此,禁用安装和卸载按钮。下面是我检查安装命令值的行。

 this.InstallCommand = new DelegateCommand(() =>
        model.PlanAction(LaunchAction.Install),
        () => this.State == InstallState.NotPresent);

当我调试代码时,不会调用model.PlanAction方法。即使我按下步骤,它也会运行此方法。此外,PlanAction方法的调试点未被命中。我在这做错了什么?下面是我的ViewModel类。

    public class InstallViewModel : NotificationObject
    {
        public enum InstallState
        {
            Initializing,
            Present,
            NotPresent,
            Applying,
            Cancelled
        }
        private InstallState state;
        private string message;
        private BootstrapperApplicationModel model;
        public ICommand InstallCommand { get; private set; }
        public ICommand UninstallCommand { get; private set; }
        public ICommand CancelCommand { get; private set; }
        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                if (this.message != value)
                {
                    this.message = value;
                    this.RaisePropertyChanged(() => this.Message);
                }
            }
        }
        public InstallState State
        {
            get
            {
                return this.state;
            }
            set
            {
                if (this.state != value)
                {
                    this.state = value;
                    this.Message = this.state.ToString();
                    this.RaisePropertyChanged(() => this.State);
                    this.Refresh();
                }
            }
        }
        public InstallViewModel(
        BootstrapperApplicationModel model)
        {
            this.model = model;
            this.State = InstallState.Initializing;
            this.WireUpEventHandlers();
            this.InstallCommand = new DelegateCommand(() =>
            this.model.PlanAction(LaunchAction.Install),
            () => this.State == InstallState.NotPresent);
            this.UninstallCommand = new DelegateCommand(() =>
            this.model.PlanAction(LaunchAction.Uninstall),
            () => this.State == InstallState.Present);
            this.CancelCommand = new DelegateCommand(() =>
        {
            this.model.LogMessage("Cancelling...");
            if (this.State == InstallState.Applying)
            {
                this.State = InstallState.Cancelled;
            }
            else
            {
                CustomBootstrapperApplication.Dispatcher
                .InvokeShutdown();
            }
        }, () => this.State != InstallState.Cancelled);
        }
        protected void DetectPackageComplete(
        object sender,
        DetectPackageCompleteEventArgs e)
        {
            if (e.PackageId.Equals(
        "MyInstaller.msi", StringComparison.Ordinal))
            {
                this.State = e.State == PackageState.Present ?
                    InstallState.Present : InstallState.NotPresent;
            }
        }
        protected void PlanComplete(
        object sender, PlanCompleteEventArgs e)
        {
            if (this.State == InstallState.Cancelled)
            {
                CustomBootstrapperApplication.Dispatcher
                .InvokeShutdown();
                return;
            }
            this.model.ApplyAction();
        }
        protected void ApplyBegin(
        object sender, ApplyBeginEventArgs e)
        {
            this.State = InstallState.Applying;
        }
        protected void ExecutePackageBegin(
        object sender, ExecutePackageBeginEventArgs e)
        {
            if (this.State == InstallState.Cancelled)
            {
                e.Result = Result.Cancel;
            }
        }
        protected void ExecutePackageComplete(
        object sender, ExecutePackageCompleteEventArgs e)
        {
            if (this.State == InstallState.Cancelled)
            {
                e.Result = Result.Cancel;
            }
        }
        protected void ApplyComplete(
        object sender, ApplyCompleteEventArgs e)
        {
            this.model.FinalResult = e.Status;
            CustomBootstrapperApplication.Dispatcher
            .InvokeShutdown();
        }
        private void Refresh()
        {
            CustomBootstrapperApplication.Dispatcher.Invoke(
            (Action)(() =>
            {
                ((DelegateCommand)this.InstallCommand)
                .RaiseCanExecuteChanged();
                ((DelegateCommand)this.UninstallCommand)
                .RaiseCanExecuteChanged();
                ((DelegateCommand)this.CancelCommand)
                .RaiseCanExecuteChanged();
            }));
        }
        private void WireUpEventHandlers()
        {
            this.model.BootstrapperApplication.DetectPackageComplete
            += this.DetectPackageComplete;
            this.model.BootstrapperApplication.PlanComplete += this.
        PlanComplete;
            this.model.BootstrapperApplication.ApplyComplete += this.
            ApplyComplete;
            this.model.BootstrapperApplication.ApplyBegin += this.
            ApplyBegin;
            this.model.BootstrapperApplication.ExecutePackageBegin +=
            this.ExecutePackageBegin;
            this.model.BootstrapperApplication.ExecutePackageComplete
            += this.ExecutePackageComplete;
        }
    }

下面是我的Model类,其中包含应该被调用的PlanAction方法。

  public class BootstrapperApplicationModel
    {
        private IntPtr hwnd;
        public BootstrapperApplicationModel(
        BootstrapperApplication bootstrapperApplication)
        {
            this.BootstrapperApplication =
            bootstrapperApplication;
            this.hwnd = IntPtr.Zero;
        }
        public BootstrapperApplication BootstrapperApplication
        {
            get;
            private set;
        }
        public int FinalResult { get; set; }
        public void SetWindowHandle(Window view)
        {
            this.hwnd = new WindowInteropHelper(view).Handle;
        }
        public void PlanAction(LaunchAction action)
        {
            this.BootstrapperApplication.Engine.Plan(action);
        }
        public void ApplyAction()
        {
            this.BootstrapperApplication.Engine.Apply(this.hwnd);
        }
        public void LogMessage(string message)
        {
            this.BootstrapperApplication.Engine.Log(
            LogLevel.Standard,
            message);
        }

以下是我的BootstrapperApplication类,以备不时之需。

public class CustomBootstrapperApplication :
BootstrapperApplication
    {
        public static Dispatcher Dispatcher { get; set; }
        protected override void Run()
        {
            Dispatcher = Dispatcher.CurrentDispatcher;
            var model = new BootstrapperApplicationModel(this);
            var viewModel = new InstallViewModel(model);
            var view = new InstallView(viewModel);
            model.SetWindowHandle(view);
            this.Engine.Detect();
            view.Show();
            Dispatcher.Run();
            this.Engine.Quit(model.FinalResult);
        }
    }

1 个答案:

答案 0 :(得分:0)

尝试以下任何可行的方法,我没有尝试使用您的代码,但过去我们遇到了类似的问题。

选项1:在代码this.WireUpEventHandlers();尝试将代码置于代码之后,如果没有调用它,它应调用您的DetectPackageComplete事件。

this.model.BootstrapperApplication.Engine.Detect();

选项2:在DetectPackageComplete事件中,包ID应该是“MyInstaller”而不是“MyInstaller.msi”,因为我假设您在bundle.wxs中给出了Id =“MyInstaller”

希望这有帮助。