1

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

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

        ActionResult result = ActionResult.Success;
        return result;

    }

我需要使用 InstallShield 创建的延迟/系统上下文自定义操作调用它,那么如何设置方法签名参数以便它发送会话?'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)
4

3 回答 3

1

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

于 2013-10-27T13:14:50.717 回答
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 的魅力。希望这对某人有所帮助。

于 2013-11-04T14:32:31.677 回答
0

我的答案是 wrt 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;而是传递字符串

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

于 2017-06-16T06:08:10.230 回答