Memanggil API Windows dari JavaScript (pengikatan JS)

Panduan ini menunjukkan kepada Anda cara memanggil API Windows — baik SDK Aplikasi Windows maupun Windows SDK — langsung dari JavaScript aplikasi Electron Anda, tanpa addon asli dan tanpa node-gyp langkah /MSBuild. Anda akan membuka pemilih file asli (SDK Aplikasi Windows), lalu memeriksa gambar yang dipilih dengan file SDK Windows dan API pencitraan yang ditambahkan melalui winapp.jsBindings.

Prerequisites

Sebelum memulai panduan ini, pastikan Anda telah:

Langkah 1: Konfirmasikan pengikatan Anda

Penyiapan membuat direktori .winapp/bindings/ di samping file sumber Anda — satu pasangan .js + .d.ts untuk setiap kelas SDK Aplikasi Windows yang dihasilkan, serta index.js yang mengekspor ulang semuanya:

.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
└── …

Langkah 2: Tambahkan API SDK Windows ke pengikatan Anda

Pengikatan default hanya mencakup API SDK Aplikasi Windows. Untuk membuka dan mendekode gambar yang dipilih, kita juga memerlukan dua kelas SDK Windows:

  • Windows.Storage.StorageFile — untuk membungkus jalur file.
  • Windows.Graphics.Imaging.BitmapDecoder — untuk membaca dimensinya.

Buka package.json dan tambahkan array additionalWinmds di dalam blok winapp.jsBindings yang dibuat oleh winapp init:

// package.json
{
  "winapp": {
    "jsBindings": {
      "additionalWinmds": [
        { "namespace": "Windows.Storage", "classes": ["StorageFile"] },
        { "namespace": "Windows.Graphics.Imaging", "classes": ["BitmapDecoder"] }
      ]
    }
  }
}

Kemudian regenerasi pengikatan:

npx winapp node generate-bindings

StorageFile.js, BitmapDecoder.js, dan file enum yang bergantung pada (FileAccessMode.js, , BitmapPixelFormat.js...) sekarang muncul di .winapp/bindings/.

Note

dynwinrt-codegen secara otomatis menyertakan tipe dependensi yang Anda perlukan untuk memanggil kelas-kelas ini (misalnya IRandomAccessStream, yang dikembalikan oleh StorageFile.openAsync), jadi biasanya cukup dengan hanya memilih kelas-kelas titik masuk.

Langkah 3: Panggil API Windows dari kode Electron Anda

Semua kelas yang dihasilkan diekspor melalui #winapp/bindings:

Memerlukan @microsoft/dynwinrt-codegen0.1.0-preview.8 — lihat Memulai dengan Electron untuk alternatif bagi proyek lama.

// 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);
});

Kemudian hubungkan ke renderer melalui skrip preload Anda:

// src/preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('winapp', {
  pickAndInspectImage: () => ipcRenderer.invoke('pick-and-inspect-image'),
});

Terakhir, tambahkan tombol ke perender Anda dan panggil window.winapp.pickAndInspectImage() saat diklik:

<!-- 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>

Langkah 4: Jalankan

Sebelum pemilih file berfungsi, Anda perlu memastikan aplikasi Anda berjalan dengan identitas. Run:

npx winapp node add-electron-debug-identity

Note

Perintah ini sudah menjadi bagian dari skrip yang postinstall kami tambahkan dalam panduan penyiapan, sehingga berjalan secara otomatis setelah npm install. Namun, Anda perlu menjalankannya secara manual setiap kali Anda memodifikasi Package.appxmanifest, memperbarui aset aplikasi, atau menginstal ulang dependensi.

Sekarang mulai aplikasi:

npm start

Klik tombol: pemilih file Windows asli muncul, dan setelah Anda memilih gambar jalur dan dimensi pikselnya muncul di bawah tombol. 🎉 Mengimpor dari .winapp/bindings/ akan memuat @microsoft/dynwinrt, yang meneruskan setiap pemanggilan ke API WinRT yang mendasarinya — transparan bagi kode Anda.

Langkah Selanjutnya

Selamat! Anda kini dapat memanggil API Windows — SDK Aplikasi Windows dan Windows SDK — langsung dari JavaScript, tanpa add-on native dan tanpa langkah build node-gyp. 🎉

Sekarang Anda siap untuk:

Atau jelajahi panduan lain:

Sumber Daya Tambahan