如何使用InstallShield将“Session”参数传递给我的WiX自定义操作?

时间:2013-10-27 06:52:37

标签: wix installshield custom-action

我有简单的WiX(Microsoft.Deployment.WindowsInstaller)自定义操作:

    [CustomAction]
    public static ActionResult TestDtf(Session session)
    {
        MessageBox.Show("Test");

        ActionResult result = ActionResult.Success;
        return result;

    }

我需要使用InstallShield调用它创建一个延迟/系统上下文自定义操作,那么如何设置Method Signature参数以便它发送Session? 'Session'基本上是Msi句柄吗?我尝试过使用'MsiHandle'值,但这会导致错误:

InstallShield: Deferred action requested property MsiHiddenProperties not provided by CustomActionData
InstallShield: Loading assembly Test.Installation.CustomActions from resource 4098
InstallShield: Loading Assembly Microsoft.Deployment.WindowsInstaller
InstallShield: Unexpected parameter type Microsoft.Deployment.WindowsInstaller.Session encountered; passing string instead
InstallShield: Calling method with parameters [(System.String)294]
InstallShield: Exception: System.ArgumentException: Object of type 'System.String' cannot be converted to type 'Microsoft.Deployment.WindowsInstaller.Session'.
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at InstallShield.ClrHelper.CustomActionHelper.CallMethod(EntryPointInfo info)

3 个答案:

答案 0 :(得分:1)

你没有,因为你不需要。您正在InstallShield中创建错误的自定义操作。假装你的DLL不是.NET,因为就DTF而言,它并非如此。它已被封装为本机DLL。

答案 1 :(得分:1)

这个问题的答案是改变我添加到MSI DLL的DLL CA的类型。然后它只询问函数名称而不是参数和返回值。不幸的是,我无法在网上找到这个很容易解释的内容,并且需要一些猜测。以下是您的方法签名应该是什么样的。

[CustomAction]
  public static ActionResult VerifyCA( Session session )
  {
     //Record record = new Record( 2 );
     //record[0] = "[1]";
     //record[1] = "Testing Wix message";
     //session.Message( InstallMessage.Error, record );

     return ActionResult.Failure;
  }

选择正确的CA类型后,它就像Installshield 2009中的魅力一样。希望这对某人有所帮助。

答案 2 :(得分:0)

我的回答是w.r.t. Installshiled 2016并且在所有可能的情况下它必须在早期的installshield版本中以相同的方式工作,但我没有验证相同。

是。内置MsiHandle变量是正在进行的安装的会话,但它需要一行额外的代码才能在C#端获得。我能够在.Net程序集中实现它,我从托管的自定义操作中调用它。代码如下:

//import this namespace at the top of your *.cs file
using Microsoft.Deployment.WindowsInstaller;

public static int MakeChangesInCurrentInstallSession(IntPtr hMsi)
{
    Session session = Session.FromHandle(hMsi, false);

    view = session.Database.OpenView("SELECT * FROM ComboBox");
    view.Execute();
    //do other things whatever you want to do in the installer session
    //Record record = session.Database.CreateRecord(4);
    //view.Modify(....);
    //.....
    //return success if everything went well
    return (int)ActionResult.Success;
}

如果您对方法进行了如下签名,并尝试从托管自定义操作中调用它:

public static int MakeChangesInCurrentInstallSession(Session hMsi)

然后,您将面临如下的投射错误:

  

InstallShield:意外的参数类型   遇到Microsoft.Deployment.WindowsInstaller.Session;通过   改为字符串

注意:要使上述代码生效,您将在添加引用窗口的扩展选项卡中添加对C#项目中Microsoft.Deployment.WindowsInstaller.dll的引用。此外,由于此程序集不是.Net框架的一部分,因此您必须将此程序集作为详细here的installshield执行序列的托管自定义操作中的依赖项添加。