Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V této příručce se dozvíte, jak vytvořit nativní doplněk jazyka C#, který ve vaší aplikaci Electron používá Windows Machine Learning (WinML). WinML umožňuje spouštět machine learning modely (formát ONNX) místně na zařízeních s Windows pro úlohy, jako je klasifikace obrázků, detekce objektů a další.
Předpoklady
Než začnete s touto příručkou, ujistěte se, že máte:
- Dokončeno nastavení vývojového prostředí.
- Windows 11 nebo Windows 10 (verze 1809 nebo novější)
Poznámka:
WinML běží na jakémkoli zařízení Windows 10 (1809+) nebo Windows 11. Pro zajištění nejlepšího výkonu se doporučuje zařízení s GRAFICKÝmi procesory nebo NPU, ale rozhraní API funguje i na procesoru.
Důležité
Doplněk WinML vyžaduje experimental Windows App SDK. Pokud jste v winapp init průvodci nastavením vybrali stabilní sady SDK, budete muset aktualizovat verzi sady SDK. Upravte winapp.yaml a změňte verzi Microsoft.WindowsAppSDK na 2.0.0-experimental3 a potom spusťte npx winapp restore, aby se aktualizovala.
Krok 1: Vytvoření nativního doplňku jazyka C#
Pojďme vytvořit nativní doplněk, který bude používat rozhraní API WinML. Použijeme šablonu jazyka C#, která využívá node-api-dotnet k propojení JavaScriptu a C#.
npx winapp node create-addon --template cs --name winMlAddon
Tím se winMlAddon/ vytvoří složka s:
-
addon.cs– Kód v jazyce C#, který bude volat rozhraní API WinML -
winMlAddon.csproj– Projektový soubor s odkazy na sadu Windows SDK a Windows App SDK -
README.md- Dokumentace k používání doplňku
Příkaz také přidá skript build-winMlAddon do package.json pro sestavení addonů a skript clean-winMlAddon pro vyčištění artefaktů sestavení:
{
"scripts": {
"build-winMlAddon": "dotnet publish ./winMlAddon/winMlAddon.csproj -c Release",
"clean-winMlAddon": "dotnet clean ./winMlAddon/winMlAddon.csproj"
}
}
Šablona automaticky zahrnuje odkazy na obě sady SDK, takže můžete ihned volat Windows API.
Pojďme ověřit, jestli je všechno správně nastavené, a to sestavením doplňku:
# Build the C# addon
npm run build-winMlAddon
Poznámka:
Můžete také vytvořit doplněk jazyka C++ pomocí npx winapp node create-addon příznaku (bez příznaku --template ). Doplňky jazyka C++ používají node-addon-api a poskytují přímý přístup k rozhraním API Windows s maximálním výkonem. Viz průvodce doplňkem oznámení pro C++ pro návod nebo úplnou dokumentaci příkazů pro další možnosti.
Krok 2: Stažení modelu SqueezeNet a získání ukázkového kódu
Jako referenci použijeme ukázku Klasifikovat obrázek z galerie vývojářů AI . Tato ukázka používá model SqueezeNet 1.1 pro klasifikaci obrázků.
2.1. Stažení modelu
- Nainstalujte AI galerii pro vývojáře
- Přejít na ukázku Klasifikace obrazu
- Stáhněte si model SqueezeNet 1.1 (podporuje procesor, GPU a NPU).
- Kliknutím na Otevřít složku obsahující soubor vyhledejte
.onnx.
- Zkopírujte soubor
squeezenet1.1.onnxdo složkymodels/v kořenovém adresáři project.
Poznámka:
Model lze stáhnout také přímo z úložiště ONNX Model Zoo GitHub
Krok 3: Přidání požadovaných balíčků NuGet
Před přidáním kódu WinML musíme přidat další balíčky NuGet potřebné pro zpracování obrázků, modul runtime ONNX a podporu GenAI.
3.1. Aktualizace Directory.packages.props
Do souboru v kořenovém adresáři projektu přidejte následující verze Directory.packages.props balíčků (měly by být vytvořeny při vytváření doplňku):
<Project>
<PropertyGroup>
<!-- Enable central package versioning -->
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.JavaScript.NodeApi" Version="0.9.17" />
<PackageVersion Include="Microsoft.JavaScript.NodeApi.Generator" Version="0.9.17" />
<!-- Add these packages for WinML -->
+ <PackageVersion Include="Microsoft.ML.OnnxRuntime.Extensions" Version="0.14.0" />
+ <PackageVersion Include="System.Drawing.Common" Version="9.0.9" />
+ <PackageVersion Include="Microsoft.Extensions.AI" Version="9.9.1" />
+ <PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.Managed" Version="0.10.1" />
+ <PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.WinML" Version="0.10.1" />
<!-- These versions may be updated automatically during restore to match yaml -->
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="2.0.0-experimental3" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7175" />
</ItemGroup>
</Project>
3.2. Aktualizace winMlAddon.csproj
Otevřete winMlAddon/winMlAddon.csproj a přidejte odkazy na balíček do :<ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.JavaScript.NodeApi" />
<PackageReference Include="Microsoft.JavaScript.NodeApi.Generator" />
<!-- Add these packages for WinML -->
+ <PackageReference Include="Microsoft.ML.OnnxRuntime.Extensions" />
+ <PackageReference Include="System.Drawing.Common" />
+ <PackageReference Include="Microsoft.Extensions.AI" />
+ <PackageReference Include="Microsoft.ML.OnnxRuntimeGenAI.Managed" />
+ <PackageReference Include="Microsoft.ML.OnnxRuntimeGenAI.WinML" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
<PackageReference Include="Microsoft.WindowsAppSDK" />
</ItemGroup>
Co tyto balíčky dělají:
- Microsoft.ML.OnnxRuntime.Extensions – poskytuje další operátory a nástroje pro modul runtime ONNX
- System.Drawing.Common – Umožňuje načítání a manipulaci s obrázky pro předběžné zpracování.
- Microsoft. Extensions.AI – abstrakce AI pro .NET
- Microsoft.ML.OnnxRuntimeGenAI.Managed – spravované vazby pro ONNX Runtime GenAI
- Microsoft.ML.OnnxRuntimeGenAI.WinML – integrace WinML pro ONNX Runtime GenAI
Krok 4: Přidání ukázkového kódu
Galerie AI Dev zobrazuje úplnou implementaci klasifikace obrázků pomocí SqueezeNetu:
Tento kód jsme přizpůsobili pro Elektron a kompletní implementaci najdete ve vzorku elektron-winml. Složka winMlAddon/ obsahuje upravený kód z galerie vývojářů AI.
Zkopírujte celou winMlAddon/ složku z samples/elektron-winml/winMlAddon/ do kořenového adresáře projektu a nahraďte ji vytvořenou v kroku 1. Ukázka obsahuje více souborů nad rámec addon.cs (pomocné třídy v Utils/chatovacím klientovi atd.), které jsou potřeba k sestavení a spuštění doplňku.
Důležité
Musíte zkopírovat celou složku, nejen addon.cs. Doplněk závisí na pomocných Utils/ souborech v podsložce (Prediction.cs, ImageNet.cs, BitmapFunctions.csatd.).
Klíčové podrobnosti implementace
Pojďme zdůraznit důležité části implementace a klíčové rozdíly od kódu AI Dev Gallery:
Požadavek na kořenovou cestu projektu
Na rozdíl od kódu AI Dev Gallery vyžaduje náš doplněk Electron kód JavaScriptu, aby předal kořenovou cestu projektu. To je nezbytné, protože:
- Doplněk musí vyhledat soubor modelu ONNX ve
models/složce. - Nativní knihovny (DLL) je potřeba načíst z konkrétních adresářů.
[JSExport]
public static async Task<Addon> CreateAsync(string projectRoot)
{
if (!Path.Exists(projectRoot))
{
throw new Exception("Project root is invalid.");
}
var addon = new Addon(projectRoot);
addon.PreloadNativeDependencies();
string modelPath = Path.Join(projectRoot, "models", @"squeezenet1.1-7.onnx");
await addon.InitModel(modelPath, ExecutionProviderDevicePolicy.DEFAULT, null, false, null);
return addon;
}
Tím se automaticky vybere nejlepší poskytovatel spouštění (CPU, GPU nebo NPU) na základě možností zařízení.
2. Předběžné načtení nativních závislostí
Doplněk obsahuje metodu PreloadNativeDependencies() pro načtení požadovaných knihoven DLL. Tento přístup funguje pro vývojové i produkční scénáře bez nutnosti kopírovat knihovny DLL do kořenového adresáře projektu:
private void PreloadNativeDependencies()
{
// Loads required DLLs from the winMlAddon build output
// This ensures dependencies are available regardless of the execution context
}
Tato operace se volá během inicializace před načtením modelu a zajišťuje dostupnost všech nativních knihoven.
3. Konfigurace Electron Forge pro vytváření balíčků
Abyste měli jistotu, že doplněk v produkčních buildech funguje správně, je potřeba nakonfigurovat, aby váš packager fungoval správně:
- Rozbalení nativních souborů – knihovny DLL, modely ONNX a soubory .node musí být přístupné mimo archiv ASAR.
- Vyloučení nepotřebných souborů – Zachovejte malou velikost balíčku vyloučením artefaktů sestavení a dočasných souborů
Pro Electron Forge aktualizujte forge.config.js:
// From samples/electron-winml/forge.config.js
module.exports = {
packagerConfig: {
asar: {
// Unpack native files so they can be accessed by the addon
unpack: "**/*.{dll,exe,node,onnx}"
},
ignore: [
// Exclude .winapp folder (SDK packages and headers)
/^\/.winapp\//,
// Exclude MSIX packages
"\\.msix$",
// Exclude winMlAddon source files, but keep the dist folder
/^\/winMlAddon\/(?!dist).+/
]
},
// ... rest of your config
};
Co to dělá:
asar.unpack– Extrahuje knihovny DLL, spustitelné soubory, binární soubory .node a modely ONNX doapp.asar.unpacked/- Díky tomu jsou přístupné za běhu prostřednictvím cest souborového systému.
- Kód JavaScriptu upravuje cesty automaticky (viz nahrazení
app.asar→app.asar.unpacked).
ignore- Vyloučí z konečného balíčku:-
.winapp/– Balíčky a hlavičky sady SDK (není potřeba za běhu) -
.msixsoubory – zabalené výstupy -
winMlAddon/zdrojové soubory – uchovává pouzedist/složku s kompilovanými binárními soubory.
-
Poznámka:
Pokud používáte jiný nástroj pro balení (elektron-builder atd.), budete muset nakonfigurovat podobná nastavení pro rozbalení nativních závislostí a vyloučení vývojových souborů. Informace o možnostech rozbalení ASAR najdete v dokumentaci vašeho packageru.
4. Klasifikace obrázků
Metoda ClassifyImage zpracuje obrázek a vrátí předpovědi:
[JSExport]
public async Task<Prediction[]> ClassifyImage(string imagePath)
{
// Loads the image, preprocesses it, and runs inference
// Returns top predictions with labels and confidence scores
}
Kompletní implementace zpracovává:
- Načítání a předběžné zpracování obrázků (změna velikosti, normalizace)
- Spuštění inference modelu
- Výsledky následného zpracování pro získání nejlepších předpovědí s popisky a skóre spolehlivosti
Poznámka:
Úplný zdrojový kód zahrnuje předběžné zpracování obrázku, vytvoření tensoru a analýzu výsledků. Zkontrolujte ukázkovou implementaci pro všechny podrobnosti.
Principy kódu
Doplněk poskytuje tyto hlavní funkce:
- CreateAsync – Inicializuje doplněk a načte model SqueezeNet.
- ClassifyImage – přijímá cestu k obrázku a vrací výsledky klasifikace.
WinML automaticky vybere nejlepší spouštěcí zařízení (CPU, GPU nebo NPU) na základě dostupnosti.
Krok 5: Sestavení doplňku jazyka C#
Teď sestavte doplněk:
npm run build-winMlAddon
Tento kód C# se zkompiluje pomocí Native AOT (Ahead-of-Time kompilace), která:
- Vytvoří binární soubor ve formátu nativního doplňku
.node. - Ořezává nepoužívaný kód pro menší velikost balíčku.
- Vyžaduje no .NET runtime na cílových počítačích.
- Poskytuje nativní výkon.
Zkompilovaný doplněk bude v winMlAddon/dist/winMlAddon.node.
Krok 6: Otestování doplňku
Teď pojďme doplněk otestovat tak, že ho zavoláme z hlavního procesu. Otevřete src/main.js a postupujte takto:
6.1. Načtení doplňku
Nahoře přidejte příkazy require:
const winMlAddon = require('../winMlAddon/dist/winMlAddon.node');
6.2. Vytvoření testovací funkce
Přidejte tuto funkci pro testování klasifikace obrázků:
const testWinML = async () => {
console.log('Testing WinML addon...');
try {
let projectRoot = path.join(__dirname, '..');
// Adjust path for packaged apps
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!');
// Classify a sample image
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);
}
};
klíčové body:
- Úprava cesty (
app.asar→app.asar.unpacked) zajišťuje, že kód funguje ve vývojových i zabalených aplikacích. - Tím se přistupují k rozbaleným nativním souborům nakonfigurovaným v
forge.config.js
6.3. Volání testovací funkce
Přidejte tento řádek na konec createWindow() funkce:
testWinML();
6.4. Příprava testovacích imagí
Testování klasifikace obrázků:
- Vytvoření
test-images/složky v kořenovém adresáři projektu - Přidejte testovací obrázek s názvem
sample.jpg(kód očekává tento přesný název souboru). - Model SqueezeNet rozpozná 1000 různých tříd ImageNet (zvířata, objekty, scény atd.).
Po spuštění aplikace se v konzole zobrazí výsledky klasifikace.
Tip
Kompletní implementaci s obslužnými rutinami IPC, dialogovými okny pro výběr souborů a uživatelským rozhraním najdete v ukázce elektron-winml.
Krok 7: Aktualizace ladicí identity
Abychom zajistili načtení a dostupnost Windows App SDK pro použití, musíme nastavit identitu ladění, která zajistí načítání frameworku při každém spuštění naší aplikace. Stejně tak je potřeba aktualizovat identitu ladění aplikace pokaždé, když upravíte Package.appxmanifest nebo změníte prostředky, na které odkazuje manifest (například ikony aplikací). Běh:
npx winapp node add-electron-debug-identity
Tento příkaz:
- Přečte vaše
Package.appxmanifesta zjistí podrobnosti a schopnosti aplikace. - Zaregistruje
electron.exeve vašínode_moduless dočasnou identitou. - Umožňuje otestovat rozhraní API vyžadující identitu bez kompletního balíčku MSIX.
Poznámka:
Tento příkaz je již součástí postinstall skriptu, který jsme přidali v průvodci nastavením, takže se spustí automaticky po npm install. Musíte ho ale spustit ručně pokaždé, když:
- Úprava
Package.appxmanifest(změna schopností, identit nebo vlastností) - Aktualizace zdrojů aplikace (ikony, loga atd.)
Teď spusťte aplikaci:
npm start
Zkontrolujte výstup konzoly – měli byste vidět výsledky testu WinML.
⚠️ Známý problém: Chybové ukončení aplikace nebo prázdné okno (kliknutím rozbalte)
Existuje známá chyba Windows s řídkým balením aplikací Electron, která způsobuje, že aplikace se při startu zhroutí nebo nevykreslí webový obsah. Tento problém je opravený v Windows, ale zatím se nerozšířel na všechna zařízení.
Alternativní řešení najdete v části Nastavení vývojového prostředí .
Další kroky
Gratulujeme! Úspěšně jste vytvořili nativní doplněk, který dokáže spouštět modely strojového učení pomocí WinML! 🎉
Teď jste připraveni:
- Zabalení aplikace pro distribuci – Vytvoření balíčku MSIX, který můžete distribuovat
Nebo prozkoumejte další příručky:
- Vytvoření doplňku Phi Silica – Naučte se používat rozhraní API Phi Silica AI
- Přehled Začínáme – návrat k hlavnímu průvodci
Přizpůsobení vašeho modelu
Pokud chcete plně integrovat model ONNX, budete muset:
- Seznamte se se vstupy modelu – obrázky, tensory, sekvence atd.
- Vytvoření správných vstupních vazeb – Převod dat do formátu, který WinML očekává
- Zpracování výstupů – Parsování a interpretace předpovědí modelu
- Elegantní zpracování chyb – Načítání a inference modelu může selhat
Další zdroje
- Dokumentace k WinML – oficiální dokumentace k WinML
- Dokumentace k rozhraní příkazového řádku winapp – Kompletní referenční informace k rozhraní příkazového řádku
- Ukázková aplikace Elektron – kompletní funkční příklad
- Galerie AI Dev – Ukázková galerie všech rozhraní API AI
- Windows App SDK Samples – Kolekce ukázek Windows App SDK
- node-api-dotnet – knihovna interoperability javascriptového jazyka C# ↔
Troubleshooting
Sestavení selže s NU1010: Položky PackageReference nedefinují příslušnou PackageVersion
Ujistěte se, že všechny balíčky uvedené v winMlAddon.csproj mají odpovídající položky v Directory.packages.props. Úplný seznam požadovaných balíčků najdete v kroku 3.
"není platná aplikace Win32" při načítání doplňku
To znamená, že doplněk byl vytvořen pro jinou architekturu než váš modul runtime Node.js/Electron. Zkontrolujte architekturu Node.js:
node -e "console.log(process.arch)"
Potom znovu sestavte doplněk s odpovídajícím cílem:
# For x64 Node.js:
dotnet publish ./winMlAddon/winMlAddon.csproj -c Release -r win-x64
# For ARM64 Node.js:
dotnet publish ./winMlAddon/winMlAddon.csproj -c Release -r win-arm64
Pokud jste nedávno změnili instalaci Node.js, přeinstalujte také node_modules, abyste získali odpovídající binární soubor pro Electron.
rm -rf node_modules package-lock.json
npm install
Získání nápovědy
- Našli jste chybu?Zapište problém.
- Dotazy k WinML? Projděte si dokumentaci k WinML.
Šťastné strojové učení! 🤖
Windows developer