このガイドでは、ネイティブ アドオンもnode-gyp/MSBuild ステップも使用せず、electron アプリの JavaScript から Windows API (Windows アプリ SDK と Windows SDK の両方) を直接呼び出す方法について説明します。 ネイティブ ファイル ピッカー (Windows アプリ SDK) を開き、次に winapp.jsBindings を通じて追加された Windows SDK のファイル API とイメージング API を使用して、選択した画像を調査します。
[前提条件]
このガイドを開始する前に、次の作業が完了していることを確認してください。
- 開発環境の セットアップが完了しました。
手順 1: バインディングを確認する
セットアップでは、ソースの横に .winapp/bindings/ ディレクトリが生成されました。出力されたWindows アプリ SDK クラスごとに 1 つの.js + .d.ts ペアに加えて、それらすべてを再エクスポートするindex.jsが生成されました。
.winapp/bindings/
├── index.js # entry — re-exports every emitted class
├── index.d.ts # TS bundle
├── FileOpenPicker.js # one pair of files per emitted class
├── FileOpenPicker.d.ts
├── PickerLocationId.js
├── PickerLocationId.d.ts
└── …
手順 2: Windows SDK API をバインドに追加する
既定のバインドでは、Windows アプリ SDK API のみが対象となります。 選択したイメージを開いてデコードするには、次の 2 つのWindows SDK クラスも必要です。
-
Windows.Storage.StorageFile— ファイル パスをラップします。 -
Windows.Graphics.Imaging.BitmapDecoder— 寸法を読み取ります。
package.jsonを開き、作成したadditionalWinmds ブロック内にwinapp.jsBindings配列winapp init追加します。
// package.json
{
"winapp": {
"jsBindings": {
"additionalWinmds": [
{ "namespace": "Windows.Storage", "classes": ["StorageFile"] },
{ "namespace": "Windows.Graphics.Imaging", "classes": ["BitmapDecoder"] }
]
}
}
}
次に、バインディングを再生成します。
npx winapp node generate-bindings
StorageFile.js、 BitmapDecoder.js、および依存する列挙型ファイル (FileAccessMode.js、 BitmapPixelFormat.js、...) が .winapp/bindings/に表示されるようになりました。
Note
dynwinrt-codegen では、これらのクラスを呼び出すために必要な依存型 (たとえば、IRandomAccessStreamによって返されるStorageFile.openAsync) が自動的にプルされるため、通常はエントリ ポイント クラスだけを選択するだけで十分です。
手順 3: Electron コードから Windows API を呼び出す
生成されたすべてのクラスは、 #winapp/bindingsを介してエクスポートされます。
@microsoft/dynwinrt-codegen≥0.1.0-preview.8が必要です — 古いプロジェクト向けの代替手段については、Electron を使い始めるを参照してください。
// src/index.js (Electron main, CommonJS)
const { app, BrowserWindow, ipcMain } = require('electron');
const {
// Windows App SDK (default bindings)
FileOpenPicker,
PickerLocationId,
PickerViewMode,
// Windows SDK (added via additionalWinmds in Step 2)
StorageFile,
FileAccessMode,
BitmapDecoder,
} = require('#winapp/bindings');
async function pickAndInspectImage(mainWindow) {
// FileOpenPicker needs the parent window's HWND wrapped in a WindowId struct.
// Electron's getNativeWindowHandle() returns an 8-byte buffer on 64-bit Windows.
const hwnd = mainWindow.getNativeWindowHandle().readBigUInt64LE(0);
const picker = FileOpenPicker.createInstance({ value: hwnd });
picker.viewMode = PickerViewMode.Thumbnail;
picker.suggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.fileTypeFilter.replaceAll(['.png', '.jpg', '.jpeg', '.gif']);
const result = await picker.pickSingleFileAsync();
if (!result?.path) return null; // User cancelled.
// Use Windows SDK APIs to inspect the picked image.
const file = await StorageFile.getFileFromPathAsync(result.path);
const stream = await file.openAsync(FileAccessMode.Read);
const decoder = await BitmapDecoder.createAsync(stream);
return {
path: result.path,
width: decoder.pixelWidth,
height: decoder.pixelHeight,
};
}
// Expose it to the renderer via IPC so a button click can trigger the flow.
ipcMain.handle('pick-and-inspect-image', (event) => {
const win = BrowserWindow.fromWebContents(event.sender);
return pickAndInspectImage(win);
});
その後、事前読み込みスクリプトを使用してレンダラーにブリッジします。
// src/preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('winapp', {
pickAndInspectImage: () => ipcRenderer.invoke('pick-and-inspect-image'),
});
最後に、レンダラーにボタンを追加し、クリックされたときに window.winapp.pickAndInspectImage() を呼び出します。
<!-- src/index.html -->
<button id="pick">Pick an image</button>
<p id="result"></p>
<script>
document.getElementById('pick').addEventListener('click', async () => {
const info = await window.winapp.pickAndInspectImage();
document.getElementById('result').textContent = info
? `${info.path} (${info.width}×${info.height})`
: 'Cancelled';
});
</script>
手順 4: 実行する
ファイル ピッカーが機能する前に、アプリが ID で実行されていることを確認する必要があります。 Run:
npx winapp node add-electron-debug-identity
Note
このコマンドは既にセットアップ ガイドで追加した postinstall スクリプトの一部であるため、 npm install後に自動的に実行されます。 ただし、 Package.appxmanifestを変更したり、アプリ資産を更新したり、依存関係を再インストールしたりするたびに、手動で実行する必要があります。
次に、アプリを起動します。
npm start
ボタンをクリックすると、ネイティブ Windows ファイル ピッカーが表示され、イメージを選択すると、そのパスとピクセル サイズがボタンの下に表示されます。 🎉 .winapp/bindings/ からインポートすると @microsoft/dynwinrt が読み込まれ、各呼び出しは基盤となる WinRT API にディスパッチされます。これはコードからは透過的に行われます。
次のステップ
おめでとうございます! JavaScript から、ネイティブ アドオンも node-gyp ビルド ステップも不要で、Windows API(Windows アプリ SDK と Windows SDK)を直接呼び出せるようになりました。 🎉
これで、次の準備ができました。
-
配布用にアプリをパッケージ化 する — 出荷できる MSIX を生成します (
@microsoft/dynwinrtランタイムは既にdependenciesにあります)。
または、他のガイドを調べる:
- JavaScript からの通知を表示する — JS バインディングを使用してWindows アプリ SDK通知を表示します。
- JavaScript から Phi Silica を呼び出します。JS バインドを使用して、Windows アプリ SDK AI でテキストを要約します。
-
JavaScript から WinML を実行 —
onnxruntime-nodeで Windows アプリ SDK の ML プロバイダー検出を使用する。 - C++ ネイティブ アドオンの作成 — WinRT プロジェクションがない Win32/pure-COM API 用。
- Phi Silica アドオンの作成 — C# アドオンから Windows AI API を利用する。
- 概要 - メイン ガイドに戻ります。
その他のリソース
-
winapp CLI ドキュメント — 完全な CLI リファレンス (
init、restore、node generate-bindings)。 - サンプル Electron App — JS バインドを含む完全な作業例。
- @microsoft/dynwinrt — 生成されたバインディングを実行するランタイム。
- @microsoft/dynwinrt-codegen — コード ジェネレーター。
Windows developer