为什么 MST 不包含具有不同内容的文件 [英] Why would MST not include files with different content

查看:24
本文介绍了为什么 MST 不包含具有不同内容的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试制作多语言安装程序 - 该过程总体上运行正常,但似乎无法安装要安装的本地化文件.

Trying to make a multilingual installer - the process is working in general, but seems to be failing for localised files that are to be installed.

每个本地化安装程序都可以独立运行并安装本地化文件,如 eula.pdf.

Each of the localised installers works fine as a standalone and installs the localised files like the eula.pdf.

我希望我只是在转换生成步骤中遗漏了一个标志(或者可能使用了错误的工具?)

I'm hoping that I'm just missing a flag on the transform generation step (or maybe using the wrong tool?)

首先要为每种语言安装一堆安装程序 1.

Process being to start by having a bunch of installers 1 for each language.

为了构建每个安装程序,我们使用 -b "folder"-loc "folder" 选项来指定每种语言,其中包括一些替代文件内容,例如作为许可证.pdf.

To build each installer we are 'lighting' using -b "folder" and -loc "folder" option to specify each language which includes some alternate file content such as the licence.pdf.

要本地化的文件有一个共同的源名称

The files to be localised have a common source name

<File Id='License.pdf' Name='eula.pdf' Source='License(EULA).pdf' KeyPath='yes'/>
<WixVariable Id="WixUILicenseRtf" Value="License.rtf" />

文件夹例如是

en-US/License(EULA).pdf
en-US/License.rtf
en-US/Product.wxl
fr-FR/License(EULA).pdf
fr-FR/License.rtf
fr-FR/Product.wxl

还有一些未本地化的文件,例如 binary.dll 和 binary.exe,对于所有 msi 都是相同的 - 不要期望在 MST 中看到它们.

There are also some files such as binary.dll and binary.exe which are not localised and are the same for all msi - don't expect to see them in MST.

流程的下一步是在基本语言(英语)和其他每种语言之间创建 MST 差异.使用来自 Window SDK 的 Windows\v7.1\Bin\MsiTran.exe

Following the next step in the process is creating an MST diff between a base language (english) and each of the other languages. Using Windows\v7.1\Bin\MsiTran.exe from the Window SDK

对于内容的变化,MST 似乎有点小.

The MST seem a bit small for the change in content.

使用 Windows\v7.1\Samples\sysmgmt\msi\scripts\wisubstg.vbs

以英语以外的语言安装会显示整个安装程序 UI,包括许可证的 rtf 版本已本地化,但磁盘上的 eula.pdf 始终是基础英语.

Installing in a language other than english shows the whole installer UI including rtf version of the licence as being localised, but the eula.pdf on disk is always the base english.

使用 Ant-dotnet 任务运行构建(以防万一)msi 构建任务

Using the Ant-dotnet tasks to run the build (in case it makes a difference) The msi build task

    <wix mode="light" target="${outlocation}\${lang.folder}\my.msi" wixHome="${wixhome}">
        <lightArg line="-b &quot;${location}&quot;"/> <!-- provide the location of the signable binaries -->
        <lightArg line="-b &quot;${msiwixsource}\Localisation\${lang.folder}&quot;"/> <!-- provide the location of the localisation -->
        <lightArg line="-sice:ICE57"/>
        <lightArg line="-cultures:${lang.culture}"/>
        <lightArg line="-loc &quot;${msiwixsource}\Localisation\${lang.folder}\Product.wxl&quot;"/>
        <lightArg line="-ext &quot;${wixhome}\WixUtilExtension.dll&quot;"/>
        <lightArg line="-ext &quot;${wixhome}\WixUIExtension.dll&quot;"/>
        <lightArg line="-ext &quot;${wixhome}\WixFirewallExtension.dll&quot;"/>
        <lightArg line="-ext &quot;${wixhome}\WixNetFxExtension.dll&quot;"/>
        <sources dir="${msiwixobjects}">
          <include name="*.wixobj"/>
        </sources>
        <moresources dir="${msiwixsource}\Localisation\${lang.folder}">
          <include name="*"/>
        </moresources>
        <moresources dir="${location}">
          <include name="binary.dll,binary.exe"/>
        </moresources>
    </wix>

