⚡️

Mac環境でElectronアプリをWindows用にパッケージングしようとしたけど途中で諦めた話

2024/12/30に公開

Mac book Pro M1 チップ
MacOs Sonoma ver14.2.1


Msc 環境で、Electron Forge で Windows バイナリを作成しようといろいろ試みたけど、エラー解決できず途中で諦めた。
その時の備忘録です。
Mac 環境での Windows バイナリ作成に成功した人がいたら教えて下さい。

wine と mono が必要?

Mac で Windows 用バイナリを作成するにはこの wine が必要らしい。

Electron Forge の公式サイトには Mono と Wine のインストールが必要とある。
Wine は、Linux や macOS などの非 Windows オペレーティングシステム上で Windows 用ソフトウェアを実行するための互換レイヤーですが、Mono とはよく分からないので ChatGPT 先生に聞いてみた。

wine と mono の違い
項目 wine mono
目的 Windows アプリケーションの実行 .NET アプリケーションの実行
対象 Windows API .NET Framework および C#
アプローチ Windows API の再実装と互換性の提供 .NET ランタイムとライブラリの再実装
クロスプラットフォーム Linux/macOS 上で Windows プログラムを動かす Linux/macOS 上で.NET アプリを動かす
実行環境 Windows バイナリ(.exe ファイル)を直接動かす .NET アプリケーション(.dll や.exe ファイル)を動かす

wine と mono の役割

  • Wine: Windows API を再現する互換レイヤーで、Electron Builder が Windows 用バイナリ(exe やインストーラー)を生成する際に必要です。特に NSIS(Nullsoft Scriptable Install System)インストーラーを生成する場合、Windows 用ツールが必要で、それをエミュレートするのに Wine が利用されます。

  • Mono: Mono は.NET アプリケーションの実行やビルドに使用されますが、Electron アプリの Windows 用パッケージングでは基本的に必要ありません。Electron Builder が Mono を要求することはありません。

公式で書かれているので、Mono と Wine をインストールする。(Mono をインストールせずに実行したら Mono がない!と怒られたので、Mono は必須です。)

wine, mono のインストール

brew update
brew upgrade

# XQuartzをインストール(WineはXQuartzに依存します)
brew install --cask xquartz

# WineはIntel CPUようなので、Rosetta2をインストールする
softwareupdate --install-rosetta --agree-to-license

# wineインストール
brew install --cask wine-stable

# monoインストール
brew install mono

.zshrc に追記する

# mono環境変数
export MONO_GAC_PREFIX="/opt/homebrew"

このままでは Wine を使おうとするとブロックされるので、下記の設定をします。

  • [システム設定]>>[プライバシーとセキュリティ]を選択
    「wine stable は開発元を確認できないため、使用がブロックされました」の右下「このまま開く」をクリック
    001
  • 「許可する」
    002
    しばらくするとこれが出てくるので、閉じる
    003

日本語化対策

# winetrickを入れる
arch -arm64 brew install winetricks

# cjkfontsを入れる
winetricks cjkfonts

# wineを再起動する
wineserver -k && wineboot

パッケージング

maker-squirrel をインストールしておきます。

npm install --save-dev @electron-forge/maker-squirrel

forge.config.js と package.json はこんな感じです。

forge.config.js
const { FusesPlugin } = require("@electron-forge/plugin-fuses");
const { FuseV1Options, FuseVersion } = require("@electron/fuses");

