Localization wix工具集:如何创建一个产品名为多语言本地化的exe

Localization wix工具集:如何创建一个产品名为多语言本地化的exe,localization,wix,installation,bootstrapper,wix3.9,Localization,Wix,Installation,Bootstrapper,Wix3.9,我正在使用wixv3.9r2创建我的安装程序。我已经将安装程序本地化为几种语言,效果非常好。但是,无论格式和显示语言设置为何种语言,它在程序和功能中始终使用应用程序的英文名称 如何告诉it部门在程序和功能中为我的应用程序使用本地化名称 编辑: 澄清一下:我想我需要的是一种在安装时根据用户的语言更改Bundle的name属性(或[WixBundleName])的方法。可能吗 或者,如果不能做到这一点,人们目前如何使用WiX捆绑包,并最终在程序和功能中本地化程序名称 编辑2: 从: WixBundl

我正在使用wixv3.9r2创建我的安装程序。我已经将安装程序本地化为几种语言,效果非常好。但是,无论格式和显示语言设置为何种语言,它在程序和功能中始终使用应用程序的英文名称

如何告诉it部门在程序和功能中为我的应用程序使用本地化名称

编辑:

澄清一下:我想我需要的是一种在安装时根据用户的语言更改Bundle的name属性(或[WixBundleName])的方法。可能吗

或者,如果不能做到这一点,人们目前如何使用WiX捆绑包,并最终在程序和功能中本地化程序名称

编辑2: 从:

WixBundleName-获取捆绑包的名称(来自bundle/@name)。这 变量也可以由引导程序应用程序设置,以修改 运行时的包名称

听起来这是可以做到的,但是怎么做呢

编辑3: 这是我当前的捆绑包,供参考。链中的最后一项是我的应用程序

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
    <Bundle Name="Map Creator"
            Version="$(var.ProductVersion)" 
            Manufacturer="FMOsoft" 
            IconSourceFile="$(var.KarteDir)\assets\logo\ico\icon.ico" 
            UpgradeCode="[GUID]" 
            AboutUrl="http://fmosoft.com/MapCreator"
            Copyright="Copyright© 2015, FMOsoft">

        <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkSidebarLicense">
          <bal:WixStandardBootstrapperApplication
            LocalizationFile="$(var.KarteDir)\install\win\L10n\installer\thm_en_us.wxl"
            ThemeFile="$(var.KarteDir)\install\win\HyperlinkSidebarTheme_fmosoft.xml"
            LogoFile="$(var.KarteDir)\assets\logo\bmp\logo_64.bmp"
            LogoSideFile="logoside.bmp"
            ShowVersion="yes"
            LicenseFile="$(var.KarteDir)\install\license_en.html"
            SuppressOptionsUI="yes"
            LaunchTarget="[ProgramFiles6432Folder]\FMOsoft\MapCreator\MapCreator.exe"
            />

          <!-- WixStdBa requires specific names, at run time, in the temporary .BA1 folder.  XML and png file is only needed for layout changes. 
               Payload/@Name for .wxl must be <lcid>\thm.wxl 
               Payload/@Name for .xml must be <lcid>\thm.xml AND must also have logo.png in same folder.--> 
          <Payload Id="theme_en_us" Compressed="yes"  Name="1033\thm.wxl" SourceFile="$(var.KarteDir)\install\win\L10n\installer\thm_en_us.wxl"/> 
          <Payload Id="license_en_us" Compressed="yes"  Name="1033\license.html" SourceFile="$(var.KarteDir)\install\license_en.html"/> 
          <Payload Id="theme_es_es" Compressed="yes"  Name="1034\thm.wxl" SourceFile="$(var.KarteDir)\install\win\L10n\installer\thm_es_es.wxl"/> 
          <Payload Id="license_es_es" Compressed="yes"  Name="1034\license.html" SourceFile="$(var.KarteDir)\install\license_es.html"/> 
          <Payload Id="theme_fr_fr_xml" Compressed="yes"  Name="1036\thm.xml" SourceFile="$(var.KarteDir)\install\win\L10n\installer\HyperlinkSidebarTheme_fmosoft_fr.xml"/> 
          <Payload Id="theme_fr_fr" Compressed="yes"  Name="1036\thm.wxl" SourceFile="$(var.KarteDir)\install\win\L10n\installer\thm_fr_fr.wxl"/> 
          <Payload Id="theme_fr_fr_logo" Compressed="yes"  Name="1036\logo.png" SourceFile="$(var.KarteDir)\assets\logo\bmp\logo_64.bmp"/> 
          <Payload Id="theme_fr_fr_sidelogo" Compressed="yes"  Name="1036\logoside.png" SourceFile="$(var.KarteDir)\install\win\logoside.bmp"/> 
          <Payload Id="license_fr_fr" Compressed="yes"  Name="1036\license.html" SourceFile="$(var.KarteDir)\install\license_fr.html"/> 
          <Payload Id="theme_pt_br" Compressed="yes"  Name="1046\thm.wxl" SourceFile="$(var.KarteDir)\install\win\L10n\installer\thm_pt_br.wxl"/>
          <Payload Id="license_pt_br" Compressed="yes"  Name="1046\license.html" SourceFile="$(var.KarteDir)\install\license_pt.html"/> 
          <Payload Id="theme_id" Compressed="yes"  Name="1057\thm.wxl" SourceFile="$(var.KarteDir)\install\win\L10n\installer\thm_id.wxl"/>
          <Payload Id="license_id" Compressed="yes"  Name="1057\license.html" SourceFile="$(var.KarteDir)\install\license_id.html"/> 
        </BootstrapperApplicationRef>

        <WixVariable Id="WixStdbaLicenseUrl" Value="license.html" />
        <Variable Name="MyProductVersion" Value="$(var.ProductVersion)" />
        <!-- There must be a better way to show the localized name of the app in the setup, but this works. -->
        <Variable Name="AppName_es" Value="Creador de Mapas"/>
        <Variable Name="AppName_fr" Value="Créateur de Carte"/>
        <Variable Name="AppName_pt" Value="Criador de Mapas"/>
        <Variable Name="AppName_id" Value="Pencipta Peta"/>

        <Chain>
            <ExePackage SourceFile="vcredist_x64.exe" PerMachine="yes" Permanent="yes" Vital="yes" Compressed="yes" InstallCommand="/quiet /norestart" InstallCondition="VersionNT64"/>
            <ExePackage SourceFile="vcredist_x86.exe" PerMachine="yes" Permanent="yes" Vital="yes" Compressed="yes" InstallCommand="/quiet /norestart" InstallCondition="NOT VersionNT64"/>
            <PackageGroupRef Id="OldMapEditorPackage"/>
            <MsiPackage Vital="yes" SourceFile="$(var.BuildDir)out\map-creator-$(var.Platform).msi" />
        </Chain>
    </Bundle>
