Advanced Installer (AIL)

Lingo.dev CLIを使用したAdvanced InstallerローカライゼーションファイルのAI翻訳

Advanced Installer AILとは?

Advanced Installerは、開発者がMSI(Microsoft Installer)パッケージを作成するのに役立つWindowsインストーラー作成ツールです。AIL(Advanced Installer Localization)は、インストーラーのダイアログ、ボタン、メッセージ、プロパティをローカライズするために使用されるXMLベースの多言語辞書形式です。複数の言語のすべての翻訳は、単一のAILファイルに保存されます。

Lingo.dev CLIとは?

Lingo.dev CLIは、AIを使用してアプリとコンテンツを翻訳するための無料のオープンソースCLIです。従来の翻訳管理ソフトウェアを置き換えながら、既存のパイプラインと統合するように設計されています。

詳細については、概要を参照してください。

このガイドについて

このガイドでは、Lingo.dev CLIを使用してAdvanced Installer AILファイルを翻訳する方法を説明します。

次の方法を学習します:

  • ゼロからプロジェクトを作成する
  • 翻訳パイプラインを設定する
  • AIで翻訳を生成する

前提条件

Lingo.dev CLIを使用するには、Node.js v18+がインストールされていることを確認してください:

❯ node -v
v22.17.0

ステップ 1. プロジェクトをセットアップする

プロジェクトのディレクトリに、i18n.json ファイルを作成します:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

このファイルは、翻訳する言語とファイルシステム上のローカライズ可能なコンテンツの場所を含む、翻訳パイプラインの動作を定義します。

使用可能なプロパティの詳細については、i18n.jsonを参照してください。

ステップ 2. ソースロケールを設定する

_ソースロケール_は、コンテンツが書かれた元の言語と地域です。ソースロケールを設定するには、i18n.json ファイルで locale.source プロパティを設定します:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

ソースロケールは、BCP 47言語タグとして指定する必要があります。

Lingo.dev CLIがサポートするロケールコードの完全なリストについては、サポートされているロケールコードを参照してください。

ステップ3. ターゲットロケールの設定

_ターゲットロケール_は、コンテンツを翻訳したい言語と地域です。ターゲットロケールを設定するには、i18n.jsonファイルのlocale.targetsプロパティを設定します。

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

ステップ4. ソースコンテンツの作成

まだ作成していない場合は、翻訳対象のコンテンツを含むAILファイルを作成します。AILファイルはXML構造を使用し、すべての言語翻訳が単一のファイルに保存されます。

ファイル構造:

<?xml version="1.0" encoding="UTF-8"?>
<DICTIONARY type="multilanguage">
  <ENTRY id="Control.Text.WelcomeDlg#Title">
    <STRING lang="en" value="Welcome to the Setup Wizard"/>
  </ENTRY>
  <ENTRY id="Control.Button.Next">
    <STRING lang="en" value="Next"/>
  </ENTRY>
</DICTIONARY>

翻訳可能なコンテンツ:

  • ENTRY要素は、一意のid属性を持つ翻訳可能な文字列を表します
  • ENTRY内のSTRING要素には、特定の言語の翻訳が含まれます
  • lang属性は言語コードを指定します
  • value属性には翻訳可能なテキストが含まれます

エントリIDの規則:

AILファイルは、インストーラーコンテンツを整理するために構造化されたIDを使用します。

  • コントロールテキスト: Control.Text.DialogName#ElementName
  • コントロールボタン: Control.Button.ButtonName
  • プロパティ: Property.PropertyName

例:

  • Control.Text.WelcomeDlg#Title - Welcomeダイアログのタイトルテキスト
  • Control.Button.Next - Nextボタンのテキスト
  • Property.ProductName - 製品名プロパティ

Advanced Installer変数:

AILファイルは、実行時に置き換えられるAdvanced Installer変数をサポートしています。

  • [ProductName] - 製品名に置き換えられます
  • [ProductVersion] - 製品バージョンに置き換えられます
  • [Manufacturer] - 製造元名に置き換えられます

これらの変数は翻訳中も保持されます。

<ENTRY id="Control.Text.WelcomeDlg#Title">
  <STRING lang="en" value="Welcome to [ProductName] Setup"/>
</ENTRY>

出力モード:

AILバケットは、ロケールごとに個別のファイルを作成するのではなく、元のファイルを変更します。翻訳を実行すると、CLIは既存のAILファイル内のターゲットロケール用のSTRING要素を追加または更新します。これは、AILファイルがすべての言語翻訳を単一のファイルに保存するように設計されているためです。

