Wix Csharp自定义操作未被触发

时间:2018-03-20 07:49:50

标签: c# visual-studio wix

Wix Toolset 3.10

Visual Studio 2010(使用Visual Studio 2010的Wix工具集扩展https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2010Extension

目前我想制作一个SQL Server自定义安装程序,调用Setup.exe为每个客户提供产品代码和几乎固定的条件......

可能与调用此类批处理文件相同......

  

E:\Setup.exe /Action=Install /Q /IACCEPTSQLSERVERLICENSETERMS /SECURITYMODE=SQL /SAPWD=hoge_for_fuga /InstanceName=MSSQLSERVER /UpdateEnabled=True /FEATURES=SQLEngine,FullText /INSTANCEDIR="D:\Program Files\Microsoft SQL Server" /INSTALLSHAREDDIR="D:\Program Files\Microsoft SQL Server" /INSTALLSHAREDWOWDIR="D:\Program Files (x86)\Microsoft SQL Server" /AGTSVCACCOUNT="NT AUTHORITY\SYSTEM" /AGTSVCSTARTUPTYPE="Automatic" /SQLCOLLATION="Japanese_CI_AS" /SQLSVCACCOUNT="NT AUTHORITY\SYSTEM" /SQLSYSADMINACCOUNTS="{localmachine}\Administrator" >>SQLINSTALLRESULT.txt

抱歉,最终目标与当前问题无关。

对于浏览setup.exe的用户,我已经阅读了一篇关于Csharp dll File Browse Dialog in Wix Installer的文件浏览对话的文章。如果我理解正确,Wix提供“文件夹浏览器”,但不提供“文件浏览器”,但是我没有调用dll方法。安装程序不输出错误,按“浏览...”按钮不响应,鼠标光标将其形状更改为滚动循环...等待一晚后,任务管理器强制终止只停止msiexec进程... < / p>

以下是csharp和wsx文件的代码...... CallSQLSvrInstallDlg.wxs

~Snip~

<Binary Id="CustomAction1.CA.dll" SourceFile="SourceDir\CustomAction1.CA.dll" />
<CustomAction Id="OpenFileChooser" Return="check" Execute="immediate" BinaryKey="CustomAction1.CA.dll" DllEntry="OpenFileChooser" />

~Snip~

<!-- this property links to the UI SQLSvrInstanceDlg defined -->
<Property Id="SETUPEXEPATH" Secure="yes" Value="hogehoge" />


<UI Id="MyWixUI_FeatureTree">
  <UIRef Id="WixUI_FeatureTree" />

  <DialogRef Id="SQLSvrInstanceDlg" />
  <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="SQLSvrInstanceDlg" Order="2">
    1
  </Publish>
  <Publish Dialog="SQLSvrInstanceDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">
    1
  </Publish>
  <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="SQLSvrInstanceDlg" Order="2">
    1
  </Publish>
</UI>

~Snip~

SQLSvrInstanceDlg.wxs

~Snip~

<Property Id="ONOFF_PROPERTY" Secure="yes" Value="0" />
<UI>
  <Dialog Id="SQLSvrInstanceDlg"
          Width="420" Height="270"
          Title="[ProductName] [Setup]" NoMinimize="yes">
    <Control Id="RdxOnlineOffline2" Type="RadioButtonGroup" X="40" Y="63" Width="350" Height="35" Property="ONOFF_PROPERTY" Text="Choose Instance:">
        <RadioButtonGroup Property="ONOFF_PROPERTY">
                 <RadioButton Value="0" X="0" Y="0" Width="300" Height="15" Text="Use Existing Instance" />
                 <RadioButton Value="1" X="0" Y="20" Width="300" Height="15" Text="Create New Instance" />
        </RadioButtonGroup>
    </Control>
    <Control Id="SetupFile" Type="Text"
             X="45" Y="98" Width="200" Height="15"
             TabSkip="no" Text="Setup File(&amp;U):" />

    <Control Type="Edit" Id="TxtExe" X="45" Y="110" Width="220" Height="18" Property="SETUPEXEPATH" Indirect="yes">
             <Condition Action="disable"><![CDATA[ONOFF_PROPERTY <> "1"]]></Condition>
             <Condition Action="enable"><![CDATA[ONOFF_PROPERTY = "1"]]></Condition>
    </Control>
    <Control Id="ChangeFolder" Type="PushButton" X="265" Y="110" Width="56" Height="18" Text="Browser...">
             <Condition Action="disable"><![CDATA[ONOFF_PROPERTY <> "1"]]></Condition>
             <Condition Action="enable"><![CDATA[ONOFF_PROPERTY = "1"]]></Condition>
             <Publish Event="DoAction" Value="OpenFileChooser">1</Publish>
    </Control>

~Snip~


</UI>

CustomAction.cs(CustomAction1.CA.dll)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WinForms = System.Windows.Forms;
using System.IO;
using Microsoft.Deployment.WindowsInstaller;

public class CustomActions
{
    [CustomAction]
    public static ActionResult OpenFileChooser(Session session)
    {
        try
        {
            session.Log("Begin OpenFileChooser Custom Action");
            GetFile(session);
            session.Log("End OpenFileChooser Custom Action");
        }
        catch (Exception ex)
        {
            session.Log("Exception occurred as Message: {0}\r\n StackTrace: {1}", ex.Message, ex.StackTrace);
            return ActionResult.Failure;
        }
        return ActionResult.Success;
    }

    private static void GetFile(Session session)
    {
        var fileDialog = new WinForms.OpenFileDialog { Filter = "Text File (*.txt)|*.txt" };
        if (fileDialog.ShowDialog() == WinForms.DialogResult.OK)
        {
            session["SETUPEXEPATH"] = fileDialog.FileName;
        }
    }

}

我把CustomAction1.CA.dll放到msi安装程序文件的同一目录下,出了什么问题?

P.S.1根据@Towel的建议,我使用Thread操作更改了Csharp CA代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WinForms = System.Windows.Forms;
using System.IO;
using Microsoft.Deployment.WindowsInstaller;
using System.Threading;

public class CustomActions
{
    [CustomAction]
    public static ActionResult OpenFileChooser(Session session)
    {
        try
        {
            session.Log("Begin OpenFileChooser Custom Action");
            var task = new Thread(() => GetFile(session));
            task.SetApartmentState(ApartmentState.STA);
            task.Start();
            task.Join();
            session.Log("End OpenFileChooser Custom Action");
        }
        catch (Exception ex)
        {
            session.Log("Exception occurred as Message: {0}\r\n StackTrace: {1}", ex.Message, ex.StackTrace);
            return ActionResult.Failure;
        }
        return ActionResult.Success;
    }

    private static void GetFile(Session session)
    {
        var fileDialog = new WinForms.OpenFileDialog { Filter = "Text File (*.txt)|*.txt" };
        if (fileDialog.ShowDialog() == WinForms.DialogResult.OK)
        {
            session["SETUPEXEPATH"] = fileDialog.FileName;
        }
    }

}

但结果是一样的。 Wix详细日志片段如下:

{Snip}
Action 11:55:11: WelcomeDlg. 
Action start 11:55:11: WelcomeDlg.
Action 11:55:11: WelcomeDlg. Dialog created
MSI (c) (A0:24) [11:55:11:356]: Note: 1: 2205 2:  3: _RemoveFilePath 
MSI (c) (A0:24) [11:55:11:362]: PROPERTY CHANGE: Modifying CostingComplete property. Its current value is '0'. Its new value: '1'.
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: Registry 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: BindImage 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: ProgId 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: PublishComponent 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: SelfReg 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: Extension 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: Font 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: Shortcut 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: Class 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: Icon 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2205 2:  3: TypeLib 
MSI (c) (A0:24) [11:55:11:362]: Note: 1: 2727 2:  
MSI (c) (A0:20) [11:55:21:648]: Note: 1: 2205 2:  3: Error 
MSI (c) (A0:20) [11:55:21:648]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 2898 
Info 2898.For WixUI_Font_Title textstyle, the system created a 'Tahoma' font, in 128 character set, of 14 pixels height.
Action 11:55:21: SQLSvrInstanceDlg. Dialog created
MSI (c) (A0:20) [11:55:23:957]: PROPERTY CHANGE: Modifying ONOFF_PROPERTY property. Its current value is '0'. Its new value: '1'.
MSI (c) (A0:20) [11:55:25:397]: Doing action: OpenFileChooser
MSI (c) (A0:20) [11:55:25:397]: Note: 1: 2205 2:  3: ActionText 
Action 11:55:25: OpenFileChooser. 
Action start 11:55:25: OpenFileChooser.
MSI (c) (A0:F0) [11:55:25:460]: Invoking remote custom action. DLL: C:\Users\{LogonName}\AppData\Local\Temp\MSIBF1D.tmp, Entrypoint: OpenFileChooser
MSI (c) (A0:90) [11:55:25:462]: Cloaking enabled.
MSI (c) (A0:90) [11:55:25:462]: Attempting to enable all disabled privileges before calling Install on Server
MSI (c) (A0:90) [11:55:25:462]: Connected to service 

明天我将在互联网上发布整个日志文件。 可能我犯了另一个简单的错误,我应该再次阅读文章https://blogs.msdn.microsoft.com/jschaffe/2012/10/23/creating-wix-custom-actions-in-c-and-passing-parameters/ ....

我上传了详细的日志文件... https://drive.google.com/file/d/1FOnhwU8LWmntuoMIT6LlrXEN_EFRp8-U/view?usp=sharing 任何帮助将不胜感激。

Visual Studio 2010 Solution Explorer

1 个答案:

答案 0 :(得分:1)

当我在我的环境中手动将dll复制并粘贴到msi文件夹时,似乎Binary SourceFile属性=“SourceDir \ CustomAction1.CA.dll”无法正常工作。 (我只想让目录结构变得简单)因为msi就好像它找不到dll一样......即使我删除了文件夹中的dll文件,msi也能正常工作。

在WiX邮件列表中,Ronny Eriksson先生告诉我,可以使用表达式语法“$(var.CustomAction.TargetDir)”将dll合并到MSI文件中成功按“浏览器”按钮打开文件资源管理器,触发JIT调试器我在我的Csharp代码中加入了System.Diagnostics.Debugger.Break。

下面是重写的CallSQLSvrInstallDlg.wxs ......

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <Product Id="*" Name="My Service" Manufacturer="Company Name" UpgradeCode="MY-UID" Language="1033" Codepage="1252" Version="1.0.0">
    <Package Id="*" Description="My Service Installer" Manufacturer="Company Name" InstallerVersion="200" Languages="1033" Compressed="yes" SummaryCodepage="1252" Platform="x64" InstallScope="perMachine" />

    ~Snip~

    <Binary Id="CustomAction1.CA.dll" SourceFile="$(var.CustomAction1.TargetDir)CustomAction1.CA.dll" />

    <CustomAction Id="OpenFileChooser" Return="check" Execute="immediate" BinaryKey="CustomAction1.CA.dll" DllEntry="OpenFileChooser" />
    <!--<CustomAction Id="OpenFileChooser" Execute="firstSequence" BinaryKey="CustomAction1.CA.dll" DllEntry="OpenFileChooser" />-->

    ~Snip~

    <!-- this property links the UI InstallDir chooser to the destination location defined -->
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />

    <!-- this property links to the UI SQLSvrInstanceDlg defined -->
    <Property Id="SETUPEXEPATH" Secure="yes" Value="hogehoge" />

    <!-- depending on what components you want, you may need to add additional features to this command line -->
    <InstallExecuteSequence>
    </InstallExecuteSequence>

    <UI Id="MyWixUI_FeatureTree">
      <UIRef Id="WixUI_FeatureTree" />

      <DialogRef Id="SQLSvrInstanceDlg" />
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="SQLSvrInstanceDlg" Order="2">
        1
      </Publish>
      <Publish Dialog="SQLSvrInstanceDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">
        1
      </Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="SQLSvrInstanceDlg" Order="2">
        1
      </Publish>
    </UI>
  </Product>

    ~Snip~


  </Wix>

我仍然无法重用Csharp会话[“SETUPEXEPATH”]的返回值,但我挑战自己解决这个问题......

P.S.在阅读Set edit control text value from custom action with WIX之后,我略微更改了SQLSvrInstanceDlg.wxs以显示返回的编辑文本框的完整路径。

~Snip~
<UI>
~Snip~

        <Control Id="ChangeSetupExePath" Type="PushButton" X="265" Y="110" Width="56" Height="18" Text="Browser...">
                 <Condition Action="disable"><![CDATA[ONOFF_PROPERTY <> "1"]]></Condition>
                 <Condition Action="enable"><![CDATA[ONOFF_PROPERTY = "1"]]></Condition>
                 <Publish Event="DoAction" Value="OpenFileChooser">1</Publish>
                 <Publish Property="SETUPEXEPATH" Value="[SETUPEXEPATH]"><![CDATA[1]]></Publish>
        </Control>

~Snip~
</UI>
~Snip~