[インデックス 12081] ファイルの概要
このコミットは、Go言語のWindowsインストーラー(MSI)に関する継続的な開発作業の一部です。主な目的は、インストーラーのユーザーエクスペリエンスと機能性を向上させることにあります。具体的には、インストーラーのダイアログやバナーにGoのロゴやイメージを埋め込み、Goツールのバージョン情報に基づいてGoツリーのクローンを作成するように変更し、インストーラーが既存のGoバージョンのアップグレード、ダウングレード、修復をサポートするように機能を追加しています。また、システムレジストリに2つの新しい値を書き込むように設定が更新されています。
コミット
commit 8d7ee2b9987d2c7bb91a858d4dfa61f669cc3e8e
Author: Joe Poirier <jdpoirier@gmail.com>
Date: Mon Feb 20 00:29:57 2012 -0600
misc/dist/windows: ongoing dev
Embedded Go images in the installer dialog and
banner boxes, Go tree cloning uses version info
from the Go tool (readme updated), the installer
allows up/down-grading and reparing of the version
that's installed, added two registry values.
R=golang-dev, bradfitz, bradfitz
CC=golang-dev
https://golang.org/cl/5683048
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8d7ee2b9987d2c7bb91a858d4dfa61f669cc3e8e
元コミット内容
misc/dist/windows/README | 15 ++++++---\n misc/dist/windows/dist.bat | 8 +++--\n misc/dist/windows/images/Banner.jpg | Bin 0 -> 11219 bytes\n misc/dist/windows/images/Dialog.jpg | Bin 0 -> 16428 bytes\n misc/dist/windows/images/DialogLeft.jpg | Bin 0 -> 12961 bytes\n misc/dist/windows/images/gopher.ico | Bin 0 -> 42929 bytes\n misc/dist/windows/installer.wxs | 58 +++++++++++++++++++++-----------\n 7 files changed, 56 insertions(+), 25 deletions(-)\n\ndiff --git a/misc/dist/windows/README b/misc/dist/windows/README\nindex 898940edf5..a0b0a8a7c1 100644\n--- a/misc/dist/windows/README\n+++ b/misc/dist/windows/README\n@@ -4,7 +4,7 @@ and installer (msi) format.\n Dependencies\r\n ============\r\n - Windows Installer XML (WiX) toolset: http://wix.sourceforge.net/\r\n-- 7Zip (command-line version): http://www.7-zip.org/download.html\r\n+- 7Zip (command line version): http://www.7-zip.org/download.html\r\n - Mercurial (hg): http://mercurial.selenic.com/\r\n \r\n \r\n@@ -13,9 +13,9 @@ Packaging\n The dependencies must be callable from dist.bat, therefore,\r\n they\'ll need to be in/added to the system\'s search PATH.\r\n \r\n-Ensure the working directory reflects the toolset version;\r\n-the packager clones the Go directory it resides in and copies the\r\n-pre-built toolchain over into the cloned folder.\r\n+The packaging needs to be done from within a tracked Go folder. \r\n+Packages are built by cloning the same version of the source tree\r\n+that the Go tools were built from.\r\n \r\n To create an i386 distribution package on a 64 bit system, set\r\n GOARCH=386 prior to calling dist.bat.\r\n@@ -26,4 +26,11 @@ TODO\n ----\r\n - Documentation server shortcut checkbox option\r\n \r\n+Misc\r\n+----\r\n+WiX box sizes:\r\n+ - banner size: 493x58\r\n+ - left side of dialog: 164x312\r\n+ - full dialog size: 493x312\r\n+\r\n \r\ndiff --git a/misc/dist/windows/dist.bat b/misc/dist/windows/dist.bat\nindex 0903577ef1..4ae2df58aa 100644\n--- a/misc/dist/windows/dist.bat\n+++ b/misc/dist/windows/dist.bat\n@@ -7,10 +7,14 @@ setlocal\n \r\n :: Requires Windows Installer XML (WiX), 7zip, and Mercurial (hg)\r\n \r\n+echo # Cleaning previous WiX output files\r\n+del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb>NUL\r\n+\r\n echo # Setting some variables\r\n for /f %%i in (\'hg.exe root\') do set ROOT=%%i\r\n-for /f %%i in (\'hg.exe id -n\') do set ID=%%i\r\n for /f \"tokens=3\" %%i in (\'%ROOT%\\bin\\go.exe version\') do set VER=%%i\r\n+for /f \"tokens=4\" %%i in (\'%ROOT%\\bin\\go.exe version\') do set ID=%%i\r\n+set ID=%ID:+=%\r\n if errorlevel 1 goto end\r\n \r\n echo # Getting GOARCH\r\n@@ -35,7 +39,7 @@ xcopy %ROOT%\\pkg go\\pkg /V /E /Y /I\r\n xcopy %ROOT%\\bin go\\bin /V /E /Y /I\r\n xcopy %ROOT%\\src\\pkg\\runtime\\z*.c go\\src\\pkg\\runtime /V /E /Y\r\n xcopy %ROOT%\\src\\pkg\\runtime\\z*.go go\\src\\pkg\\runtime /V /E /Y\r\n-xcopy %ROOT%\\src\\pkg\\runtime\\z*.h go\\src\\pkg\\runtime /V /E /T\r\n+xcopy %ROOT%\\src\\pkg\\runtime\\z*.h go\\src\\pkg\\runtime /V /E /Y\r\n \r\n echo # Starting zip packaging\r\n 7za a -tzip -mx=9 go.%VER%.windows-%GOARCH%.zip \"go/\"\r\ndiff --git a/misc/dist/windows/images/Banner.jpg b/misc/dist/windows/images/Banner.jpg\nnew file mode 100644\nindex 0000000000..636479614c\nBinary files /dev/null and b/misc/dist/windows/images/Banner.jpg differ\ndiff --git a/misc/dist/windows/images/Dialog.jpg b/misc/dist/windows/images/Dialog.jpg\nnew file mode 100644\nindex 0000000000..1f0ec0a313\nBinary files /dev/null and b/misc/dist/windows/images/Dialog.jpg differ\ndiff --git a/misc/dist/windows/images/DialogLeft.jpg b/misc/dist/windows/images/DialogLeft.jpg\nnew file mode 100644\nindex 0000000000..73bab89b43\nBinary files /dev/null and b/misc/dist/windows/images/DialogLeft.jpg differ\ndiff --git a/misc/dist/windows/images/gopher.ico b/misc/dist/windows/images/gopher.ico\nnew file mode 100644\nindex 0000000000..8421829d84\nBinary files /dev/null and b/misc/dist/windows/images/gopher.ico differ\ndiff --git a/misc/dist/windows/installer.wxs b/misc/dist/windows/installer.wxs\nindex 62a5e7cc0b..ee5d22c285 100644\n--- a/misc/dist/windows/installer.wxs\n+++ b/misc/dist/windows/installer.wxs\n@@ -25,7 +25,8 @@\n <!-- Version=\"$(var.Version)\" TODO: Version requires X.X.X.X format -->\r\n \r\n <Package\r\n- Id=\'*\' Keywords=\'Installer\'\r\n+ Id=\'*\' \r\n+ Keywords=\'Installer\'\r\n Description=\"The Go Programming Language Installer\"\r\n Comments=\"The Go programming language is an open source project to make programmers more productive.\"\r\n InstallerVersion=\"300\"\r\n@@ -40,21 +41,11 @@\r\n <Property Id=\"ARPHELPLINK\" Value=\"golang.org/doc/community.html\" />\r\n <Property Id=\"ARPREADME\" Value=\"golang.org\" />\r\n <Property Id=\"ARPURLINFOABOUT\" Value=\"golang.org\" />\r\n-\r\n-<!--\r\n-<Upgrade Id=\"\">\r\n- <UpgradeVersion\r\n- IncludeMaximum=\"yes\"\r\n- IncludeMinimum=\"yes\"\r\n- Language=\"1033\"\r\n- Maximum=\"\"\r\n- Minimum=\"\"\r\n- Property=\"\" />\r\n-</Upgrade>\r\n--->\r\n-\r\n+<Icon Id=\"gopher.ico\" SourceFile=\"images\\gopher.ico\"/>\r\n+<Property Id=\"ARPPRODUCTICON\" Value=\"gopher.ico\" />\r\n <Media Id=\'1\' Cabinet=\"go.cab\" EmbedCab=\"yes\" CompressionLevel=\"high\" />\r\n <Condition Message=\"Windows 2000 or greater required.\"> VersionNT >= 500</Condition>\r\n+<MajorUpgrade AllowDowngrades=\"yes\" />\r\n <SetDirectory Id=\"INSTALLDIRROOT\" Value=\"C:\\\"/>\r\n \r\n <CustomAction\r\n@@ -70,10 +61,13 @@\r\n <Directory Id=\"ProgramMenuFolder\">\r\n <Directory Id=\"GoProgramShortcutsDir\" Name=\"Go Programming Language\"/>\r\n </Directory>\r\n+ <Directory Id=\"EnvironmentEntries\">\r\n+ <Directory Id=\"GoEnvironmentEntries\" Name=\"Go Programming Language\"/>\r\n+ </Directory>\r\n <Directory Id=\"DesktopFolder\" Name=\"Desktop\"/>\r\n </Directory>\r\n \r\n-<!-- Programs Menu & Desktop Shortcuts, Registry & Environment Settings -->\r\n+<!-- Programs Menu & Desktop Shortcuts -->\r\n <DirectoryRef Id=\"GoProgramShortcutsDir\">\r\n <Component Id=\"Component_GoShortCuts\" Guid=\"f5fbfb5e-6c5c-423b-9298-21b0e3c98f4b\">\r\n <Shortcut\r\n@@ -82,6 +76,7 @@\r\n Description=\"Starts the Go documentation server (http://localhost:6060)\"\r\n Show=\"minimized\"\r\n Arguments=\'/c \"start /d[INSTALLDIR]bin godoc.exe -http=:6060 && start http://localhost:6060\"\'\r\n+ Icon=\"gopher.ico\"\r\n Target=\"[%ComSpec]\" />\r\n <Shortcut\r\n Id=\"GoDocServerDesktopShortcut\"\r\n@@ -89,6 +84,7 @@\r\n Name=\"GoDocServer\"\r\n Description=\"Starts the godoc server (http://localhost:6060)\"\r\n Show=\"minimized\"\r\n+ Icon=\"gopher.ico\"\r\n Arguments=\'/c \"start /d[INSTALLDIR]bin godoc.exe -http=:6060 && start http://localhost:6060\"\'\r\n Target=\"[%ComSpec]\" />\r\n <Shortcut\r\n@@ -102,11 +98,31 @@\r\n On=\"uninstall\" />\r\n <RegistryValue\r\n Root=\"HKCU\"\r\n- Key=\"Software\\Microsoft\\TheGoProgrammingLanguage\"\r\n+ Key=\"Software\\GoProgrammingLanguage\"\r\n+ Name=\"ShortCuts\"\r\n+ Type=\"integer\" \r\n+ Value=\"1\"\r\n+ KeyPath=\"yes\" /> \r\n+ </Component>\r\n+</DirectoryRef>\r\n+\r\n+<!-- Registry & Environment Settings -->\r\n+<DirectoryRef Id=\"GoEnvironmentEntries\">\r\n+ <Component Id=\"Component_GoEnvironment\" Guid=\"3ec7a4d5-eb08-4de7-9312-2df392c45993\">\r\n+ <RegistryKey \r\n+ Root=\"HKCU\"\r\n+ Key=\"Software\\GoProgrammingLanguage\"\r\n+ Action=\"create\" >\r\n+ <RegistryValue\r\n Name=\"installed\"\r\n Type=\"integer\"\r\n Value=\"1\"\r\n KeyPath=\"yes\" />\r\n+ <RegistryValue\r\n+ Name=\"installLocation\"\r\n+ Type=\"string\"\r\n+ Value=\"[INSTALLDIR]\" />\r\n+ </RegistryKey>\r\n <Environment\r\n Id=\"Environment\"\r\n Action=\"set\"\r\n@@ -115,6 +131,9 @@\r\n Permanent=\"no\"\r\n System=\"yes\"\r\n Value=\"[INSTALLDIR]bin\" />\r\n+ <RemoveFolder\r\n+ Id=\"GoEnvironmentEntries\"\r\n+ On=\"uninstall\" />\r\n </Component>\r\n </DirectoryRef>\r\n \r\n@@ -126,19 +145,20 @@\r\n Title=\"Go\"\r\n Level=\"1\">\r\n \r\n+ <ComponentRef Id=\"Component_GoEnvironment\" />\r\n <ComponentGroupRef Id=\"AppFiles\" />\r\n <ComponentRef Id=\"Component_GoShortCuts\" />\r\n </Feature>\r\n \r\n <!-- Update the environment -->\r\n <InstallExecuteSequence>\r\n- <Custom\r\n- Action=\"SetApplicationRootDirectory\"\r\n- Before=\"InstallFinalize\" />\r\n+ <Custom Action=\"SetApplicationRootDirectory\" Before=\"InstallFinalize\" />\r\n </InstallExecuteSequence>\r\n \r\n <!-- Include the user interface -->\r\n <WixVariable Id=\"WixUILicenseRtf\" Value=\"LICENSE\" />\r\n+<WixVariable Id=\"WixUIBannerBmp\" Value=\"images\\Banner.jpg\" />\r\n+<WixVariable Id=\"WixUIDialogBmp\" Value=\"images\\Dialog.jpg\" />\r\n <Property Id=\"WIXUI_INSTALLDIR\" Value=\"INSTALLDIR\" />\r\n <UIRef Id=\"WixUI_InstallDir\" />\r\n \r\n```
## 変更の背景
このコミットの背景には、Go言語のWindowsインストーラーの品質とユーザーエクスペリエンスを向上させるという明確な意図があります。当時のGo言語はまだ比較的新しく、クロスプラットフォーム対応、特にWindows環境での導入を容易にすることが重要でした。
具体的な変更の背景は以下の点が挙げられます。
1. **インストーラーの視覚的改善**: 従来のインストーラーは、おそらく標準的なWindowsインストーラーのUI要素をそのまま使用しており、Goプロジェクトのブランドイメージを反映していなかった可能性があります。GoのロゴやマスコットであるGopherの画像をインストーラーに組み込むことで、よりプロフェッショナルで親しみやすい印象を与えることを目指しました。
2. **バージョン管理の厳密化**: Goのソースコードツリーのクローン作成において、単にMercurialのIDを使用するだけでなく、`go.exe version`コマンドから取得した正確なバージョン情報を使用するように変更されました。これにより、インストーラーがインストールするGoのバージョンと、ビルドに使用されたソースコードのバージョンとの整合性がより確実になります。これは、特にGoの急速な開発サイクルにおいて、ユーザーが期待するバージョンを正確にインストールできるようにするために重要です。
3. **インストーラーの柔軟性向上**: 既存のGoインストールに対するアップグレード、ダウングレード、および修復機能のサポートは、ユーザーがGoのバージョンを管理する上で非常に重要な機能です。これにより、ユーザーは手動でアンインストールしてから新しいバージョンをインストールする手間を省き、よりスムーズな移行が可能になります。これは、開発者が複数のGoバージョンを試したり、特定のバージョンに固定したりするシナリオで特に役立ちます。
4. **システムレジストリへの情報記録**: インストールされたGoのバージョンやインストールパスをレジストリに記録することで、他のアプリケーションやシステムツールがGoのインストール情報をプログラム的に取得できるようになります。これは、Go開発環境に依存するIDEやビルドツール、あるいはGoのバージョンをチェックするスクリプトなどにとって有用です。
これらの変更は、Go言語がWindowsユーザーにとってよりアクセスしやすく、管理しやすい開発環境となるための重要なステップでした。
## 前提知識の解説
このコミットを理解するためには、以下の技術的な前提知識が必要です。
### 1. Windows Installer XML (WiX) Toolset
* **概要**: WiX (Windows Installer XML) Toolsetは、Microsoft Windows Installer (MSI) パッケージをXMLソースコードからビルドするためのオープンソースツールセットです。MSIは、Windowsアプリケーションのインストール、メンテナンス、削除を行うための標準的なパッケージ形式です。
* **特徴**:
* XMLベース: インストーラーの構造、ファイル、レジストリ設定、ショートカットなどをXMLで記述します。これにより、インストーラーのバージョン管理が容易になり、テキストベースの差分比較が可能になります。
* コンパイルとリンク: WiXソースファイル(`.wxs`)は、コンパイラ(`candle.exe`)によってオブジェクトファイル(`.wixobj`)にコンパイルされ、リンカー(`light.exe`)によって最終的なMSIパッケージにリンクされます。
* カスタムアクション: インストールプロセス中にカスタムのスクリプトやプログラムを実行する機能を提供します。
* UIカスタマイズ: インストーラーのユーザーインターフェース(ダイアログ、バナーなど)をカスタマイズできます。
* **関連要素**:
* `<Product>`: MSIパッケージのルート要素。製品情報、バージョン、アップグレードコードなどを定義します。
* `<Package>`: MSIパッケージの一般的な属性(キーワード、説明、インストーラーバージョンなど)を定義します。
* `<Media>`: インストールメディア(CABファイルなど)の定義。
* `<Directory>` / `<DirectoryRef>`: ファイルシステム上のディレクトリ構造を定義します。
* `<Component>`: インストールされるファイル、レジストリキー、ショートカットなどの論理的なグループ。各コンポーネントにはGUIDが割り当てられます。
* `<Feature>`: ユーザーがインストール時に選択できる機能のグループ。複数のコンポーネントを含むことができます。
* `<Shortcut>`: プログラムメニューやデスクトップに作成されるショートカット。
* `<RegistryValue>` / `<RegistryKey>`: レジストリへの書き込みを定義します。
* `<Environment>`: 環境変数の設定。
* `<Icon>`: インストーラーで使用されるアイコン。
* `<Property>`: MSIプロパティの定義。インストーラーの動作を制御したり、情報を格納したりするために使用されます。
* `<MajorUpgrade>`: メジャーアップグレードの動作を定義します。`AllowDowngrades="yes"`は、古いバージョンへのダウングレードを許可します。
* `<WixVariable>`: WiXツールセットが提供するUIテンプレートで使用される変数を設定します。例えば、バナー画像やダイアログ画像をカスタマイズするために使用されます。
* `<UIRef>`: 組み込みのUIシーケンスを参照します。
### 2. Microsoft Installer (MSI)
* **概要**: Windowsオペレーティングシステムにおけるソフトウェアのインストール、保守、削除のための標準的なパッケージ形式およびAPIです。MSIファイルは、アプリケーションのインストールに必要なすべての情報(ファイル、レジストリキー、ショートカットなど)を含むデータベースです。
* **アップグレードとダウングレード**: MSIは、製品のアップグレード(新しいバージョンへの更新)とダウングレード(古いバージョンへの戻し)をサポートするためのメカニズムを提供します。これには、`ProductCode`、`UpgradeCode`、`Version`などのプロパティが関与します。`MajorUpgrade`要素は、WiXでこれらの動作を構成するための主要な方法です。
### 3. Mercurial (hg)
* **概要**: Mercurialは、分散型バージョン管理システム(DVCS)の一つです。Gitと同様に、ソースコードの変更履歴を管理するために使用されます。
* **`hg.exe root`**: Mercurialリポジトリのルートディレクトリのパスを返します。
* **`hg.exe id -n`**: 現在の作業ディレクトリの変更セットID(リビジョンハッシュ)を返します。`-n`オプションは、数値リビジョンIDを返します。
### 4. Go言語のビルドとバージョン情報
* **`go.exe version`**: Goのコンパイラ(`go.exe`)を実行する際に、そのバージョン情報を表示するコマンドです。通常、出力は「go version go1.x.y <OS>/<ARCH>」のような形式になります。このコミットの時点(2012年)では、出力形式が現在とは異なる可能性があり、特にビルドIDや変更セット情報が含まれていたと考えられます。
* **Goのソースツリー**: Goのソースコードは、`src`、`pkg`、`bin`などのディレクトリ構造を持っています。インストーラーは、これらのディレクトリを適切に配置する必要があります。
### 5. バッチファイル (`.bat`)
* **概要**: Windowsのコマンドプロンプトで実行されるスクリプトファイルです。一連のコマンドを自動的に実行するために使用されます。
* **`setlocal`**: 環境変数の変更を現在のバッチスクリプトのスコープに限定します。
* **`for /f`**: ファイルの内容やコマンドの出力を解析し、行ごとに処理するためのコマンドです。`tokens`オプションで、行を区切って特定のトークン(単語)を抽出できます。
* **`del /F /Q /S`**: ファイルを削除するコマンド。`/F`は読み取り専用ファイルを強制削除、`/Q`は確認プロンプトなし、`/S`はサブディレクトリからも削除します。
* **`xcopy`**: ファイルやディレクトリをコピーするコマンド。`/V`はコピー後に検証、`/E`は空のディレクトリを含むサブディレクトリをコピー、`/Y`は既存のファイルを上書きする際に確認プロンプトを表示しない、`/I`はコピー元がディレクトリでコピー先が存在しない場合にディレクトリとして作成します。
これらの知識を組み合わせることで、コミットがGoのWindowsインストーラーをどのように改善し、どのような技術的選択がなされたかを深く理解できます。
## 技術的詳細
このコミットは、Go言語のWindowsインストーラーのビルドプロセスとインストーラー自体の両方にわたる重要な変更を含んでいます。
### 1. インストーラービルドスクリプト (`dist.bat`) の変更
`misc/dist/windows/dist.bat`は、GoのWindowsインストーラーをビルドするためのバッチスクリプトです。
* **WiX出力ファイルのクリーンアップ**:
```diff
+echo # Cleaning previous WiX output files
+del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb>NUL
```
インストーラーをビルドする前に、以前のWiXビルドによって生成された中間ファイル(`.wixobj`、`AppFiles.wxs`、`.wixpdb`)を削除するステップが追加されました。これにより、クリーンなビルドが保証され、古いビルドアーティファクトによる問題が防止されます。
* **Goバージョン情報の取得方法の変更**:
```diff
-for /f %%i in ('hg.exe id -n') do set ID=%%i
for /f "tokens=3" %%i in ('%ROOT%\bin\go.exe version') do set VER=%%i
+for /f "tokens=4" %%i in ('%ROOT%\bin\go.exe version') do set ID=%%i
+set ID=%ID:+=%
```
以前はMercurialの変更セットID (`hg.exe id -n`) を使用していましたが、この変更により、`go.exe version`コマンドの出力から直接バージョン情報とビルドIDを取得するようになりました。
* `for /f "tokens=3" %%i in ('%ROOT%\bin\go.exe version') do set VER=%%i`: `go.exe version`の出力の3番目のトークン(例: `go1.0.1`のようなバージョン文字列)を`VER`変数に設定します。
* `for /f "tokens=4" %%i in ('%ROOT%\bin\go.exe version') do set ID=%%i`: 同様に、4番目のトークン(例: `+8d7ee2b9987d`のようなビルドID)を`ID`変数に設定します。
* `set ID=%ID:+=%`: 取得した`ID`から`+`記号を削除します。これは、MercurialのIDが`+`で始まる場合があるため、ファイル名などに使用する際に問題が発生しないようにするためと考えられます。
この変更は、インストーラーがGoの公式ビルドツールチェーンによって報告される正確なバージョン情報に基づいて動作することを保証します。
* **ランタイムファイルのコピー方法の修正**:
```diff
-xcopy %ROOT%\src\pkg\runtime\z*.h go\src\pkg\runtime /V /E /T
+xcopy %ROOT%\src\pkg\runtime\z*.h go\src\pkg\runtime /V /E /Y
```
`xcopy`コマンドのオプションが`/T`から`/Y`に変更されました。
* `/T`: ディレクトリ構造のみをコピーし、ファイルはコピーしません。
* `/Y`: 既存のファイルを上書きする際に確認プロンプトを表示しません。
この変更は、`z*.h`ファイル(おそらくGoランタイムの内部ヘッダーファイル)が実際にコピーされるようにするための修正です。
### 2. WiXインストーラー定義ファイル (`installer.wxs`) の変更
`misc/dist/windows/installer.wxs`は、Windowsインストーラーの構造と動作を定義するXMLファイルです。
* **パッケージIDの柔軟性向上**:
```diff
-<Package
- Id='*' Keywords='Installer'
+<Package
+ Id='*'
+ Keywords='Installer'
```
`<Package>`要素の`Id`属性が`*`に設定されています。これは、MSIパッケージの`ProductCode`がビルドごとに自動的に生成されることを意味します。これにより、各ビルドがユニークな識別子を持つことが保証されます。
* **インストーラーUIへの画像埋め込み**:
新しい画像ファイル(`Banner.jpg`, `Dialog.jpg`, `DialogLeft.jpg`, `gopher.ico`)が追加され、これらがインストーラーのUIに組み込まれるようになりました。
```xml
<Icon Id="gopher.ico" SourceFile="images\gopher.ico"/>
<Property Id="ARPPRODUCTICON" Value="gopher.ico" />
...
<WixVariable Id="WixUIBannerBmp" Value="images\Banner.jpg" />
<WixVariable Id="WixUIDialogBmp" Value="images\Dialog.jpg" />
```
* `<Icon>`: `gopher.ico`をインストーラーのアイコンとして定義し、`ARPPRODUCTICON`プロパティを通じて「プログラムの追加と削除」に表示されるアイコンとして設定されます。
* `<WixVariable>`: WiXの標準UI(`WixUI_InstallDir`など)で使用される変数を設定します。`WixUIBannerBmp`はインストーラー上部のバナー画像、`WixUIDialogBmp`はダイアログの背景画像として使用されます。これにより、インストーラーにGoのブランドイメージが視覚的に統合されます。
* **メジャーアップグレードとダウングレードのサポート**:
```diff
-<Upgrade Id="">
- ... (コメントアウトされたアップグレード関連のXML) ...
-</Upgrade>
+<MajorUpgrade AllowDowngrades="yes" />
```
以前はコメントアウトされていたアップグレード関連のXMLが削除され、代わりに`<MajorUpgrade AllowDowngrades="yes" />`が追加されました。
* `<MajorUpgrade>`: MSIのメジャーアップグレード機能を有効にします。これにより、インストーラーは既存の古いバージョンを自動的にアンインストールし、新しいバージョンをインストールすることができます。
* `AllowDowngrades="yes"`: 通常、MSIは古いバージョンを新しいバージョンで上書きすることを許可しませんが、この属性を設定することで、古いバージョンへのダウングレードも可能になります。これは、開発者が特定のGoバージョンに戻す必要がある場合に非常に便利です。
* **レジストリと環境変数の設定の改善**:
インストーラーは、Goのインストールに関する情報をレジストリに書き込み、Goの実行可能ファイルへのパスをシステム環境変数に追加するようになりました。
```diff
-<RegistryValue
- Root="HKCU"
- Key="Software\Microsoft\TheGoProgrammingLanguage"
- Name="installed"
- Type="integer"
- Value="1"
- KeyPath="yes" />
+<Directory Id="EnvironmentEntries">
+ <Directory Id="GoEnvironmentEntries" Name="Go Programming Language"/>
+</Directory>
...
+<!-- Registry & Environment Settings -->
+<DirectoryRef Id="GoEnvironmentEntries">
+ <Component Id="Component_GoEnvironment" Guid="3ec7a4d5-eb08-4de7-9312-2df392c45993">
+ <RegistryKey
+ Root="HKCU"
+ Key="Software\GoProgrammingLanguage"
+ Action="create" >
+ <RegistryValue
+ Name="installed"
+ Type="integer"
+ Value="1"
+ KeyPath="yes" />
+ <RegistryValue
+ Name="installLocation"
+ Type="string"
+ Value="[INSTALLDIR]" />
+ </RegistryKey>
<Environment
Id="Environment"
Action="set"
Name="Path"
Part="last"
Permanent="no"
System="yes"
Value="[INSTALLDIR]bin" />
+ <RemoveFolder
+ Id="GoEnvironmentEntries"
+ On="uninstall" />
</Component>
</DirectoryRef>
...
+ <ComponentRef Id="Component_GoEnvironment" />
```
* 新しいディレクトリ構造(`EnvironmentEntries`、`GoEnvironmentEntries`)が導入され、レジストリと環境変数の設定を管理する新しいコンポーネント`Component_GoEnvironment`が作成されました。
* レジストリキーのパスが`Software\Microsoft\TheGoProgrammingLanguage`から`Software\GoProgrammingLanguage`に変更され、より簡潔になりました。
* `installed`という値に加えて、`installLocation`という文字列値が追加され、Goのインストールパスがレジストリに記録されるようになりました。これは、他のプログラムがGoのインストール場所を簡単に特定できるようにするために有用です。
* 環境変数`Path`への追加は、Goの実行可能ファイル(`go.exe`など)がコマンドプロンプトから直接実行できるようにするために不可欠です。
* アンインストール時にレジストリキーと環境変数が適切に削除されるように、`RemoveFolder`要素が追加されました。
* これらの新しいコンポーネントは、インストーラーの機能(`Feature`)に参照として追加され、インストール時に実行されるように設定されます。
* **ショートカットアイコンの追加**:
```diff
- Arguments='/c "start /d[INSTALLDIR]bin godoc.exe -http=:6060 && start http://localhost:6060"'
+ Arguments='/c "start /d[INSTALLDIR]bin godoc.exe -http=:6060 && start http://localhost:6060"'
+ Icon="gopher.ico"
```
プログラムメニューとデスクトップに作成される`godoc`サーバーのショートカットに、`gopher.ico`がアイコンとして設定されました。これにより、ショートカットの視覚的な識別性が向上します。
### 3. READMEファイルの更新
`misc/dist/windows/README`ファイルも、インストーラーのビルドに関する情報が更新されました。
* **7Zipの依存関係の表記修正**:
`7Zip (command-line version)`の表記が`7Zip (command line version)`に修正されました。これは軽微な修正ですが、ドキュメントの正確性を保つためのものです。
* **パッケージング手順の明確化**:
```diff
-Ensure the working directory reflects the toolset version;
-the packager clones the Go directory it resides in and copies the
-pre-built toolchain over into the cloned folder.
+The packaging needs to be done from within a tracked Go folder.
+Packages are built by cloning the same version of the source tree
+that the Go tools were built from.
```
パッケージングの前提条件がより明確に記述されました。インストーラーのビルドは、Mercurialによって追跡されているGoのソースフォルダ内で行う必要があり、パッケージはGoツールがビルドされたのと同じバージョンのソースツリーをクローンして作成されることが強調されています。これは、ビルドの再現性と整合性を確保するために重要です。
* **WiX UIのサイズ情報追加**:
```
+Misc
+----
+WiX box sizes:
+ - banner size: 493x58
+ - left side of dialog: 164x312
+ - full dialog size: 493x312
```
WiXインストーラーのUI要素(バナー、ダイアログの左側、フルダイアログ)の推奨サイズが追記されました。これは、将来のUIカスタマイズや画像作成の際に役立つ情報です。
これらの技術的詳細は、GoのWindowsインストーラーが単なるファイルコピーではなく、Windowsの標準的なインストールメカニズムと統合され、より洗練されたユーザーエクスペリエンスを提供するように進化していることを示しています。
## コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更箇所は、主に以下の3つのファイルに集中しています。
1. **`misc/dist/windows/dist.bat`**: インストーラービルドスクリプト
* WiX中間ファイルのクリーンアップ処理の追加。
* Goバージョン情報の取得方法をMercurial IDから`go.exe version`の出力に変更。
* ランタイムヘッダーファイルのコピーオプションの修正。
```diff
--- a/misc/dist/windows/dist.bat
+++ b/misc/dist/windows/dist.bat
@@ -7,10 +7,14 @@ setlocal
:: Requires Windows Installer XML (WiX), 7zip, and Mercurial (hg)
+echo # Cleaning previous WiX output files
+del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb>NUL
+
echo # Setting some variables
for /f %%i in ('hg.exe root') do set ROOT=%%i
-for /f %%i in ('hg.exe id -n') do set ID=%%i
for /f "tokens=3" %%i in ('%ROOT%\bin\go.exe version') do set VER=%%i
+for /f "tokens=4" %%i in ('%ROOT%\bin\go.exe version') do set ID=%%i
+set ID=%ID:+=%
if errorlevel 1 goto end
echo # Getting GOARCH
@@ -35,7 +39,7 @@ xcopy %ROOT%\pkg go\pkg /V /E /Y /I
xcopy %ROOT%\bin go\bin /V /E /Y /I
xcopy %ROOT%\src\pkg\runtime\\z*.c go\src\pkg\runtime /V /E /Y
xcopy %ROOT%\src\pkg\runtime\\z*.go go\src\pkg\runtime /V /E /Y
-xcopy %ROOT%\src\pkg\runtime\\z*.h go\src\pkg\runtime /V /E /T
+xcopy %ROOT%\src\pkg\runtime\\z*.h go\src\pkg\runtime /V /E /Y
echo # Starting zip packaging
7za a -tzip -mx=9 go.%VER%.windows-%GOARCH%.zip "go/"
```
2. **`misc/dist/windows/installer.wxs`**: WiXインストーラー定義ファイル
* インストーラーUIへのGo関連画像の埋め込み設定。
* メジャーアップグレードとダウングレードを許可する設定の追加。
* レジストリへのインストールパス記録と環境変数設定の改善。
* ショートカットへのGopherアイコンの追加。
```diff
--- a/misc/dist/windows/installer.wxs
+++ b/misc/dist/windows/installer.wxs
@@ -25,7 +25,8 @@
<!-- Version="$(var.Version)" TODO: Version requires X.X.X.X format -->
<Package
- Id='*' Keywords='Installer'
+ Id='*'
+ Keywords='Installer'
Description="The Go Programming Language Installer"
Comments="The Go programming language is an open source project to make programmers more productive."
InstallerVersion="300"
@@ -40,21 +41,11 @@
<Property Id="ARPHELPLINK" Value="golang.org/doc/community.html" />
<Property Id="ARPREADME" Value="golang.org" />
<Property Id="ARPURLINFOABOUT" Value="golang.org" />
-
-<!--
-<Upgrade Id="">
- <UpgradeVersion
- IncludeMaximum="yes"
- IncludeMinimum="yes"
- Language="1033"
- Maximum=""
- Minimum=""
- Property="" />
-</Upgrade>
--->
-
+<Icon Id="gopher.ico" SourceFile="images\gopher.ico"/>
+<Property Id="ARPPRODUCTICON" Value="gopher.ico" />
<Media Id='1' Cabinet="go.cab" EmbedCab="yes" CompressionLevel="high" />
<Condition Message="Windows 2000 or greater required."> VersionNT >= 500</Condition>
+<MajorUpgrade AllowDowngrades="yes" />
<SetDirectory Id="INSTALLDIRROOT" Value="C:\"/>
<CustomAction
@@ -70,10 +61,13 @@
<Directory Id="ProgramMenuFolder">
<Directory Id="GoProgramShortcutsDir" Name="Go Programming Language"/>
</Directory>
+ <Directory Id="EnvironmentEntries">
+ <Directory Id="GoEnvironmentEntries" Name="Go Programming Language"/>
+ </Directory>
<Directory Id="DesktopFolder" Name="Desktop"/>
</Directory>
-<!-- Programs Menu & Desktop Shortcuts, Registry & Environment Settings -->
+<!-- Programs Menu & Desktop Shortcuts -->
<DirectoryRef Id="GoProgramShortcutsDir">
<Component Id="Component_GoShortCuts" Guid="f5fbfb5e-6c5c-423b-9298-21b0e3c98f4b">
<Shortcut
@@ -82,6 +76,7 @@
Description="Starts the Go documentation server (http://localhost:6060)"
Show="minimized"
Arguments='/c "start /d[INSTALLDIR]bin godoc.exe -http=:6060 && start http://localhost:6060"'
+ Icon="gopher.ico"
Target="[%ComSpec]" />
<Shortcut
Id="GoDocServerDesktopShortcut"
@@ -89,6 +84,7 @@
Name="GoDocServer"
Description="Starts the godoc server (http://localhost:6060)"
Show="minimized"
+ Icon="gopher.ico"
Arguments='/c "start /d[INSTALLDIR]bin godoc.exe -http=:6060 && start http://localhost:6060"'
Target="[%ComSpec]" />
<Shortcut
@@ -102,11 +98,31 @@
On="uninstall" />
<RegistryValue
Root="HKCU"
- Key="Software\Microsoft\TheGoProgrammingLanguage"
+ Key="Software\GoProgrammingLanguage"
+ Name="ShortCuts"
+ Type="integer"
+ Value="1"
+ KeyPath="yes" />
+ </Component>
+</DirectoryRef>
+
+<!-- Registry & Environment Settings -->
+<DirectoryRef Id="GoEnvironmentEntries">
+ <Component Id="Component_GoEnvironment" Guid="3ec7a4d5-eb08-4de7-9312-2df392c45993">
+ <RegistryKey
+ Root="HKCU"
+ Key="Software\GoProgrammingLanguage"
+ Action="create" >
+ <RegistryValue
Name="installed"
Type="integer"
Value="1"
KeyPath="yes" />
+ <RegistryValue
+ Name="installLocation"
+ Type="string"
+ Value="[INSTALLDIR]" />
+ </RegistryKey>
<Environment
Id="Environment"
Action="set"
@@ -115,6 +131,9 @@
Permanent="no"
System="yes"
Value="[INSTALLDIR]bin" />
+ <RemoveFolder
+ Id="GoEnvironmentEntries"
+ On="uninstall" />
</Component>
</DirectoryRef>
@@ -126,19 +145,20 @@
Title="Go"
Level="1">
+ <ComponentRef Id="Component_GoEnvironment" />
<ComponentGroupRef Id="AppFiles" />
<ComponentRef Id="Component_GoShortCuts" />
</Feature>
<!-- Update the environment -->
<InstallExecuteSequence>
- <Custom
- Action="SetApplicationRootDirectory"
- Before="InstallFinalize" />
+ <Custom Action="SetApplicationRootDirectory" Before="InstallFinalize" />
</InstallExecuteSequence>
<!-- Include the user interface -->
<WixVariable Id="WixUILicenseRtf" Value="LICENSE" />
+<WixVariable Id="WixUIBannerBmp" Value="images\Banner.jpg" />
+<WixVariable Id="WixUIDialogBmp" Value="images\Dialog.jpg" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
<UIRef Id="WixUI_InstallDir" />
```
3. **`misc/dist/windows/README`**: ドキュメントファイル
* パッケージング手順の明確化とWiX UIサイズの追記。
```diff
--- a/misc/dist/windows/README
+++ b/misc/dist/windows/README
@@ -4,7 +4,7 @@ and installer (msi) format.
Dependencies
============
- Windows Installer XML (WiX) toolset: http://wix.sourceforge.net/
-- 7Zip (command-line version): http://www.7-zip.org/download.html
+- 7Zip (command line version): http://www.7-zip.org/download.html
- Mercurial (hg): http://mercurial.selenic.com/
@@ -13,9 +13,9 @@ Packaging
The dependencies must be callable from dist.bat, therefore,
they'll need to be in/added to the system's search PATH.
-Ensure the working directory reflects the toolset version;
-the packager clones the Go directory it resides in and copies the
-pre-built toolchain over into the cloned folder.
+The packaging needs to be done from within a tracked Go folder.
+Packages are built by cloning the same version of the source tree
+that the Go tools were built from.
To create an i386 distribution package on a 64 bit system, set
GOARCH=386 prior to calling dist.bat.
@@ -26,4 +26,11 @@ TODO
----
- Documentation server shortcut checkbox option
+Misc
+----
+WiX box sizes:
+ - banner size: 493x58
+ - left side of dialog: 164x312
+ - full dialog size: 493x312
+
```
## コアとなるコードの解説
### `misc/dist/windows/dist.bat` の変更点
* **WiX出力ファイルのクリーンアップ**:
`del /F /Q /S *.wixobj AppFiles.wxs *.wixpdb>NUL` は、WiXのビルドプロセスで生成される一時ファイルや出力ファイルを削除します。これにより、ビルドのたびにクリーンな状態から開始され、以前のビルドの残骸による潜在的な問題を回避できます。特に、`*.wixobj`はコンパイルされたオブジェクトファイル、`AppFiles.wxs`は動的に生成される可能性のあるファイル、`*.wixpdb`はデバッグ情報を含むファイルです。
* **Goバージョン情報の取得**:
`for /f "tokens=3" %%i in ('%ROOT%\bin\go.exe version') do set VER=%%i` と `for /f "tokens=4" %%i in ('%ROOT%\bin\go.exe version') do set ID=%%i` は、`go.exe version` コマンドの出力を解析して、Goのバージョン (`VER`) とビルドID (`ID`) を抽出します。当時の `go.exe version` の出力形式が「go version go1.0.1 +8d7ee2b9987d windows/amd64」のような形式であったと仮定すると、`tokens=3` は `go1.0.1` を、`tokens=4` は `+8d7ee2b9987d` を取得します。
`set ID=%ID:+=%` は、取得したビルドIDから先頭の `+` 記号を削除します。これは、ファイル名やその他の識別子として使用する際に、特殊文字が問題を引き起こすのを防ぐためです。この変更により、インストーラーがGoツールチェーン自体が報告する正確なバージョン情報に基づいて動作するようになり、ビルドの整合性が向上します。
* **ランタイムヘッダーファイルのコピー**:
`xcopy %ROOT%\src\pkg\runtime\z*.h go\src\pkg\runtime /V /E /Y` は、Goのランタイム関連のヘッダーファイル(`z*.h`)をコピーします。以前の `/T` オプションはディレクトリ構造のみをコピーし、ファイル自体はコピーしないため、この変更はこれらのヘッダーファイルが実際にインストールパッケージに含まれるようにするための修正です。`/Y` オプションは、既存のファイルを上書きする際に確認プロンプトを表示しないようにします。
### `misc/dist/windows/installer.wxs` の変更点
* **インストーラーUIのカスタマイズ**:
`<Icon Id="gopher.ico" SourceFile="images\gopher.ico"/>` と `<Property Id="ARPPRODUCTICON" Value="gopher.ico" />` は、Gopherのアイコンをインストーラーの実行ファイルと「プログラムの追加と削除」リストに表示されるアイコンとして設定します。
`<WixVariable Id="WixUIBannerBmp" Value="images\Banner.jpg" />` と `<WixVariable Id="WixUIDialogBmp" Value="images\Dialog.jpg" />` は、WiXの標準UIテンプレートで使用される変数を設定し、インストーラーのバナーとダイアログの背景にカスタム画像を表示できるようにします。これにより、インストーラーの視覚的なブランドイメージが向上します。
* **メジャーアップグレードとダウングレードのサポート**:
`<MajorUpgrade AllowDowngrades="yes" />` は、WiXのメジャーアップグレード機能を有効にします。これにより、インストーラーは既存のGoのインストールを検出し、新しいバージョンへのアップグレード、または古いバージョンへのダウングレードを自動的に処理できるようになります。`AllowDowngrades="yes"` は、通常は許可されないダウングレード操作を明示的に許可します。これは、ユーザーがGoの特定のバージョンに戻す必要がある場合に非常に有用な機能です。
* **レジストリと環境変数の設定**:
新しい `<Directory>` と `<Component>` 要素(`GoEnvironmentEntries` と `Component_GoEnvironment`)が導入され、Goのインストールに関するレジストリ情報と環境変数を管理します。
`<RegistryKey Root="HKCU" Key="Software\GoProgrammingLanguage" Action="create">` は、現在のユーザーのレジストリハイブに `Software\GoProgrammingLanguage` というキーを作成します。
その中に `<RegistryValue Name="installed" Type="integer" Value="1" KeyPath="yes" />` でインストール済みであることを示すフラグを、`<RegistryValue Name="installLocation" Type="string" Value="[INSTALLDIR]" />` でGoのインストールパスを記録します。`KeyPath="yes"` は、このレジストリ値がコンポーネントのキーパスであることを示し、コンポーネントのインストール状態を決定するために使用されます。
`<Environment Id="Environment" Action="set" Name="Path" Part="last" Permanent="no" System="yes" Value="[INSTALLDIR]bin" />` は、Goの `bin` ディレクトリをシステム全体の `Path` 環境変数に追加します。これにより、コマンドプロンプトから `go` コマンドを直接実行できるようになります。
`<RemoveFolder Id="GoEnvironmentEntries" On="uninstall" />` は、アンインストール時にレジストリキーと関連する環境変数が適切に削除されることを保証します。
これらのコンポーネントは `<Feature>` 要素内で参照され、インストーラーの実行時にこれらの設定が適用されるようにします。
### `misc/dist/windows/README` の変更点
* **パッケージング手順の明確化**:
「The packaging needs to be done from within a tracked Go folder. Packages are built by cloning the same version of the source tree that the Go tools were built from.」という記述は、インストーラーをビルドする際の重要な前提条件を明確にしています。これは、ビルドの再現性を確保し、インストーラーがGoの特定のバージョンと正確に対応するようにするために不可欠です。
* **WiX UIサイズの追記**:
WiXインストーラーのUI要素(バナー、ダイアログの左側、フルダイアログ)の推奨サイズが追加されました。これは、将来的にインストーラーのUIをカスタマイズする開発者にとって、適切な画像サイズを設計するためのガイドラインとなります。
これらの変更は、GoのWindowsインストーラーがより堅牢で、ユーザーフレンドリーで、Goプロジェクトのブランドイメージを反映したものになるように、細部にわたる配慮がなされていることを示しています。
## 関連リンク
* **WiX Toolset 公式サイト**: [https://wixtoolset.org/](https://wixtoolset.org/)
* **Windows Installer (MSI) について**: [https://learn.microsoft.com/ja-jp/windows/win32/msi/windows-installer-portal](https://learn.microsoft.com/ja-jp/windows/win32/msi/windows-installer-portal)
* **Mercurial 公式サイト**: [https://www.mercurial-scm.org/](https://www.mercurial-scm.org/)
* **Go言語 公式サイト**: [https://go.dev/](https://go.dev/)
## 参考にした情報源リンク
* WiX Toolset Documentation: 各XML要素(`Package`, `MajorUpgrade`, `RegistryValue`, `Environment`, `WixVariable`など)の公式ドキュメントを参照しました。
* Microsoft Learn - Windows Installer: MSIの基本的な概念と動作について理解を深めるために参照しました。
* Mercurial Command-Line Reference: `hg.exe root` や `hg.exe id -n` の動作を確認するために参照しました。
* Go言語の過去のリリースノートやコミット履歴: 2012年当時のGoのバージョン管理やインストーラー開発の文脈を理解するために、Goの公式リポジトリの関連コミットやメーリングリストの議論を参考にしました。
* Stack Overflow や技術ブログ: WiXやバッチスクリプトの具体的な構文や一般的な使用例について、必要に応じて参照しました。