Wywoływanie interfejsów API Windows z poziomu języka JavaScript (powiązań JS)

Ten przewodnik pokazuje, jak wywoływać interfejsy API systemu Windows — zarówno Zestaw SDK do aplikacji systemu Windows, jak i Windows SDK — bezpośrednio z poziomu języka JavaScript w aplikacji Electron, bez natywnego dodatku i bez kroku node-gyp / MSBuild. Otworzysz natywne okno wyboru plików (Zestaw SDK do aplikacji systemu Windows), a następnie przeanalizujesz wybrany obraz przy użyciu interfejsów API plików i obrazowania z zestawu Windows SDK dodanych za pomocą winapp.jsBindings.

Wymagania wstępne

Przed rozpoczęciem tego przewodnika upewnij się, że:

Krok 1. Potwierdzenie powiązań

Podczas konfiguracji wygenerowano katalog .winapp/bindings/ obok źródeł — po jednej parze .js + .d.ts dla każdej wygenerowanej klasy Zestaw SDK do aplikacji systemu Windows oraz plik index.js, który ponownie eksportuje je wszystkie:

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

Krok 2: Dodaj interfejsy API zestawu SDK systemu Windows do swoich wiązań

Domyślne powiązania obejmują tylko interfejsy API zestawu Zestaw SDK do aplikacji systemu Windows. Aby otworzyć i zdekodować wybrany obraz, potrzebujemy również dwóch klas zestawu SDK Windows:

  • Windows.Storage.StorageFile — aby opakowować ścieżkę pliku.
  • Windows.Graphics.Imaging.BitmapDecoder — aby odczytać jego wymiary.

Otwórz package.json i dodaj tablicę additionalWinmds wewnątrz utworzonego winapp.jsBindings bloku winapp init :

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

Następnie ponownie wygeneruj powiązania:

npx winapp node generate-bindings

StorageFile.js, BitmapDecoder.js oraz pliki enumów, od których są zależne (FileAccessMode.js, BitmapPixelFormat.js, …), są teraz wyświetlane w .winapp/bindings/.

Note

dynwinrt-codegen automatycznie dołącza typy zależne potrzebne do wywoływania tych klas (na przykład IRandomAccessStream, zwracany przez StorageFile.openAsync), więc wybranie tylko klas wejściowych jest zwykle wystarczające.

Krok 3. Wywoływanie interfejsów API Windows z kodu Electron

Wszystkie wygenerowane klasy są eksportowane za pomocą metody #winapp/bindings:

Wymaga @microsoft/dynwinrt-codegen0.1.0-preview.8 — zobacz Wprowadzenie do Electrona, aby poznać alternatywne rozwiązania dla starszych projektów.

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

Następnie przeforsuj go do modułu renderowania za pomocą skryptu wstępnego ładowania:

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

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

Na koniec dodaj przycisk do renderera i wywołaj window.winapp.pickAndInspectImage(), gdy zostanie kliknięty:

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

Krok 4. Uruchamianie

Zanim funkcja wybierania plików zacznie działać, musisz upewnić się, że aplikacja działa z przypisaną tożsamością. Run:

npx winapp node add-electron-debug-identity

Note

To polecenie jest już częścią skryptu dodanego postinstall w przewodniku konfiguracji, więc jest uruchamiane automatycznie po npm install. Należy jednak uruchomić go ręcznie za każdym razem, gdy zmodyfikujesz Package.appxmanifest, zaktualizuj zasoby aplikacji lub ponownie zainstaluj zależności.

Teraz uruchom aplikację:

npm start

Kliknij przycisk: zostanie wyświetlony natywny selektor plików Windows, a po wybraniu obrazu jego ścieżka i wymiary pikseli są wyświetlane poniżej przycisku. 🎉 Importowanie z .winapp/bindings/ powoduje załadowanie @microsoft/dynwinrt, które przekazuje każde wywołanie do bazowego interfejsu API WinRT — w sposób przezroczysty dla Twojego kodu.

Dalsze kroki

Gratulacje! Teraz wywołujesz interfejsy API Windows — Zestaw SDK do aplikacji systemu Windows i Windows SDK — bezpośrednio z języka JavaScript bez natywnego dodatku i bez node-gyp kroku kompilacji. 🎉

Teraz możesz przystąpić do:

  • Spakuj aplikację do dystrybucji — tworzy plik MSIX, który można wysłać ( @microsoft/dynwinrt środowisko uruchomieniowe znajduje się już w twoim pliku dependencies).

Możesz też zapoznać się z innymi przewodnikami:

Dodatkowe zasoby