转换任务

    <exec executable="${windowsSDKBin}">
        <arg value="-g"/>
        <arg value="${outlocation}\en-US\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\my.mst"/>
    </exec>

重新打包任务

    <exec executable="cscript">
        <arg value="${windowsSDKMsi}"/>
        <arg value="${outlocation}\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\my.mst"/>
        <arg value="${lang.id}"/>
    </exec>

Product/@Language="!(loc.Lang)" 在 Product.wxl 中指定对于英语基础我们列出了所有 1033,1028,1029,1031,1036,1040,1041,1043,1045,1046,2052,3082 其他语言只是特定的例如 1036代码>为fr-FR

Product/@Language="!(loc.Lang)" specified in Product.wxl for English base we listed all 1033,1028,1029,1031,1036,1040,1041,1043,1045,1046,2052,3082 for other languages just the specific such as 1036 for fr-FR

推荐答案

好的,经过几天的搜索,我找到了一篇描述该问题的文章.如何使用 MST 本地化设置 GUI 并提供本地化文件.

Ok, so after a couple of days of searching I found an article that describes the issue. How To Localize the Setup GUI and Deliver Localized Files Using a MST.

问题在于 MST 不包含存储 CAB 文件的_Streams"表元素.

The issue being that MST doesn't include '_Streams' table elements which is where the CAB files are stored.

你可以采取多种方式 -

You could go several ways from that -

1) 制作多个文件 &基于语言或文化的条件包含的不同语言的组件条目

这意味着如果您想更改支持的语言,请更改您的 wxs.

This means changing your wxs if you want to change which languages are supported.

<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***'>
  <Condition><![CDATA[(ProductLanguage = "1033")]]></Condition>
  <File Id='License.pdf' Name='!(loc.EULA)' Source='en-US\License(EULA).pdf' KeyPath='yes'/>
</Component>
<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***'>
  <Condition><![CDATA[(ProductLanguage = "1046")]]></Condition>
  <File Id='License.pdf' Name='!(loc.EULA)' Source='pt-BR\License(EULA).pdf' KeyPath='yes'/>
</Component>
... add a new block each time you add a language, changes to files have to be duplicated for every block.

这反过来意味着重新编译而不是仅仅重新链接 wxl.您仍然需要重新打包 mst 文件.

Which in turn means recompiling instead of just relinking the wxl. You still need to repack the mst files.

2) 手动调整本地化的MSI

根据 如何使用 MST 本地化安装 GUI 和交付本地化文件.

3) 自动将本地化项目拆分为具有本地化名称的单独 CAB

这不是重新编译,而是重新链接和管理 CAB 文件的额外过程.额外的过程 -* 提取 CAB 文件并生成 mst,
* 然后在合并 mst 时还要添加 cab 文件.

Rather than recompile this is then relinking and extra process for managing the CAB files. Extra process to - * extract the CAB file(s) along with generating the mst,
* then when merging the mst also add the cab files.

添加一个具有本地化名称的额外媒体 - 我使用的是 lang id,因为它很方便

Add an extra media which has a localised name - I'm using the lang id as it is convenient

<Media Id="2" Cabinet="localised_!(loc.LANG).cab" EmbedCab="yes" />

将本地化的文件/组件更改为来自新媒体

Change the localised files/components to come from the new media

<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***' DiskId='2'>
  <File Id='License.pdf' Name='!(loc.EULA)' Source='License(EULA).pdf' KeyPath='yes'/>
</Component>

当使用 MSITran.exe 生成转换时,也使用 MsiDb.Exe 导出本地化的 CAB 文件当使用 WiSubStg.vbs 将转换合并到基础 MSI 时,还使用 ​​WiStram.vbs

