为什么MST不包含不同内容的文件?



尝试制作一个多语言安装程序-该过程一般正常,但对于要安装的本地化文件似乎失败。

每个本地化的安装程序都可以独立运行,并安装像eula.pdf这样的本地化文件。

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

每一种语言都有一堆安装程序。

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

要本地化的文件有一个通用的源名称

<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中看到它们。

该过程的下一步是在基本语言(英语)和其他每种语言之间创建MST差异。使用Windowsv7.1BinMsiTran.exe从windows SDK

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

使用Windowsv7.1Samplessysmgmtmsiscriptswisubstg.vbs将所有MST文件合并到单个安装程序中

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

使用Ant-dotnet任务来运行构建(以防它产生差异)msi构建任务

    <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-USmy.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,例如fr-FR的1036

好,经过几天的搜索,我找到了一篇描述这个问题的文章。如何使用MST本地化安装GUI和交付本地化文件。

问题是MST不包括'_Streams'表元素,这是存储CAB文件的地方。

你可以有多种选择-

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

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

<Component Directory="INSTALLDIR" Id='EULADoc' Guid='***'>
  <Condition><![CDATA[(ProductLanguage = "1033")]]></Condition>
  <File Id='License.pdf' Name='!(loc.EULA)' Source='en-USLicense(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-BRLicense(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文件。

2)手动调整本地化的MSI

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

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

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

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

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

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

<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将CAB文件添加到_Streams

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

  • 我没有写很多ANT,所以请随时提供建议
  • 我们构建了一个用于测试的无符号版本和用于发布的有符号版本,因此需要调整输入/输出位置以找到二进制文件和msi。

和ant构建看起来像下面这样。

<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.5bin"/>
<property name="binarieslocation" value="build"/>
<property name="msiwixsource" value="install"/>
<property name="msiwixobjects" value="${msiwixsource}objx64Release"/>
<!-- <dirname property="windowsSDK" file="C:Program FilesMicrosoft SDKsWindowsv7.1"/> Ant doesn't like path segments with . -->
<property name="windowsSDKBin" location="C:Program FilesMicrosoft SDKsWindowsv7.1BinMsiTran.exe"/>
<property name="windowsSDKCab" location="C:Program FilesMicrosoft SDKsWindowsv7.1BinMsiDb.Exe"/>
<property name="windowsSDKMsiStorage" location="C:Program FilesMicrosoft SDKsWindowsv7.1SamplessysmgmtmsiscriptsWiSubStg.vbs"/>
<property name="windowsSDKMsiStream" location="C:Program FilesMicrosoft SDKsWindowsv7.1SamplessysmgmtmsiscriptsWiStream.vbs"/>
<property name="windowsSDKMsiLanguages" location="C:Program FilesMicrosoft SDKsWindowsv7.1SamplessysmgmtmsiscriptsWiLangId.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-USmy.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-USmy.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>

相关内容

  • 没有找到相关文章

最新更新