ステップ5. バケットを作成する

  1. i18n.jsonファイルで、bucketsオブジェクトに"ail"オブジェクトを追加します:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "ail": {}
      }
    }
    
  2. "ail"オブジェクトで、1つ以上のincludeパターンの配列を定義します:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "ail": {
          "include": ["./*.ail"]
        }
      }
    }
    

    これらのパターンは、翻訳するファイルを定義します。

    パターン自体は:

    • ファイルパスを指定できます(例:"./installer.ail"
    • ワイルドカードプレースホルダーとしてアスタリスクを使用できます(例:"./*.ail"
    • [locale]プレースホルダーは使用しません(すべてのロケールが同じファイルにあるため)

    再帰的なglobパターン(例:**/*.ail)はサポートされていません。

ステップ6. LLMを設定する

Lingo.dev CLIは、大規模言語モデル(LLM)を使用してAIでコンテンツを翻訳します。これらのモデルのいずれかを使用するには、サポートされているプロバイダーからAPIキーが必要です。

できるだけ早く開始するには、Lingo.dev Engineの使用をお勧めします:

  1. Lingo.devアカウントにサインアップします。

  2. 次のコマンドを実行します:

    npx lingo.dev@latest login
    

    これにより、デフォルトのブラウザが開き、認証を求められます。

  3. プロンプトに従います。

ステップ7. 翻訳を生成する

i18n.jsonファイルを含むディレクトリで、次のコマンドを実行します:

npx lingo.dev@latest run

このコマンドは:

  1. i18n.jsonファイルを読み取ります。
  2. 翻訳が必要なファイルを見つけます。
  3. ファイルから翻訳可能なコンテンツを抽出します。
  4. 設定されたLLMを使用して抽出されたコンテンツを翻訳します。
  5. 翻訳されたコンテンツをファイルシステムに書き戻します。

翻訳が初めて生成されると、i18n.lockファイルが作成されます。このファイルは、どのコンテンツが翻訳されたかを追跡し、後続の実行で不要な再翻訳を防ぎます。

翻訳前(example.ail)

<?xml version="1.0" encoding="UTF-8"?>
<DICTIONARY type="multilanguage">
  <ENTRY id="Control.Text.WelcomeDlg#Title">
    <STRING lang="en" value="Welcome to the [ProductName] Setup Wizard"/>
  </ENTRY>
  <ENTRY id="Control.Text.WelcomeDlg#Description">
    <STRING lang="en" value="The Setup Wizard will install [ProductName] on your computer. Click Next to continue or Cancel to exit the Setup Wizard."/>
  </ENTRY>
  <ENTRY id="Control.Text.LicenseAgreementDlg#Title">
    <STRING lang="en" value="End-User License Agreement"/>
  </ENTRY>
  <ENTRY id="Control.Text.LicenseAgreementDlg#AcceptCheckbox">
    <STRING lang="en" value="I accept the terms in the License Agreement"/>
  </ENTRY>
  <ENTRY id="Control.Button.Next">
    <STRING lang="en" value="Next"/>
  </ENTRY>
  <ENTRY id="Control.Button.Cancel">
    <STRING lang="en" value="Cancel"/>
  </ENTRY>
  <ENTRY id="Property.ProductName">
    <STRING lang="en" value="My Application"/>
  </ENTRY>
</DICTIONARY>

翻訳後(example.ail)

<?xml version="1.0" encoding="UTF-8"?>
<DICTIONARY type="multilanguage">
  <ENTRY id="Control.Text.WelcomeDlg#Title">
    <STRING lang="en" value="Welcome to the [ProductName] Setup Wizard"/>
    <STRING lang="es" value="Bienvenido al asistente de instalación de [ProductName]"/>
  </ENTRY>
  <ENTRY id="Control.Text.WelcomeDlg#Description">
    <STRING lang="en" value="The Setup Wizard will install [ProductName] on your computer. Click Next to continue or Cancel to exit the Setup Wizard."/>
    <STRING lang="es" value="El asistente de instalación instalará [ProductName] en su ordenador. Haga clic en Siguiente para continuar o en Cancelar para salir del asistente de instalación."/>
  </ENTRY>
  <ENTRY id="Control.Text.LicenseAgreementDlg#Title">
    <STRING lang="en" value="End-User License Agreement"/>
    <STRING lang="es" value="Acuerdo de licencia para el usuario final"/>
  </ENTRY>
  <ENTRY id="Control.Text.LicenseAgreementDlg#AcceptCheckbox">
    <STRING lang="en" value="I accept the terms in the License Agreement"/>
    <STRING lang="es" value="Acepto los términos del acuerdo de licencia"/>
  </ENTRY>
  <ENTRY id="Control.Button.Next">
    <STRING lang="en" value="Next"/>
    <STRING lang="es" value="Siguiente"/>
  </ENTRY>
  <ENTRY id="Control.Button.Cancel">
    <STRING lang="en" value="Cancel"/>
    <STRING lang="es" value="Cancelar"/>
  </ENTRY>
  <ENTRY id="Property.ProductName">
    <STRING lang="en" value="My Application"/>
    <STRING lang="es" value="My Application"/>
  </ENTRY>
</DICTIONARY>

i18n.json

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {
    "ail": {
      "include": ["./*.ail"]
    }
  }
}

i18n.lock

version: 1
checksums:
  f84d41a1c3ad7e70e25c84811ef9baef:
    Control.Text.WelcomeDlg%23Title: 93af4b47a8c0a84ce9fb82d2ee2bca13
    Control.Text.WelcomeDlg%23Description: 9cbc6500217ae2a7b3ffd74a3c723493
    Control.Text.LicenseAgreementDlg%23Title: 3fe6d3757d7129ede78b41dd06042bf2
    Control.Text.LicenseAgreementDlg%23AcceptCheckbox: 768d9d11db014facbc1b65af8e39e260
    Control.Button.Next: 4c49d903308e8e3f5c866cfd78ef0e89
    Control.Button.Cancel: a149e8d5b349f68b3cfc9fbe6b23cbb4
    Property.ProductName: c215a8d46c95f00089c5ea0d17eef742