為 Electron 建立 WinML 外掛

本指南將教你如何在 Electron 應用程式中建立一個使用 Windows Machine Learning(WinML) 的 C# 原生外掛。 WinML 允許你在 Windows 裝置上本地執行machine learning model(ONNX 格式),用於影像分類、物件偵測等任務。

先決條件

備註

WinML 可在任何 Windows 10(1809+)或 Windows 11 裝置上執行。 為了最佳效能,建議使用有 GPU 或 NPU 的裝置,但 API 也能支援 CPU。

步驟 1:建立一個 C# 原生外掛

npx winapp node create-addon --template cs --name winMlAddon

這會建立一個 winMlAddon/ 資料夾,其中包含已配置的 C# 專案,並包含 Windows SDK 和 Windows App SDK 參考。

建立附加元件:

npm run build-winMlAddon

步驟 2:下載 SqueezeNet 模型

  1. 安裝 AI 開發者圖庫
  2. 前往 分類影像 範例
  3. 下載 SqueezeNet 1.1 模型
  4. .onnx 檔案複製到 project 根目錄裡的 models/ 資料夾

備註

此模型也可從 ONNX Model Zoo GitHub 倉庫下載。

步驟 3:新增所需的 NuGet 套件

在你的專案根目錄中更新 Directory.packages.props

<PackageVersion Include="Microsoft.ML.OnnxRuntime.Extensions" Version="0.14.0" />
<PackageVersion Include="System.Drawing.Common" Version="9.0.9" />

更新 winMlAddon/winMlAddon.csproj 來添加套件引用:

<PackageReference Include="Microsoft.ML.OnnxRuntime.Extensions" />
<PackageReference Include="System.Drawing.Common" />

步驟 4:加入範例程式碼

AI 開發畫廊提供了 SqueezeNet 影像分類的完整實作。 你可以在 electron-winml 樣本中找到改編後的程式碼。

從範例複製 winMlAddon/ 資料夾,或用範例程式碼手動更新 winMlAddon/addon.cs

重要實作詳細數據

Project根路徑:外掛要求 JavaScript 程式碼傳遞project根路徑,以便定位 ONNX 模型及原生相依關係。

預載原生相依性:外掛包含一種載入必要 DLL 的方法,適用於開發與生產場景。

Electron Forge 設定:設定你的封包器解壓原生檔案:

module.exports = {
  packagerConfig: {
    asar: {
      unpack: "**/*.{dll,exe,node,onnx}"
    },
    ignore: [
      /^\/.winapp\//,
      "\\.msix$",
      /^\/winMlAddon\/(?!dist).+/
    ]
  },
};

步驟五:建立外掛

npm run build-winMlAddon

步驟 6:測試外掛

打開 src/index.js 並裝入附加元件:

const winMlAddon = require('../winMlAddon/dist/winMlAddon.node');

新增測試函數:

const testWinML = async () => {
  try {
    let projectRoot = path.join(__dirname, '..');
    if (projectRoot.includes('app.asar')) {
      projectRoot = projectRoot.replace('app.asar', 'app.asar.unpacked');
    }

    const addon = await winMlAddon.Addon.createAsync(projectRoot);
    console.log('Model loaded successfully!');

    const imagePath = path.join(projectRoot, 'test-images', 'sample.jpg');
    const predictions = await addon.classifyImage(imagePath);

    console.log('Top predictions:');
    predictions.slice(0, 5).forEach((pred, i) => {
      console.log(`${i + 1}. ${pred.label}: ${(pred.confidence * 100).toFixed(2)}%`);
    });
  } catch (error) {
    console.error('Error testing WinML:', error.message);
  }
};

先建立一個包含範例圖片的資料夾來準備測試影像 test-images/ ,然後執行:

npm start

步驟 7:更新除錯身份

npx winapp node add-electron-debug-identity

備註

Electron 應用程式封裝稀疏,導致 Windows 出現一個已知的錯誤,可能導致當機或視窗空白。 請參考 設定指南 了解解決方法。

下一步