我使用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);
}
}
答案 0 :(得分:0)
尝试以下任何可行的方法,我没有尝试使用您的代码,但过去我们遇到了类似的问题。
选项1:在代码this.WireUpEventHandlers();
尝试将代码置于代码之后,如果没有调用它,它应调用您的DetectPackageComplete事件。
this.model.BootstrapperApplication.Engine.Detect();
选项2:在DetectPackageComplete事件中,包ID应该是“MyInstaller”而不是“MyInstaller.msi”,因为我假设您在bundle.wxs中给出了Id =“MyInstaller”
希望这有帮助。