</Wix>

有一个打开的功能请求:。此解决方案允许您提供一个资源dll,程序和功能将查询该dll的显示名称,因此,如果用户更改操作系统语言,该dll将发生更改

在有人实现该功能之前,您可以通过设置
WixBundleName
变量来实现这一点。如果您正在编写自定义BA,您将调用

如果您使用的是WixStdBA,则必须使用没有很好文档记录的BAFunctions dll来调用此方法。有一个示例项目。请注意,最近刚刚添加的将帮助您了解当前语言是什么

要添加BAFunctions.dll,只需将其添加为有效负载:

<BootstrapperApplicationRef ...>
  <Payload Name="BAFunctions.dll" SourceFile="path\to\your.dll" />
</BootstrapperApplicationRef>

如果有帮助的话,因为我花了很长时间才弄明白,下面是我如何本地化WixBundleName的,以便在程序和功能中进行本地化。这是基于肖恩·霍尔的回答和评论

这对我来说很有效


我不确定我是否理解这个功能要求——我对这一切都是新手。我想我要做的是,在安装时根据用户的语言更改bundle@name。谢谢!如何“使用BADLL”?从示例项目来看,我应该构建自己的BAFunctions.dll,对吗?如果是这样,我如何告诉我的Bundle使用我的BAFunctions.dll?我尝试在wxl中引用[WixStdBALanguageId],但它是空字符串。WixStdBALanguageId在WiX 3.9 R2中可用吗?还是有新的发展?如果是在3.9 R2中,我可以在哪里使用它?@DavidBurson更新了如何包含BAFunctions.dll。它在v3.10中,可以在每周发布的网站上找到<代码> WixStdBalAugAdvID是一个在C++代码中使用的变量,我不相信你在函数中访问了你的WXL文件。@ DavidBurson示例项目是静态链接的,所以它没有依赖关系。这也是WixStdBA的构建方式。是否可以检索原始捆绑包名称,并向其附加一些本地化字符串?请提出建议。我的bundle.wxs中有BootstrapperApplicationRef元素之后的注释和代码,希望对您有所帮助:
/* This document describes how we build bafunctions.dll.

1. Install the version of WiX you want to use.  This is necessary because it sets some environment variables or something, 
    and provides some .h files needed to get the BAFunctions project to compile.
2. Download the wixXX-debug.zip file from the same page where the WiX installer is for the version of WiX you want.
3. Unzip and browse to [wixXX-debug\src\burn\Samples\bafunctions\ and open the project in Visual Studio 2010.
4. In WixBootstrapperBAFunction.cpp, add our code as shown below.
5. Rebuild solution in Release configuration.
6. copy bafunctions\release\bafunctions.dll to Map Creator build machine, [map_creator]\install\win\[Wix_X.X]

*/

