代码之家  ›  专栏  ›  技术社区  ›  JohnZaj

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

  •  1
  • JohnZaj  · 技术社区  · 11 年前

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

        [CustomAction]
        public static ActionResult TestDtf(Session session)
        {
            MessageBox.Show("Test");
    
            ActionResult result = ActionResult.Success;
            return result;
    
        }
    

    我需要使用InstallShield创建一个延迟/系统上下文自定义操作来调用这个,那么我如何设置方法签名参数,以便它发送会话呢?“会话”基本上是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 回复  |  直到 11 年前
        1
  •  1
  •   Christopher Painter    11 年前

    你没有,因为你不需要。你在InstallShield中创建了错误类型的自定义操作。假设你的DLL不是.NET,因为就DTF而言,它不是。它已被封装为本机DLL。

        2
  •  1
  •   Jay McMunn    11 年前

    对我来说,这个问题的答案是更改我添加到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的魅力。希望这能帮助到别人。

        3
  •  0
  •   RBT    5 年前

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

    对内置的 MsiHandle variable是正在进行的安装的会话,但它需要一行额外的代码才能在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;经过 字符串

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