Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wix 如何在不调用安装的情况下执行MSI中的自定义操作?_Wix_Windows Installer_Custom Action - Fatal编程技术网

Wix 如何在不调用安装的情况下执行MSI中的自定义操作?

Wix 如何在不调用安装的情况下执行MSI中的自定义操作?,wix,windows-installer,custom-action,Wix,Windows Installer,Custom Action,给定: Wix 3.0用于创建MSI 该产品由多个功能部件组成 每个特征都有几个子特征。这是一个标准的MSI功能树 每个特征或子特征都依赖于多个外部组件。 例如,NET4、ASP.NET等 使用Wix 3.0 SDK以C#编写的自定义操作处理这些 依赖项,并计算是否存在组件 给定的一组特性 在安装时,如果给定时间缺少从属组件 选择功能,安装失败 要实现的目标: 能够执行先决条件检查,这在安装期间已作为自定义操作在MSI中完成,而无需在给定计算机上安装MSI 尝试失败: 1) 自定义操作具有如下函

给定:

  • Wix 3.0用于创建MSI
  • 该产品由多个功能部件组成
  • 每个特征都有几个子特征。这是一个标准的MSI功能树
  • 每个特征或子特征都依赖于多个外部组件。 例如,NET4、ASP.NET等
  • 使用Wix 3.0 SDK以C#编写的自定义操作处理这些 依赖项,并计算是否存在组件 给定的一组特性
  • 在安装时,如果给定时间缺少从属组件 选择功能,安装失败
  • 要实现的目标: 能够执行先决条件检查,这在安装期间已作为自定义操作在MSI中完成,而无需在给定计算机上安装MSI

    尝试失败:

    1) 自定义操作具有如下函数签名

    [CustomAction]
    public static ActionResult ProcessFeaturePrerequisite(Session session);
    
    msiexec /i "Product.msi" ADDLOCAL=ALL REMOVE="Foo,Bar " 
    
    为了获得会话对象,我使用了WIX3.0SDK中的以下API

    Session session = Installer.OpenPackage("Pathto\\Product.msi", true); // true doesn’t install it. Also tried with false, but didn’t work.
    
    当我在上面的会话中调用上述方法时,以下操作失败

    session.Features["SomeFeature"].CurrentState;
    
    这会引发异常

    System.ArgumentException was unhandled by user code
      Message=Feature ID not registered. SomeFeature
      Source=Microsoft.Deployment.WindowsInstaller
      StackTrace:
           at Microsoft.Deployment.WindowsInstaller.FeatureInfo.get_CurrentState()
    
    同样,在决定先决条件状态的关键API下,始终返回false

    session.EvaluateCondition(prereq);
    
    2) 我知道一种命令行方式来指定上述MSI的功能并安装它。事情是这样的

    [CustomAction]
    public static ActionResult ProcessFeaturePrerequisite(Session session);
    
    msiexec /i "Product.msi" ADDLOCAL=ALL REMOVE="Foo,Bar " 
    
    我在SDK中找不到任何API,它允许我在不启动安装的情况下传递返回会话对象的附加参数。我猜传递这样的参数会使session.Features更有效

    问题: 那么,我如何实现上述目标呢? 有吗

  • Wix SDK中允许我调用自定义操作的任何API 调用安装
  • 从给定MSI的命令行调用自定义操作的任何方法 不安装
  • 让Wix将MSI更改为接受命令字符串的任何方法 是否包含仅计算操作的自定义操作名称
  • 还有更好的方法吗

  • 我想你试图用错误的工具解决这个问题。据我所知,您希望从某个工具内部检查安装先决条件,而不是从安装中检查。只要该功能是作为MSI包中的自定义操作实现的,您就希望利用该功能以避免重复代码

    我会根据你的情况选择不同的方式:

  • 将实际检查先决条件的功能提取到单独的程序集中,例如
    checkprereq.dll
  • 重构自定义操作以引用
    checkprereq.dll
    。请注意,您必须将
    checkprereq.dll
    添加到
    Binary
    表以及
    customaction.dll
    。您应该在这里划分责任:自定义操作部分与MSI内容一起工作-在您的情况下,它根据用户选择的功能组合定义要检查的先决条件-以及功能部分-实际先决条件验证,这是通过
    checkprereq.dll
  • 当需要检查未触发安装过程的先决条件时,请分别使用
    checkprereq.dll
  • 您在这里概述的尝试证明了一个重要的错误假设:安装时的
    会话
    对象与您仅打开MSI数据库进行只读操作而获得的安装对象相同。这不是真的!实际上,我怀疑在安装事务之外引用
    会话
    对象是否有意义。正如其名称所述,它是一个安装会话,也就是说,在过程中可用,而不是一个静态的东西

    当MSI包只是一个文件而不是一个正在运行的安装时,它应该被视为一个数据库。因此,当您只打开MSI包进行读取而不进行安装时,只能查询和使用MSI包中的静态信息。我的意思是,例如,您可以查询
    功能表
    ,但不要期望它包含仅在安装时有意义的信息,例如用户是否选择了功能进行安装


    希望这是有意义的,并为您指明了正确的方向。

    一个快速的后续问题,我在当前自定义操作中遇到了
    session.EvaluateCondition(prereq)
    。从MSI数据库的角度来看,此映射如下
    NETFX4->(AppSearch.Property,Signature)NETFX4->(RegLocator.Signature,Key,Name)SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full,Install
    WiX的DTF中是否有上述计算结果的API?对不起,我的错误。我匆忙地写了上面的话。我正在调查这个问题。