在WIX

时间:2018-01-16 15:19:25

标签: c# installation wix custom-action wix3.11

我有一个带有Edit控件的自定义用户界面,我想用按钮点击调用的c#自定义操作来更新它。

这是我创建的测试WIX片段,用于演示您的问题,它包含UI和自定义操作声明。

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <UI>
      <Dialog Id="TestDlg" Width="370" Height="270">
        <Control Id="TextBox" Type="Edit" X="80" Y="117" Height="17" Width="250"  Property="EDITBOXVALUE" Text="[EDITBOXVALUE]"/>
        <Control Id="Button" Type="PushButton" X="331" Y="117" Height="16" Width="17" Text="Update">
          <Publish Event="DoAction" Value="UpdateEditBox" Order="1">1</Publish>

          <!-- This is a workaround to update property I found here https://legalizeadulthood.wordpress.com/2009/10/23/ui-custom-action-guidelines/ -->
          <Publish Property="EDITBOXVALUE" Value="[EDITBOXVALUE]" Order="2">1</Publish>
        </Control>
      </Dialog>
    </UI>
    <Binary Id="ServerActions" SourceFile="$(var.CustomActions.TargetDir)$(var.CustomActions.TargetName).CA.dll" />
    <CustomAction Id="UpdateEditBox" BinaryKey="ServerActions" DllEntry="UpdateEditBox" Execute="immediate" Return="check" />
  </Fragment>
</Wix>

这是c#自定义操作:

[CustomAction]
public static ActionResult UpdateEditBox(Session session)
{
    session ["EDITBOXVALUE"] = "Updated Value";
    return ActionResult.Success;
}

现在这是我遇到的问题,如果我只是点击按钮,编辑框就会更新,但是,如果我先将一些文字放到编辑框中,那么点击按钮,编辑框就不再更新了。

我检查了安装日志(通过使用此命令运行安装程序msiexec.exe /i MyInstaller.msi /l*vx Output.txt),这是我发现的:

MSI (c) (FC!24) [17:13:41:225]: PROPERTY CHANGE: Adding EDITBOXVALUE property. Its value is 'Updated Value'.
MSI (c) (FC:44) [17:13:41:236]: Closing MSIHANDLE (1) of type 790542 for thread 9980
Action ended 17:13:41: UpdateEditBox. Return value 1.
MSI (c) (FC:FC) [17:13:44:521]: PROPERTY CHANGE: Modifying EDITBOXVALUE property. Its current value is 'Updated Value'. Its new value: 'NEW VALUE I TYPED INTO EDIT BOX'.
MSI (c) (FC:FC) [17:13:44:633]: Doing action: UpdateEditBox
Action 17:13:44: UpdateEditBox. 
Action start 17:13:44: UpdateEditBox.
MSI (c) (FC:FC) [17:13:44:635]: Creating MSIHANDLE (5) of type 790542 for thread 9980
MSI (c) (FC:6C) [17:13:44:635]: Invoking remote custom action. DLL: C:\Users\MYKHAI~1.SEN\AppData\Local\Temp\MSIAAE1.tmp, Entrypoint: UpdateEditBox
MSI (c) (FC!A0) [17:13:44:666]: Creating MSIHANDLE (6) of type 790531 for thread 27552
MSI (c) (FC!A0) [17:13:44:666]: Closing MSIHANDLE (6) of type 790531 for thread 27552
MSI (c) (FC!A0) [17:13:44:710]: Creating MSIHANDLE (7) of type 790531 for thread 27552
MSI (c) (FC!A0) [17:13:44:710]: Closing MSIHANDLE (7) of type 790531 for thread 27552
MSI (c) (FC!A0) [17:13:44:745]: Creating MSIHANDLE (8) of type 790531 for thread 27552
MSI (c) (FC!A0) [17:13:44:748]: Closing MSIHANDLE (8) of type 790531 for thread 27552
MSI (c) (FC!A0) [17:13:49:399]: PROPERTY CHANGE: Modifying EDITBOXVALUE property. Its current value is 'NEW VALUE I TYPED INTO EDIT BOX'. Its new value: 'Updated Value'.
MSI (c) (FC:6C) [17:13:49:425]: Closing MSIHANDLE (5) of type 790542 for thread 9980
Action ended 17:13:49: UpdateEditBox. Return value 1.
Action 17:13:52: CancelDlg. Dialog created
Action ended 17:13:53: WelcomeDlg. Return value 2.

基于此日志,似乎属性已更新,但未在UI上反映出来。

有谁知道这里发生了什么,我该如何解决?

1 个答案:

答案 0 :(得分:0)

这是我想出来解决这个问题的一个小技巧,不是很优雅,但它仍然有用。

主要思想是您拥有主对话框的精确副本,并且每当您想要更新UI时,当属性发生更改时,您只需在这两个副本之间切换。从问题中的例子来看,它会是这样的:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <UI>
      <Dialog Id="TestDlg" Width="370" Height="270">
        <Control Id="TextBox" Type="Edit" X="80" Y="117" Height="17" Width="250"  Property="EDITBOXVALUE" Text="[EDITBOXVALUE]"/>
        <Control Id="Button" Type="PushButton" X="331" Y="117" Height="16" Width="17" Text="Update">
          <Publish Event="DoAction" Value="UpdateEditBox" Order="1">1</Publish>
        </Control>
      </Dialog>
    </UI>
    <UI>
      <Dialog Id="TestCopyDlg" Width="370" Height="270">
        <Control Id="TextBox" Type="Edit" X="80" Y="117" Height="17" Width="250"  Property="EDITBOXVALUE" Text="[EDITBOXVALUE]"/>
        <Control Id="Button" Type="PushButton" X="331" Y="117" Height="16" Width="17" Text="Update">
          <Publish Event="DoAction" Value="UpdateEditBox" Order="1">1</Publish>
        </Control>
      </Dialog>
    </UI>
    <Binary Id="ServerActions" SourceFile="$(var.CustomActions.TargetDir)$(var.CustomActions.TargetName).CA.dll" />
    <CustomAction Id="UpdateEditBox" BinaryKey="ServerActions" DllEntry="UpdateEditBox" Execute="immediate" Return="check" />
  </Fragment>
</Wix>

请注意,我不再使用此<Publish Property="EDITBOXVALUE" Value="[EDITBOXVALUE]" Order="2">1</Publish>,因为我们不再需要它,因为我们正在切换到另一个用户界面。

然后在您的UI序列中的某个位置:

  <Publish Dialog="TestDlg" Control="Button" Event="NewDialog" Value="TestCopyDlg">1</Publish>
  <Publish Dialog="TestCopyDlg" Control="Button" Event="NewDialog" Value="TestDlg">1</Publish>