When generating the transforms using MSITran.exe also export the localised CAB files using MsiDb.Exe When merging the transforms into the base MSI using WiSubStg.vbs also add the CAB files to the _Streams using WiStram.vbs

我选择了选项 3我希望其他人觉得这很有用.注意:

I've gone with option 3 I hope somebody else finds this useful. Note:

  • 我不会写很多 ANT,所以请随时提供建议
  • 我们构建了一个用于测试的未签名版本和用于发布的签名版本,因此需要调整输入/输出位置以查找二进制文件和 msi.

ant 构建如下所示.

and the ant build looks something like the following.

<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="buildjars"/>
<taskdef name="for" classname="net.sf.antcontrib.logic.ForTask" classpathref="buildjars"/> 
<taskdef name="wix" classname="org.apache.ant.dotnet.wix.WixTask" classpathref="buildjars"/>

<property name="wixhome" value="C:\Program Files (x86)\Windows Installer XML v3.5\bin"/>

<property name="binarieslocation" value="build"/>
<property name="msiwixsource" value="install"/>
<property name="msiwixobjects" value="${msiwixsource}\obj\x64\Release"/>
<!-- <dirname property="windowsSDK" file="C:\Program Files\Microsoft SDKs\Windows\v7.1\"/> Ant doesn't like path segments with . -->
<property name="windowsSDKBin" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\MsiTran.exe"/>
<property name="windowsSDKCab" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\MsiDb.Exe"/>
<property name="windowsSDKMsiStorage" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiSubStg.vbs"/>
<property name="windowsSDKMsiStream" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiStream.vbs"/>
<property name="windowsSDKMsiLanguages" location="C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\sysmgmt\msi\scripts\WiLangId.vbs"/>  

<property name="cultureBase" value="en-US:en-US:1033"/>
<property name="cultures" value="pt-BR:pt-BR:1046,cs-CZ:en-US:1029"/> 

<target name="installer">
    <echo>Building ${culture} msi using binaries in "${location}"...</echo>
    <propertyregex property="lang.folder" input="${culture}" regexp="(.*):(.*):(.*)" select="\1"/>
    <propertyregex property="lang.culture" input="${culture}" regexp="(.*):(.*):(.*)" select="\2"/>

<wix mode="light" target="${outlocation}\${lang.folder}\my.msi" wixHome="${wixhome}">
    <lightArg line="-b &quot;${location}&quot;"/> <!-- provide the location of the signable binaries -->
    <lightArg line="-b &quot;${msiwixsource}\Localisation\${lang.folder}&quot;"/> <!-- provide the location of the localisation -->
    <lightArg line="-sice:ICE57"/>
    <lightArg line="-cultures:${lang.culture}"/>
    <lightArg line="-loc &quot;${msiwixsource}\Localisation\${lang.folder}\Product.wxl&quot;"/>
    <lightArg line="-ext &quot;${wixhome}\WixUtilExtension.dll&quot;"/>
    <lightArg line="-ext &quot;${wixhome}\WixUIExtension.dll&quot;"/>
    <sources dir="${msiwixobjects}">
      <include name="*.wixobj"/>
    </sources>
    <moresources dir="${msiwixsource}\Localisation\${lang.folder}">
      <include name="*"/>
    </moresources>
    <moresources dir="${location}">
      <include name="binary.dll,binary.exe"/>
    </moresources>
</wix>

</target>

<target name="checkTransform" depends="installer">
    <uptodate property="transform.notRequired" targetfile="${outlocation}\${culture}\my.mst" >
        <srcfiles dir= "${outlocation}\en-US\" includes="my.msi"/>
        <srcfiles dir= "${outlocation}\${lang.culture}\" includes="my.msi"/>
    </uptodate>
</target>