module.exports = {
  packagerConfig: {
    asar: true,
  },
  rebuildConfig: {},
  makers: [
    {
      name: "@electron-forge/maker-squirrel",
      platforms: ["win32"], // Windows用のパッケージを作成するために追加
      config: {},
    },
    {
      name: "@electron-forge/maker-zip",
      platforms: ["darwin"],
    },
    {
      name: "@electron-forge/maker-deb",
      platforms: ["linux"], // Linux用のパッケージを作成するために追加
      config: {},
    },
    {
      name: "@electron-forge/maker-rpm",
      platforms: ["linux"], // Linux用のパッケージを作成するために追加
      config: {},
    },
  ],
  plugins: [
    {
      name: "@electron-forge/plugin-auto-unpack-natives",
      config: {},
    },
    new FusesPlugin({
      version: FuseVersion.V1,
      [FuseV1Options.RunAsNode]: false,
      [FuseV1Options.EnableCookieEncryption]: true,
      [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
      [FuseV1Options.EnableNodeCliInspectArguments]: false,
      [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
      [FuseV1Options.OnlyLoadAppFromAsar]: true,
    }),
  ],
};
package.json
{
  "name": "sample-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make"
  },
  "author": "Dipolecats",
  "license": "MIT",
  "keywords": [],
  "description": "Hello World!",
  "devDependencies": {
    "@electron-forge/cli": "^7.6.0",
    "@electron-forge/maker-deb": "^7.6.0",
    "@electron-forge/maker-rpm": "^7.6.0",
    "@electron-forge/maker-squirrel": "^7.6.0",
    "@electron-forge/maker-zip": "^7.6.0",
    "@electron-forge/plugin-auto-unpack-natives": "^7.6.0",
    "@electron-forge/plugin-fuses": "^7.6.0",
    "@electron/fuses": "^1.8.0",
    "electron": "^33.2.1"
  },
  "dependencies": {
    "electron-squirrel-startup": "^1.0.1"
  }
}
npx electron-forge make --platform win32 --arch x64

大量のエラーが出たのでここで諦めました。
対処方法知っている方いたら教えて下さい。

007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
007c:fixme:hid:handle_IRP_MN_QUERY_ID Unhandled type 00000005
0088:fixme:keyboard:NtUserActivateKeyboardLayout Changing user locale is not supported
00cc:fixme:keyboard:NtUserActivateKeyboardLayout Changing user locale is not supported
0024:err:kerberos:kerberos_LsaApInitializePackage no Kerberos support, expect problems
0024:fixme:powrprof:PowerRegisterSuspendResumeNotification (0x00000002,000000000081FE10,000000000081FE08) stub!
0024:fixme:process:GetProcessMitigationPolicy (FFFFFFFFFFFFFFFF, 4, 000000000081FC84, 4): stub
0024:fixme:uxtheme:SetPreferredAppMode 1: stub
0024:fixme:heap:RtlSetHeapInformation HEAP_INFORMATION_CLASS 1 not implemented!

0024:fixme:winstation:GetUserObjectSecurity (0000000000000054 000000000081F690 0000000000000000 len=0 000000000081F61C),stub!
0024:fixme:winstation:GetUserObjectSecurity (0000000000000054 000000000081F690 0000000000DDE7D0 len=40 000000000081F61C),stub!
0024:fixme:winstation:GetUserObjectSecurity (0000000000000058 000000000081F610 0000000000000000 len=0 000000000081F59C),stub!
0024:fixme:winstation:GetUserObjectSecurity (0000000000000058 000000000081F610 0000000000DDE7D0 len=40 000000000081F59C),stub!
0024:fixme:nls:RtlGetThreadPreferredUILanguages 00000038, 000000000081F5EC, 0000000000000000 000000000081F5E8
0024:fixme:nls:get_dummy_preferred_ui_language (0x38 0x411 000000000081F5EC 0000000000000000 000000000081F5E8) returning a dummy value (current locale)
0024:fixme:nls:RtlGetThreadPreferredUILanguages 00000038, 000000000081F5EC, 000000000081F5D2 000000000081F5E8
0024:fixme:nls:get_dummy_preferred_ui_language (0x38 0x411 000000000081F5EC 000000000081F5D2 000000000081F5E8) returning a dummy value (current locale)
0110:fixme:thread:NtSetInformationThread info class 24 not supported yet

Discussion