【问题标题】:How to conditionally set a file extension using Wix?如何使用 Wix 有条件地设置文件扩展名?
【发布时间】:2012-08-02 13:55:36
【问题描述】:

我想在安装期间有条件地设置文件扩展名。据我了解,为了在 Wix 中有条件地做任何事情,它应该是一个独立的组件。因此,对于我希望允许用户设置的每个文件类型关联,我都有一个类似于以下内容的组件:

<Component Id="FileAssocComponent_PS" Guid="DAFE9461-2DF0-934A-F204-6B28CEA23C01">
  <Condition>FILE_ASSOC_PS</Condition>
  <RegistryValue Root="HKLM" Key="SOFTWARE\PrinterApp\Capabilities\FileAssociations" Name=".prn" Value="PrinterApp.ps" Type="string" />
  <RegistryValue Root="HKLM" Key="SOFTWARE\PrinterApp\Capabilities\MIMEAssociations" Name="application/postscript" Value="PrinterApp.ps" Type="string" />
  <RegistryValue Root="HKLM" Key="SOFTWARE\Classes\PrinterApp.ps" Name="FriendlyTypeName" Value="PostScript File" Type="string" />
  <ProgId Id="PrinterApp.ps" Description="PostScript File" Icon="PrinterApp.ico" Advertise="yes">
    <Extension Id="ps">
      <Verb Id="open" Command="Open" Argument="&quot;%1&quot;"/>
    </Extension>
  </ProgId>
</Component>

但这给了我以下错误:

error LGHT0204: ICE19: Extension: 'ps' advertises component: 'FileAssocComponent_PS'. This component cannot be advertised because the KeyPath type disallows it.

我尝试在其中一个注册表项上设置 KeyPath="yes",但这不起作用 - 从我能够找到的内容来看,它需要一个文件 KeyPath.但这是一个不包含任何文件的组件!

我该如何解决这个错误,或者我是不是走错了路?

【问题讨论】:

    标签: installation wix windows-installer


    【解决方案1】:

    我找到了适合我的解决方案。我遇到的问题是我对扩展名与 exe 的关联有一个条件。如果未选中扩展以不关联,我需要安装 exe 组件但没有 progid。问题是,如果对组件设置条件,则不会创建 progid,但也不会安装 exe。我找到的解决方案是两个创建两个组件。一个有条件,一个有互斥条件。这基本上是 Christopher Painters 帖子中的选项 2。

    见下文:

    <Component Id="My.exe" Guid="{D9CF6FDD-1234-4E90-85A1-3BF1F912C1E3}">
       <Condition>NOT FILES_ASSOCIATIONS_ABC</Condition>
        <File Id="My.exe.without_assoc" Name="My.exe" KeyPath="yes" Vital="yes" Compressed="yes" DiskId="1" Source=".\SourceDir\My.exe" />
      </Component>
      <Component Id="My.exe_assoc" Guid="{07F96643-5D74-1234-9DAE-CDEB5AC2D11E}">
        <File Id="My.exe.with_assoc" Name="My.exe" KeyPath="yes" Vital="yes" Compressed="yes" DiskId="1" Source=".\SourceDir\My.exe" />
        <Condition>FILES_ASSOCIATIONS_ABC</Condition>
        <ProgId Id="My.Document" Description="My exe" Icon="MyIcon" Advertise="yes">
          <Extension Id="abc">
            <Verb Id="open" Command="My Exe" Argument="&quot;%1&quot;" />
            <MIME Advertise="yes" ContentType="application/abc" Default="yes" />
          </Extension>
        </ProgId>
      </Component>
    

    【讨论】:

      【解决方案2】:

      如果您设置Advertise="no",您应该可以使用您编写的代码。这是我几年前在here 发布的一个示例,它使用单独的组件进行可选文件关联。

      <Component ....>
          <ProgId Id="AcmeFoobar.Document" hDescription="ACME XYZ Document">
              <Extension Id="pdf" ContentType="application/xyz">
                  <Verb Id="open" Command="Open" TargetFile="[APPLICATIONFOLDER]AcmeFoobar.exe" Argument="%1" />
              </Extension>
          </ProgId>
      
          <Condition><![CDATA[DEFAULTVIEWER=1]]></Condition>
      </Component>
      

      【讨论】:

        【解决方案3】:

        广告组件需要密钥文件,因此这里有一些解决错误的方法。

        1)

        为组件提供一个不会损害系统的虚假文件 (printermimeinstalled.txt)。

        2)

        作者 PrinterAppMime.ps 作为该组件的密钥文件。使用 CopyFile 元素将文件复制到 PrinterApp.ps

        将 PrinterAppNoMime.ps(内容相同)作为另一个组件的密钥文件。还可以使用 CopyFile 元素将文件复制到 PrinterApp.ps。给这个组件一个互斥的组件条件,这样只有一个组件会被安装。

        3)

        稍微改变你的应用程序的设计。始终安装 PrinterApp.ps 并有条件地安装 PrinterAppMimeServer.ps。

        4)

        消除此自定义操作并使用自定义操作在安装时创建 MSI 临时表行,以在选中复选框时定义 MIME 内容。

        这 4 种方法各有利弊,我个人会选择 #3。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-20
          • 1970-01-01
          • 1970-01-01
          • 2016-02-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多