Windows API's aanroepen vanuit JavaScript (JS-bindingen)

In deze handleiding ziet u hoe u Windows API's aanroept ( zowel Windows App SDK als Windows SDK), rechtstreeks vanuit javaScript van uw Electron-app, zonder systeemeigen addon en geen MSBuild-stap node-gyp . U opent een systeemeigen bestandskiezer (Windows App SDK) en inspecteert vervolgens de gekozen afbeelding met Windows SDK-bestand en imaging-API's die zijn toegevoegd via winapp.jsBindings.

Prerequisites

Voordat u aan deze handleiding begint, moet u het volgende doen:

Stap 1: Bevestig uw bindingen

Setup heeft een .winapp/bindings/ map naast uw bronnen gegenereerd: één .js + .d.ts paar per verzonden Windows App SDK klasse, plus een index.js map die ze allemaal opnieuw exporteert:

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

Stap 2: WINDOWS SDK-API's toevoegen aan uw bindingen

De standaardbindingen hebben alleen betrekking op Windows App SDK API's. Om de geselecteerde afbeelding te openen en te decoderen, hebben we ook twee Windows SDK-klassen nodig:

  • Windows.Storage.StorageFile — om een bestandspad te verpakken.
  • Windows.Graphics.Imaging.BitmapDecoder — om de afmetingen ervan te bekijken.

Open package.json en voeg een additionalWinmds array toe in het winapp.jsBindings-blok dat door winapp init is aangemaakt:

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

Genereer vervolgens de bindingen opnieuw:

npx winapp node generate-bindings

StorageFile.js, BitmapDecoder.jsen de opsommingsbestanden die ze afhankelijk zijn van (FileAccessMode.js, BitmapPixelFormat.js, , ...) worden nu weergegeven in .winapp/bindings/.

Note

dynwinrt-codegen haalt automatisch afhankelijke typen op die u nodig hebt om deze klassen aan te roepen (bijvoorbeeld IRandomAccessStreamgeretourneerd door StorageFile.openAsync), zodat het kiezen van alleen de invoerpuntklassen meestal voldoende is.

Stap 3: Windows API's aanroepen vanuit uw Electron-code

Alle gegenereerde klassen worden geëxporteerd via #winapp/bindings:

Vereist @microsoft/dynwinrt-codegen0.1.0-preview.8 — zie Aan de slag met Electron voor alternatieven voor oudere projecten.

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

Sluit deze vervolgens over naar de renderer via uw preloadscript:

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

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

Voeg ten slotte een knop toe aan uw renderer en roep window.winapp.pickAndInspectImage() deze aan wanneer erop wordt geklikt:

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

Stap 4: Voer deze uit

Voordat de bestandskiezer werkt, moet u ervoor zorgen dat uw app wordt uitgevoerd met identiteit. Uitvoeren:

npx winapp node add-electron-debug-identity

Note

Deze opdracht maakt al deel uit van het postinstall script dat we in de installatiehandleiding hebben toegevoegd, dus deze wordt automatisch uitgevoerd na npm install. U moet deze echter handmatig uitvoeren wanneer u app-assets wijzigt, bijwerkt Package.appxmanifestof afhankelijkheden opnieuw installeert.

Start nu de app:

npm start

Klik op de knop: de systeemeigen Windows bestandskiezer wordt weergegeven en zodra u een afbeelding kiest, worden het pad en de pixeldimensies weergegeven onder de knop. 🎉 Importeren vanuit .winapp/bindings/ laadt @microsoft/dynwinrt, dat elke aanroep doorstuurt naar de onderliggende WinRT-API — transparant voor je code.

Volgende stappen

Gefeliciteerd! U roept nu Windows API's aan ( Windows App SDK en Windows SDK) rechtstreeks vanuit JavaScript, zonder systeemeigen invoegtoepassing en geen node-gyp buildstap. 🎉

U kunt nu het volgende doen:

Of bekijk andere handleidingen:

Aanvullende bronnen