<target name="transform" depends="checkTransform" unless="transform.notRequired">
    <echo>Building ${culture} mst ...</echo>
    <propertyregex property="lang.folder" input="${culture}" regexp="(.*):(.*):(.*)" select="\1"/>
    <propertyregex property="lang.id" input="${culture}" regexp="(.*):(.*):(.*)" select="\3"/> 

    <!-- Generate the mst 'diff' file - this does not include exporting the language specific cab file to match -->
    <exec executable="${windowsSDKBin}">
        <arg value="-g"/>
        <arg value="${outlocation}\en-US\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\my.mst"/>
    </exec>

    <!-- Exporting the language specific cab file to match -->
    <delete file="localised_${lang.id}.cab" />
    <delete file="${outlocation}\${lang.folder}\localised_${lang.id}.cab" />
    <exec executable="${windowsSDKCab}">
        <arg value="-d"/>
        <arg value="${outlocation}\${lang.folder}\my.msi"/>
        <arg value="-x"/>
        <arg value="localised_${lang.id}.cab"/>
    </exec>
    <move file="localised_${lang.id}.cab" tofile="${outlocation}\${lang.folder}\localised_${lang.id}.cab"/>
</target>

<!-- Target to build MSIs using unsigned binaries -->
<target name="MSIs">
    <!-- we always need english as it is the base multilingual -->
    <antcall target="installer">
        <param name="culture" value="${cultureBase}" />
        <param name="location" value="${location}" />
        <param name="outlocation" value="${outlocation}" />
    </antcall>
    <!-- build the different cultures and make transforms 
    parallel="true" sometimes fails-->
    <for list="${cultures}" param="culture" >
      <sequential>
        <antcall target="transform">
            <param name="culture" value="@{culture}" />
            <param name="location" value="${location}" />
            <param name="outlocation" value="${outlocation}" />
        </antcall>
      </sequential>
    </for>
</target>

<!-- depends="transform" -->
<target name="transformRepack" >
    <echo>Packing ${culture} mst into multilingual installer...</echo>
    <propertyregex property="lang.folder" input="${culture}" regexp="(.*):(.*):(.*)" select="\1"/>
    <propertyregex property="lang.id" input="${culture}" regexp="(.*):(.*):(.*)" select="\3"/> 

    <exec executable="cscript">
        <arg value="${windowsSDKMsiStream}"/>
        <arg value="${outlocation}\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\localised_${lang.id}.cab"/>
        <arg value="localised_${lang.id}.cab"/>
    </exec> 
    <exec executable="cscript">
        <arg value="${windowsSDKMsiStorage}"/>
        <arg value="${outlocation}\my.msi"/>
        <arg value="${outlocation}\${lang.folder}\my.mst"/>
        <arg value="${lang.id}"/>
    </exec>
</target>

<target name="MSIMulti" depends="MSIs">
    <echo>Making multilingual installer...</echo>

    <copy file="${outlocation}\en-US\my.msi" todir="${outlocation}"/>

    <for list="${cultures}" param="culture">
      <sequential>
        <antcall target="transformRepack">
            <param name="culture" value="@{culture}" />
            <param name="location" value="${location}" />
            <param name="outlocation" value="${outlocation}" />
        </antcall>
      </sequential>
    </for>
    <!-- report what was packed -->
    <propertyregex property="lang.ids" input="${cultures}" regexp="([^:,]*):([^:]*):([^,]*)" replace="\3" global="true" defaultvalue="failed"/> 
    <echo/>
    <echo>Multilingual installer should include transform language ids </echo>
    <echo>${lang.ids}</echo>
    <echo>Multilingual installer reports transform language ids...</echo>
    <exec executable="cscript">
        <arg value="${windowsSDKMsiStorage}"/>
        <arg value="${outlocation}\my.msi"/>
    </exec>
    <exec executable="cscript">
        <arg value="${windowsSDKMsiLanguages}"/>
        <arg value="${outlocation}\my.msi"/>
        <arg value="Package"/>
        <arg value="1033,${lang.ids}"/>
    </exec>
</target>

<target name="UnsignedMSIMulti" >
    <antcall target="MSIMulti">
        <param name="location" value="${binarieslocation}" />
        <param name="outlocation" value="${binarieslocation}" />
    </antcall>
</target>

这篇关于为什么 MST 不包含具有不同内容的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