// In WixBootstrapperBAFunction.cpp:

// comment out this line (line 32 in WiX 3.10):

    STDMETHODIMP OnDetectComplete() { return S_OK; }

/* uncomment the commented-out OnDetectComplete procedure, and in the section marked
// YOUR CODE GOES HERE
add this code:
*/
        LONGLONG lang_id = NULL;
        LPWSTR bundle_name = NULL;
        LPWSTR platform = NULL;
        LPWSTR orig_name = NULL;

        // get the language the user is using
        BalGetNumericVariable(L"WixStdBALanguageId", &lang_id);
        BalExitOnFailure(hr, "Failed to get variable 'WixStdBALanguageId'.");

        // log the language id
        char msg[66];   // 66 I'm sure is big enough
        sprintf_s(msg, 67, "%s%d", "WixStdBALanguageId is ", lang_id);
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, msg);

        /* I don't know how to pass custom variables from the .wxs, so I tried below to use the built-in HelpTelephone.
            That doesn't work either - apparently we can only get variables listed in:
            http://wixtoolset.org/documentation/manual/v3/bundle/bundle_built_in_variables.html
        BalGetStringVariable(L"WixBundleHelpTelephone", &platform);
        BalExitOnFailure(hr, "Failed to get WixBundleHelpTelephone variable.");*/

        // Since I don't know how to pass a custom variable from the .wxs, I get the @Name attribute of the Bundle (from the .wxs),
        //  and I parse out the platform.
        BalGetStringVariable(L"WixBundleName", &orig_name);
        BalExitOnFailure(hr, "Failed to get WixBundleName variable.");

        platform = wcsrchr(orig_name, '(');

        // log the platform.
        char msg5[66];  // 66 I'm sure is big enough
        sprintf_s(msg5, 67, "%s%s", "platform is ", platform);
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, msg5);

        // Select the localized bundle name
        // I got the language codes from https://msdn.microsoft.com/en-us/goglobal/bb964664.aspx
        switch (lang_id) {
            case 1036:
            case 2060:
            case 3084:
            case 4108:
            case 5132:
            case 6156:
            case 7180:
            case 8204:
            case 9228:
            case 10252:
            case 11276:
            case 12300:
            case 13324:
            case 14348:
            case 15372:
            case 58380:
                // French
                bundle_name = L"Créateur de Carte";
                break;

            case 1057:
                // Indonesian
                bundle_name = L"Pencipta Peta";
                break;

            case 1046:
            case 2070:
                // Portuguese
                bundle_name = L"Criador de Mapas";
                break;

            case 1034:
            case 2058:
            case 3082:
            case 4106:
            case 5130:
            case 6154:
            case 7178:
            case 8202:
            case 9226:
            case 10250:
            case 11274:
            case 12298:
            case 13322:
            case 14346:
            case 15370:
            case 16394:
            case 17418:
            case 18442:
            case 19466:
            case 20490:
            case 21514:
            case 22538:
                // Spanish
                bundle_name = L"Creador de Mapas";
                break;

            default:
                bundle_name = L"Map Creator";
        }

        // log the new bundle name.
        char msg2[66];  // 66 I'm sure is big enough
        sprintf_s(msg2, 67, "%s%s", "bundle_name is ", bundle_name);
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, msg2);

        // append the platform to the end of the bundle name
        wchar_t bundle_name_platform[80];
        wcscpy_s(bundle_name_platform, bundle_name);
        wcscat_s(bundle_name_platform, L" ");
        wcscat_s(bundle_name_platform, platform);

        // log the final bundle name (which includes the platform)
        char msg3[66];  // 66 I'm sure is big enough
        sprintf_s(msg3, 67, "%s%s", "bundle_name_platform is ", bundle_name_platform);
        BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, msg3);

        // set the name of our bundle
        hr = m_pEngine->SetVariableString(L"WixBundleName", bundle_name_platform);
        BalExitOnFailure(hr, "Failed to set WixBundleName variable.");