In einem früheren Artikel, „Leitfaden zum Ausstieg aus der Abhängigkeit vom IE-Modus“, habe ich geschrieben, dass der IE-Modus nur eine zeitlich befristete Übergangsmaßnahme ist und man den Ausstieg parallel dazu planen sollte. Wenn wir zu diesem „Ausstieg“ beraten, taucht WebView2 mit hoher Häufigkeit auf. „Wir möchten das interne Web-System in einer eigenen Anwendung anzeigen“, „Nur ein Bildschirmbild der Desktop-Anwendung soll mit Webtechnik gebaut werden“, „Wir haben gehört, Electron sei schwergewichtig — gibt es eine Alternative?“ — in all diesen Fällen kommt WebView2 als Option ins Spiel.
Gleichzeitig hat WebView2 einige Eigenheiten, die man vor der Einführung kennen sollte: wie man die Laufzeit verteilt, wo man den Benutzerdatenordner ablegt, wie man native Seite und Web-Seite miteinander sprechen lässt. Und vor allem gibt es eine Einschränkung, die den Kern jedes Migrationsplans betrifft: ActiveX, das unter dem IE-Modus lief, funktioniert in WebView2 nicht. Dieser Artikel ordnet die Grundstruktur von WebView2 bis hin zu Verteilung, Design und Sicherheit sowie die realistische Kombination mit dem Ausstieg aus dem IE-Modus.
1. Zuerst das Ergebnis
- WebView2 ist ein Steuerelement, das das Chromium-basierte Microsoft Edge in eine Windows-Anwendung einbettet. Es lässt sich aus WinForms, WPF, WinUI und Win32 C++ verwenden und eignet sich dafür, einer bestehenden Desktop-Anwendung „nur ein bisschen Web-UI“ hinzuzufügen.1
- Als Laufzeit wird im Regelfall Evergreen (die automatisch aktualisierte, gemeinsam genutzte Laufzeit) verwendet. Windows 11 bringt sie standardmäßig mit, doch statt „sie ist sicher schon vorhanden“ vorauszusetzen, empfiehlt Microsoft offiziell, eine Existenzprüfung und einen Bootstrap-Schritt in den Installer einzubauen.2
- Für Offline-Umgebungen oder Fabriken/Fertigungslinien, die eine geprüfte Konfiguration einfrieren möchten, gibt es Fixed Version (der Anwendung beigelegt), doch das mitgelieferte Paket überschreitet 250 MB, und man übernimmt die Verantwortung, Sicherheitsupdates selbst auszuliefern. Wählen Sie diese Option nicht leichtfertig.3
- Der erste Stolperstein ist der Benutzerdatenordner (UDF). Da er standardmäßig direkt neben der exe angelegt wird, scheitert der Start bei einer unter Program Files installierten Anwendung. Machen Sie es sich zur festen Regel, ausdrücklich einen Ort unter
%LOCALAPPDATA%anzugeben.4 - Für die Verbindung zwischen nativ und Web gilt: Standardmäßig über
PostWebMessageAsJson/WebMessageReceivedNachrichten austauschen, undAddHostObjectToScript(die Freigabe eines COM-Objekts) auf vertrauenswürdige Inhalte beschränken.1 - Innerhalb von WebView2 funktioniert ActiveX nicht. Eine IE-Modus-abhängige Seite mit ActiveX lässt sich nicht einfach durch „Umstieg auf WebView2“ ablösen — es braucht ein Design, das die von ActiveX übernommenen Verarbeitungen auf die native Seite verlagert. Genau das ist der Kern jedes Ausstiegsplans aus dem IE-Modus.5
2. Die Grundstruktur von WebView2
WebView2 besteht aus zwei Teilen: dem „SDK“ (der API, die in die Anwendung eingebettet wird) und der „Laufzeit“ (der Edge-basierten Ausführungsumgebung, die auf dem Client installiert wird). Das entspricht demselben Aufbau wie bei der Visual-C++-Laufzeit oder der .NET-Laufzeit: Die Anwendung wird gegen das NuGet-Paket Microsoft.Web.WebView2 gebaut und nutzt zur Laufzeit die auf dem Client vorhandene Laufzeit.3
Die unterstützten Plattformen sind breit gefächert: Nutzbar ist es aus WinForms und WPF ab .NET Framework 4.6.2 bzw. .NET Core 3.1, aus WinUI und aus Win32 C++. Dass sich beispielsweise nur ein Bildschirmbild einer bestehenden WinForms-Fachanwendung schrittweise auf WebView2 umstellen lässt, ist ein großer Vorteil gegenüber einem vollständigen Frameworkwechsel (wie etwa zu Electron). Zur Auswahl des UI-Frameworks selbst siehe auch die „Entscheidungstabelle für WinForms / WPF / WinUI“.
Die Voraussetzungen, die bei jeder Prüfung erneut gefragt werden, fassen wir hier an einer Stelle zusammen, so wie sie in der offiziellen Dokumentation stehen.
| Punkt | Inhalt |
|---|---|
| Unterstütztes Client-OS | Windows 10 (SAC 1709 oder neuer), die verschiedenen Windows-10-LTSC-/IoT-Enterprise-Varianten, Windows 116 |
| Unterstütztes Server-OS | Windows Server 2016 / 2019 / 2022 (LTSC), Windows Server (SAC)6 |
| Unterstützte Entwicklungsumgebung | Win32 C/C++, .NET Framework 4.6.2 oder neuer, .NET Core 3.1 oder neuer, .NET 5 oder neuer, WinUI 2.0 / 3.06 |
| IDE | Visual Studio 2017 oder neuer. Das offizielle Tutorial hält ausdrücklich fest, dass Visual Studio Code nicht unterstützt wird7 |
| SDK | NuGet-Paket Microsoft.Web.WebView2 (pro Projekt hinzuzufügen)7 |
| Zur Laufzeit benötigt | WebView2-Laufzeit. Im Regelfall Evergreen, bei Windows 11 standardmäßig vorhanden (Kapitel 3)3 |
| Geräte außerhalb von Windows | Auch auf Xbox und HoloLens 2 nutzbar6 |
Eine minimale Einbettung sieht wie folgender Code aus (dieselbe Idee gilt gleichermaßen für WPF und WinForms).
var env = await CoreWebView2Environment.CreateAsync(
browserExecutableFolder: null, // Evergreen-Laufzeit verwenden
userDataFolder: Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"KomuraSoft", "MyApp", "WebView2"));
await webView.EnsureCoreWebView2Async(env);
webView.CoreWebView2.Navigate("https://internal.example.co.jp/app/");
Der entscheidende Punkt ist, dass wir CoreWebView2Environment selbst erstellen, statt es den Standardwerten zu überlassen. Die Gründe dafür erklären die nächsten zwei Abschnitte.
Das Einrichtungsverfahren selbst ist unkompliziert; bei WinForms/WPF sieht der Ablauf so aus:
Microsoft.Web.WebView2per NuGet zum Projekt hinzufügen (das WebView2-Steuerelement erscheint dann auch in der Toolbox des Designers)- Das Steuerelement auf dem Formular/Fenster platzieren
- Wie im obigen Code mit
EnsureCoreWebView2Asyncinitialisieren und anschließendNavigateaufrufen
Hier gibt es einen API-seitigen Hinweis, den man von Anfang an unbedingt kennen sollte: webView.CoreWebView2 ist so lange null, bis die Initialisierung abgeschlossen ist. Ein klassischer Stolperstein ist der Versuch, im Konstruktor des Formulars ein Ereignis wie CoreWebView2.WebMessageReceived += ... zu abonnieren, was zu einer NullReferenceException führt. Die Grundregel ist, alle Verarbeitungen rund um die Initialisierung „nach dem Await von EnsureCoreWebView2Async“ zu bündeln. Die Zuweisung an die Source-Eigenschaft startet die Initialisierung zwar implizit mit, doch bei Anwendungen, die Umgebungseinstellungen (etwa den UDF-Ort) angeben möchten, ist es sicherer, sich einheitlich darauf festzulegen, zuerst ausdrücklich EnsureCoreWebView2Async(env) aufzurufen.
Außerdem lösen alle WebView2-Ereignisse auf dem UI-Thread aus. Schreibt man aufwendige Verarbeitung (Gerätezugriff, Datei-I/O) direkt in WebMessageReceived, friert dabei auch die Bedienbarkeit der Web-Seite mit ein — die native Verarbeitung sollte deshalb über async/await ausgelagert werden. Die Grundsätze dazu lassen sich unverändert aus „Der UI-Thread und async/await in WPF/WinForms“ übernehmen.
3. Verteilung der Laufzeit ── Evergreen und Fixed Version
3.1 Evergreen (empfohlen)
Bei Evergreen nutzen alle WebView2-Anwendungen eine gemeinsame, auf dem Client installierte Laufzeit, die sich automatisch aktualisiert. Weil Sicherheitspatches automatisch eingespielt werden und der Plattenplatzbedarf gering bleibt, wird dieses Modell offiziell klar empfohlen.8
In der Praxis sind drei Punkte zu beachten.
- Eine Existenzprüfung implementieren. Windows 11 bringt sie standardmäßig mit, und auch auf Windows 10 ist sie weit verbreitet, doch es gibt weiterhin „Geräte ohne sie“. In .NET lässt sich das mit
CoreWebView2Environment.GetAvailableBrowserVersionString()prüfen, doch in einer Umgebung ohne installierte Laufzeit schlägt dieser Aufruf selbst mit einer Ausnahme fehl (WebView2RuntimeNotFoundException) — fangen Sie das in einem try/catch ab, werten Sie „Ausnahme = nicht installiert“, und binden Sie das in das Setup ein, sodass anschließend der Bootstrapper (ein kleiner Online-Installer) oder der eigenständige Installer ausgeführt wird.2 - Das Nachziehen von Laufzeit-Updates einplanen. Auch wenn die Laufzeit aktualisiert wird, verwendet eine bereits laufende Anwendung weiterhin die alte Version. Das empfohlene Muster besteht darin, das Ereignis
NewBrowserVersionAvailableabzufangen und einen Hinweis wie „nach einem Neustart wird das Update wirksam“ einzubauen.2 - Mit der internen Update-Governance abstimmen. Die Update-Richtlinie des Edge-Browsers und die der WebView2-Laufzeit sind getrennte Dinge. In Umgebungen, in denen eine Gruppenrichtlinie die Laufzeit-Updates eingefroren hat, bricht die Grundannahme von Evergreen — dass die neueste Version vorhanden ist — zusammen; verwenden Sie in diesem Fall bei neueren APIs eine Feature-Erkennung.8
3.2 Fixed Version (eingeschränkter Einsatz)
Bei Fixed Version wird eine bestimmte Version der Laufzeit der Anwendung beigelegt. Da sich damit eine geprüfte, funktionierende Konfiguration einfrieren lässt, ist das für Offline-Fertigungsanlagen oder Umgebungen mit strengem Änderungsmanagement eine sinnvolle Wahl. Allerdings gilt:
- Die mitgelieferten Binärdateien überschreiten 250 MB, wodurch das Verteilungspaket entsprechend größer wird2
- Da sich die Laufzeit nicht automatisch aktualisiert, übernimmt man die Verantwortung, Sicherheitskorrekturen der Browser-Engine über die eigenen Releases auszuliefern
- Vernachlässigt man die Updates, bleibt im Unternehmen dauerhaft eine „Fachanwendung mit veraltetem Chromium“ zurück
— das sind erhebliche Kosten. Wählen Sie diese Option nur, wenn die angezeigten Inhalte vollständig geschlossen und in eigener Verwaltung liegen und Sie über eine Struktur verfügen, die Laufzeit-Updates in den Release-Zyklus einbinden kann.
4. Der erste Stolperstein ── der Benutzerdatenordner
WebView2 speichert Cookies, Cache, Berechtigungen und Ähnliches im Benutzerdatenordner (UDF). Wird der UDF-Ort nicht angegeben, versucht die Anwendung, ihn an einem Standardort anzulegen (bei den meisten Konfigurationen direkt neben der exe) — bei einer unter Program Files installierten Anwendung schlägt das Schreiben deshalb fehl, und es kommt zu einem Initialisierungsfehler. Auf dem Entwicklungsrechner (Debug-Ausführung, beschreibbarer Ordner) funktioniert es, doch sobald die Anwendung installiert ist, funktioniert sie nicht mehr — ein typischer Fehler, der „erst nach der Auslieferung ans Licht kommt“.4
Die Abhilfe ist einfach: wie im vorherigen Codebeispiel immer ausdrücklich einen anwendungseigenen Ordner unter %LOCALAPPDATA% angeben. Berücksichtigen Sie im Design außerdem Folgendes:
- Den UDF pro Benutzer und pro Anwendung trennen (nicht von mehreren Anwendungen gemeinsam nutzen)
- Nicht auf einem Netzlaufwerk ablegen (das verursacht Geschwindigkeitseinbußen, Beschädigungen und Datenverlust)4
- Ein Verfahren zum Löschen des UDF bei der Deinstallation oder über eine Funktion „Anmeldedaten löschen“ festlegen (wissen die Betreibenden nicht, dass dort Cookies und Website-Daten liegen, wird das etwa beim Aufräumen der Geräte ausgeschiedener Mitarbeitender übersehen)
Betrachten Sie das als die WebView2-Version des Grundsatzes „nicht neben der exe schreiben“ aus dem vorangegangenen Artikel „Speicherung lokaler Daten in einer Business-Windows-Anwendung“.
5. Design der Verbindung zwischen nativ und Web
Was WebView2 zu mehr macht als nur einem „Browserrahmen“, ist das wechselseitige Zusammenspiel von nativem Code und Web-Inhalten. Dafür gibt es im Wesentlichen zwei Mittel.1
Wer mit welcher API sendet und wer mit welchem Ereignis empfängt, lässt sich in Worten leicht verwirrend erklären, deshalb zunächst das Gesamtbild des Hin und Her. Die native Seite sendet mit PostWebMessageAsJson und empfängt mit WebMessageReceived. Die Web-Seite sendet mit window.chrome.webview.postMessage und empfängt mit dem message-Ereignis — eine symmetrische Form.
sequenceDiagram
participant N as Native Seite Hostanwendung
participant W as WebView2-Steuerelement
participant P as Web-Seite JavaScript
Note over N,P: Initialisierung: Abonnieren erst nach Abschluss von EnsureCoreWebView2Async
N->>W: Abonniert WebMessageReceived
P->>W: Abonniert message über window.chrome.webview.addEventListener
Note over P: Nutzer klickt auf „Etikett drucken“
P->>W: Sendet die Anfrage über window.chrome.webview.postMessage
W->>N: WebMessageReceived löst aus
N->>N: Prüft mit e.Source die Herkunft und gleicht type gegen die Whitelist ab
N->>N: Führt native Verarbeitung wie Gerätesteuerung asynchron aus
N->>W: Sendet das Ergebnis über PostWebMessageAsJson
W->>P: message-Ereignis löst aus
P->>P: Aktualisiert die Statusanzeige des Bildschirms
Die linke Hälfte des Diagramms ist nativ, die rechte Hälfte ist Web. Entscheidend ist, die Prüfung an genau einer Stelle direkt nach dem Empfang auf der nativen Seite zu platzieren — die Verarbeitung nach dieser Stelle kann dann unter der Annahme geschrieben werden, dass „nur Anfragen mit erlaubtem type ankommen“.
5.1 Webnachrichten (Standardform)
Die native Seite sendet mit PostWebMessageAsJson JSON, die Web-Seite empfängt es mit window.chrome.webview.addEventListener("message", ...). In der Gegenrichtung sind es window.chrome.webview.postMessage(...) und das WebMessageReceived-Ereignis. Das ist lose gekoppelt, und die freigegebenen Operationen lassen sich an einer einzigen Stelle prüfen — machen Sie das zunächst zum Standardmittel der Verbindung.
// Nativ → Web
webView.CoreWebView2.PostWebMessageAsJson(
JsonSerializer.Serialize(new { type = "deviceStatus", connected = true }));
// Web → Nativ
webView.CoreWebView2.WebMessageReceived += (s, e) =>
{
// Nachrichten von einem anderen als dem erwarteten Ursprung (z. B. nach einer Navigation zu einer externen Website) nicht verarbeiten
if (!e.Source.StartsWith("https://internal.example.co.jp/", StringComparison.Ordinal))
return;
AppMessage? msg;
try { msg = JsonSerializer.Deserialize<AppMessage>(e.WebMessageAsJson); }
catch (JsonException) { msg = null; }
if (msg?.Type is null)
return; // Fehlerhaftes Format hier verwerfen (bei Bedarf loggen)
// Nur die für den jeweiligen type erlaubten Operationen ausführen
};
Die Web-Seite (JavaScript) empfängt das so. Es ist keine besondere Bibliothek nötig, es wird lediglich das von WebView2 injizierte Objekt window.chrome.webview verwendet.
// Nachricht von der nativen Seite empfangen
window.chrome.webview.addEventListener("message", (e) => {
if (e.data.type === "deviceStatus") {
updateStatusBadge(e.data.connected);
}
});
// Anfrage an die native Seite senden
document.getElementById("print-label").addEventListener("click", () => {
window.chrome.webview.postMessage({ type: "printLabel", copies: 2 });
});
Prüfen Sie auf der Empfängerseite, wie im obigen Code, zuerst e.Source (die URI der Seite, die die Nachricht gesendet hat), und setzen Sie darauf konsequent durch: „Den type der Nachricht gegen eine Whitelist prüfen, alles Unerwartete ignorieren und protokollieren.“ Die Web-Seite kann durch einen einzigen Link oder eine einzige Weiterleitung zu einer externen Website navigieren, lassen Sie deshalb die Herkunftsprüfung nicht aufgrund der Annahme „was gerade angezeigt wird, ist sicher die eigene Seite“ weg. Umgekehrt erhöht ein Fallback auf der Web-Seite für den Fall, dass window.chrome.webview nicht existiert (also beim Öffnen in einem gewöhnlichen Browser), die Entwicklungseffizienz, da sich der Web-UI-Teil eigenständig im Browser debuggen lässt.
5.2 Freigabe von Hostobjekten (mächtig, aber nur eingeschränkt einsetzen)
Mit AddHostObjectToScript lässt sich ein .NET-/COM-Objekt direkt aus JavaScript aufrufen. Intern läuft das über den COM-Mechanismus, und es ist ein interessanter Anblick, dass COM-Technik, mit der wir uns seit langem beschäftigen, auch an dieser Stelle noch im Einsatz ist — doch einem Web-Inhalt direkt ein natives Objekt in die Hand zu geben bedeutet auch, dass die Auswirkungen entsprechend groß sind, falls diese Seite jemals kompromittiert wird. Beschränken Sie die Freigabe auf selbst verwaltete Inhalte, und halten Sie die freigegebenen Methoden auf das notwendige Minimum. Der Grundsatz lautet: nicht bei einem WebView registrieren, das möglicherweise eine nicht vertrauenswürdige Seite anzeigt.
5.3 Laden lokaler Inhalte
Wenn HTML/JS der Anwendung beigelegt und angezeigt werden, ist es die Standardmethode, statt eines direkten Lesens über file:// mit SetVirtualHostNameToFolderMapping einen Ordner auf einen virtuellen Hostnamen abzubilden. Da der Inhalt dadurch einen Ursprung wie https://appassets.example/ erhält, funktionieren ursprungsabhängige Web-APIs wie localStorage ganz normal, und auch die Freigabestufe für Cross-Origin-Zugriffe lässt sich festlegen. Verwenden Sie für den Hostnamen eine real nicht existierende, reservierte Domäne (etwa .example), und beginnen Sie bei der Zugriffsart mit dem notwendigen Minimum (zuerst DenyCors).9
6. Ausstieg aus dem IE-Modus mit WebView2 ── ActiveX funktioniert nicht
Das ist der wichtigste Abschnitt in diesem Artikel. Dass sich der IE-Modus am Leben erhalten lässt, liegt daran, dass in Edge ein echtes IE11 (die Trident-Engine) läuft und ActiveX-Steuerelemente sowie Browser Helper Objects unverändert funktionieren.5 WebView2 dagegen ist Chromium und verfügt über keinen Mechanismus, um ActiveX zu hosten. Mit anderen Worten:
„Ein im IE-Modus laufendes internes System auf eine mit WebView2 gebaute Shell umzustellen“ funktioniert nur für Bildschirme, die nicht von ActiveX abhängen.
Der Migrationsplan muss um diese Einschränkung herum aufgebaut werden. Eine realistische Migrationsreihenfolge sieht so aus:
- Bestandsaufnahme: IE-Modus-abhängige Seiten in „Bildschirme, die IE-spezifische Technik wie ActiveX nutzen“ und „Bildschirme, die einfach nur veraltet gebaut sind“ einteilen (das Vorgehen zur Bestandsaufnahme aus dem Artikel zum IE-Modus lässt sich unverändert übernehmen. Kurz zusammengefasst: Mit Enterprise Site Discovery die für den IE-Modus vorgesehenen URLs maschinell auflisten und die Abhängigkeit jeder URL in „Dokumentmodus“, „ActiveX / BHO“, „Authentifizierung“, „Clientzertifikat“, „Datei/Druck“ und „Gerät/COM“ einordnen.)
- Bildschirme ohne IE-Spezifik: Für moderne Browser umbauen und entweder direkt in Edge anzeigen oder, wenn eine Integration in eine Fachanwendung auf dem Arbeitsplatzgerät gewünscht ist, in eine WebView2-Shell einbetten.
- ActiveX-abhängige Bildschirme: Die von ActiveX übernommenen Funktionen (serielle Kommunikation, Dateizugriff, Steuerung von Spezialgeräten und Ähnliches) so umgestalten, dass sie auf die native Seite (die Hostanwendung von WebView2) verlagert und über Webnachrichten aufgerufen werden. Man kann sich das so vorstellen, dass „ActiveX im Browser“ zu „Web-UI in der Anwendung plus native Verarbeitung“ umgedreht wird.
- Die Entscheidung, ob ActiveX selbst erhalten, gekapselt oder ersetzt wird, lässt sich unverändert anhand der Kriterien aus „ActiveX / OCX heute behandeln - Entscheidungstabelle: Behalten, Kapseln, Ersetzen“ treffen.
Genau dieses Redesign in Schritt 3 ist der eigentliche Aufwand bei der Einführung von WebView2, und in der Planungsphase muss man die Erwartungen entsprechend justieren: Es ist nicht so einfach wie „WebView2 einführen und schon ist man aus dem IE-Modus heraus“. Umgekehrt gesagt: Ist das Design, das die ActiveX-Funktionen in die Hostanwendung verlagert, erst einmal abgeschlossen, lässt sich die UI leichter im eigenen Haus mit Webtechnik bauen und pflegen, während sich die Verteilung weiterhin als Desktop-Anwendung steuern lässt — man bekommt beides.
7. Implementierungsfragen, die bei internen Systemen immer aufkommen
Erwägt man die Einführung von WebView2, tauchen von der Fachseite stets bestimmte Fragen auf. Wir ordnen sie hier vorausschauend.
7.1 Druck und Formulare
Die Anforderung „unter IE kam beim Klick auf den Druckknopf das Formular heraus“ lässt sich in WebView2 auf zwei Wegen erfüllen.
- Den Bildschirm direkt drucken: Mit
CoreWebView2.ShowPrintUI()den Druckdialog öffnen, oder mitPrintAsyncunbeaufsichtigt drucken. Das entspricht dem Browserdruck, sodass CSS-Druckvorgaben (@media print) unverändert greifen. - Als PDF ausgeben: Mit
PrintToPdfAsynclässt sich die aktuell angezeigte Seite als PDF-Datei speichern. Für einen Geschäftsablauf wie „Formular als PDF speichern und in den freigegebenen Ordner legen“ eignet sich diese Variante, da sich Dateiname und Speicherort auf der nativen Seite steuern lassen.1
Bei Formularen, die eine pixelgenaue Spaltenausrichtung verlangen — etwa Durchschreibebelege —, erwägen Sie auch die Entscheidung, statt es mit Web-Druck zu erzwingen, eher auf die native Formularausgabe (das im Artikel „Erstellung von Excel-Berichten“ beschriebene Verfahren) zu setzen.
7.2 Datei-Download und -Upload
Downloads funktionieren standardmäßig wie im Browser, doch bei einer Fachanwendung ist es üblich, über das DownloadStarting-Ereignis einzugreifen. Damit lässt sich der Speicherort festlegen, anhand der Dateierweiterung erlauben oder ablehnen, und die Standard-Download-UI durch eine eigene Benachrichtigung der Anwendung ersetzen.1 Beim Upload (<input type="file">) öffnet sich ohne besondere Implementierung der Dateiauswahldialog des Betriebssystems.
7.3 Authentifizierung und SSO
Verwendet das interne Web-System die integrierte Windows-Authentifizierung (NTLM/Kerberos), funktioniert das in WebView2 weitgehend genauso wie im Browser. Für ältere Systeme mit Basic-Authentifizierung lassen sich über das Ereignis BasicAuthenticationRequested Anmeldeinformationen bereitstellen, sodass sich ein Login-Bildschirm ganz vermeiden lässt — wo diese Anmeldeinformationen jedoch gespeichert werden, ist genau das Thema des DPAPI-Artikels. Möchte man SSO für Microsoft Entra ID (früher Azure AD) über die Anmeldeinformationen des Betriebssystems durchreichen, ist die Aktivierung der Umgebungsoption AllowSingleSignOnUsingOSPrimaryAccount zu erwägen.
Da Cookies im UDF gespeichert werden, bleibt der Anmeldezustand auch nach einem Neustart der Anwendung erhalten. Soll eine Abmeldefunktion die Sitzung zuverlässig löschen, bauen Sie eine explizite Löschung über CookieManager ein.
7.4 Debugging während der Entwicklung
Da das Innere von WebView2 Chromium ist, lassen sich während der Entwicklung die F12-DevTools unverändert nutzen (CoreWebView2Settings.AreDevToolsEnabled ist standardmäßig aktiviert). Es gibt drei Wege, sie zu öffnen: F12, Strg+Umschalt+I und Rechtsklick auf die Seite und „Untersuchen“. Auch wenn, wie in Kapitel 8 beschrieben, Tastenkürzel und das Rechtsklickmenü im Produktions-Build blockiert werden, lässt sich das Fenster über einen Aufruf von OpenDevToolsWindow von der Anwendung aus programmatisch öffnen (richtet man intern ein „Entwicklertools über ein verstecktes Menü“ ein, wird die Untersuchung von Geräten vor Ort erheblich einfacher).10
Bevor Sie mit der Implementierung der Verbindung beginnen, verringert es Nacharbeit, wenn Sie in 3 Minuten allein prüfen, ob Nachrichten hin und her gehen. Probieren Sie mit dem Code aus 5.1 in folgender Reihenfolge:
- Die Anwendung starten, im WebView2-Bildschirm die DevTools öffnen und zum Reiter „Konsole“ wechseln.
window.chrome.webvieweingeben und auswerten. Wird ein Objekt angezeigt, läuft es innerhalb von WebView2. Beiundefinedliegt vermutlich eine falsche Annahme vor, etwa dass es in einem gewöhnlichen Browser geöffnet ist oder die Initialisierung noch nicht abgeschlossen wurde.- Web → Nativ prüfen. In der Konsole
window.chrome.webview.postMessage({ type: "printLabel", copies: 1 })ausführen; setzt man einen Haltepunkt im nativseitigenWebMessageReceived-Handler, hält die Ausführung dort an. Prüfen Sie, dass ine.WebMessageAsJsondasselbe JSON steht und ine.Sourcedie URI der aktuellen Seite. - Nativ → Web prüfen. Registrieren Sie in der Konsole
window.chrome.webview.addEventListener("message", e => console.log(e.data)), und führen Sie dann auf der nativen Seite eine Aktion aus, diePostWebMessageAsJsonaufruft (etwa ein Menü oder eine Zustandsänderung eines Geräts) — in der Konsole erscheint dann das JSON.
Sind mit diesen vier Schritten „Senden funktioniert, Empfangen funktioniert, die Herkunft ist wie erwartet“ bestätigt, bleibt nur noch übrig, für jeden type die entsprechende Verarbeitung zu ergänzen. Baut man die Web-UI-Seite zudem, wie zuvor erwähnt, so, dass sie „auch eigenständig im Browser läuft“, lässt sich die Arbeit aufteilen: UI-Entwicklung und -Debugging laufen als gewöhnliche Webentwicklung, und nur die native Verbindung wird auf WebView2 überprüft. Selbst wenn die Web-Assets in der Anwendung eingeschlossen sind, bleibt die Entwicklungserfahrung also die des Webs.
8. Wesentliche Punkte des Sicherheitsdesigns
Eine WebView2-Anwendung ist „eine Anwendung mit eingebautem Browser“, denken Sie deshalb in einem browserähnlichen Bedrohungsmodell.
- Die angezeigten Inhalte begrenzen: In
NavigationStartingdas Navigationsziel gegen eine Whitelist interner Domänen prüfen und unerwartete URLs an den Standardbrowser abgeben (NewWindowRequestedebenso behandeln). - Funktionen, die eine Vertrauensgrenze überschreiten, einschränken: Den Umfang freigegebener Hostobjekte und die über Webnachrichten erlaubten Operationen minimal halten. Es ist auch sinnvoll, ein WebView, das externe Websites anzeigen kann, von einem WebView mit nativer Anbindung zu trennen.
- Nutzerorientierte Funktionen an die Umgebung anpassen: Mit
CoreWebView2Settingslässt sich genau so viel „Browser-Charakter“ belassen wie nötig. Auf Kiosk- oder Arbeitsplatzgeräten verringert eine Einschränkung Zwischenfälle. - Bei Fixed Version die Verantwortung für den Update-Plan übernehmen: Wie bereits erwähnt, wird die Verteilung von Sicherheitskorrekturen dann zur eigenen Aufgabe der Anwendung.8
Hier sind die Einstellungen aufgeführt, die bei CoreWebView2Settings häufig angepasst werden. Es empfiehlt sich, festzuhalten, wie im Produktions-Build damit verfahren wird, und das in die Checkliste vor der Veröffentlichung aufzunehmen.
| Einstellung | Standard | Typisch für Arbeitsplatzgeräte / Produktion |
|---|---|---|
AreDevToolsEnabled (F12-Entwicklertools) |
Aktiviert | In der Produktion deaktivieren |
AreDefaultContextMenusEnabled (Rechtsklickmenü) |
Aktiviert | Deaktivieren bei Bildschirmen, auf denen „Zurück“/„Neu laden“ nicht genutzt werden sollen |
AreBrowserAcceleratorKeysEnabled (Tastenkürzel wie Strg+F5) |
Aktiviert | Für Kiosk-Einsatz deaktivieren |
IsStatusBarEnabled (Anzeige des Linkziels) |
Aktiviert | Nach Bedarf |
IsZoomControlEnabled (Strg+Mausrad-Zoom) |
Aktiviert | Deaktivieren bei Fachbildschirmen, deren Layout beim Zoomen bricht |
AreHostObjectsAllowed (Hostobjekte) |
Aktiviert | Deaktivieren, wenn nicht verwendet |
Bei all dem geht es weniger darum, dass „Deaktivieren gleich sicher“ ist, sondern darum, „jeden Zugang außer den von der Anwendung beabsichtigten Bedienungen zu schließen“. Zur allgemeinen Anhebung der Sicherheit von Windows-Anwendungen siehe auch die „Minimale Sicherheitscheckliste für Windows-Anwendungen“.
9. Zusammenfassung der Einführungsentscheidung
| Konfiguration | Geeignet für | Zu beachten |
|---|---|---|
| Anzeige in Edge (Browser) | Gewöhnliches internes Web-System | Keine App-Integration, keine native Anbindung möglich |
| Bestehende Anwendung + WebView2 für einen Teil der Web-UI | Bildschirmweise Modernisierung, Wiederverwendung von Web-Assets | UDF, Laufzeitverteilung, Verbindungsdesign (dieser Artikel) |
| WebView2-Shell + verlagerte native Funktionen | Ausstieg für ActiveX-abhängige IE-Modus-Assets | Die Neuimplementierung der ActiveX-Funktionen ist der eigentliche Aufwand |
| Electron und Ähnliches | Wenn Plattformunabhängigkeit zwingend erforderlich ist | Schwergewichtig bei reinem Windows-Einsatz. Größeres Verteilungspaket, höherer Speicherbedarf |
| Vollständige native Neuentwicklung (z. B. WPF) | Keine vorhandenen Web-Assets / Offline-first | Gegen die Entwicklungskosten abwägen |
Wer „für eine reine Windows-Inhouse-Anwendung eine mit Webtechnik gebaute UI“ möchte, sollte standardmäßig eher zu WebView2 als zu Electron greifen. Da sich die Laufzeit mit dem Betriebssystem teilen lässt, bleibt die Verteilung leichtgewichtig, und auch die Integration mit vorhandenen .NET-Assets ist unkompliziert.
10. Zusammenfassung
WebView2 ist eine Technik, mit der sich eine Chromium-basierte Web-UI als Baustein in eine Windows-Anwendung einbetten lässt, und passt gut zur Modernisierung interner Systeme. Die praktischen Punkte bei der Einführung sind drei: die Existenzprüfung der Evergreen-Laufzeit und das Nachziehen ihrer Updates, die ausdrückliche Angabe des Benutzerdatenordners und ein Verbindungsdesign, das standardmäßig auf Webnachrichten setzt. Und auf der Planungsseite gilt: Der Einschränkung, dass ActiveX nicht funktioniert, ins Auge sehen und das Redesign, das die ActiveX-Funktionen auf die native Seite verlagert, in den Mittelpunkt der Aufwandsschätzung stellen.
Wer mit Blick auf die Frist des IE-Modus denkt „es wird Zeit für einen Ausstieg“, fährt am solidesten damit, zunächst mit einer Bestandsaufnahme des betroffenen Systems und der funktionalen Zerlegung der ActiveX-abhängigen Teile zu beginnen. Bei diesem Vorgehen lässt sich vieles nur beurteilen, wenn man die tatsächliche Systemkonfiguration vor Augen hat — wenden Sie sich im Zweifel gerne an uns.
Verwandte Artikel
- Leitfaden zum Ausstieg aus der Abhängigkeit vom IE-Modus
- ActiveX / OCX heute behandeln - Entscheidungstabelle: Behalten, Kapseln, Ersetzen
- Was sind COM, ActiveX und OCX?
- Entscheidungstabelle für WinForms / WPF / WinUI
Verwandte Beratungsbereiche
Die KomuraSoft LLC übernimmt Beratung zum Ausstiegsdesign für IE-Modus-/ActiveX-abhängige interne Systeme, zur schrittweisen Modernisierung mit WebView2 und zur Integration von Web-UI in bestehende Windows-Anwendungen.
- Nutzung von Altbeständen & Migrationsunterstützung
- Ablösung von Windows-Anwendungen
- Technische Beratung & Design-Review
- Kontakt
Referenzlinks
-
Microsoft Learn, Overview of WebView2 APIs. Zum Gesamtbild der WebView2-Funktionen: Navigationsverwaltung, Laden lokaler Inhalte und Host-zu-Web-Kommunikation (Webnachrichten, Hostobjekte). ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Distribute your app and the WebView2 Runtime. Zur Verteilung per Bootstrapper/eigenständigem Installer, zur Erkennung einer vorhandenen Installation, zum Nachziehen von Updates über NewBrowserVersionAvailable sowie zum Vorgehen beim Beilegen von Fixed Version (über 250 MB). ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Evergreen vs. fixed version of the WebView2 Runtime. Zum Unterschied zwischen den beiden Verteilungsmodi der Laufzeit, zur Standardausstattung von Windows 11 sowie zu Vor- und Nachteilen von Fixed Version. ↩ ↩2 ↩3
-
Microsoft Learn, Manage user data folders. Zur Rolle des Benutzerdatenordners, zu den für einen benutzerdefinierten UDF nötigen Lese-/Schreibrechten sowie dazu, dass die Ablage auf einem Netzlaufwerk Geschwindigkeitseinbußen, Abstürze und Datenverlust verursacht. ↩ ↩2 ↩3
-
Microsoft Learn, What is Internet Explorer (IE) mode?. Dazu, dass der IE-Modus auf der Trident-Engine (MSHTML) läuft und ActiveX-Steuerelemente sowie Browser Helper Objects unterstützt (das heißt, das Chromium-basierte WebView2 verfügt über diese Unterstützung nicht). ↩ ↩2
-
Microsoft Learn, Introduction to Microsoft Edge WebView2. Zu den Windows-Client-Systemen, auf denen WebView2-Anwendungen laufen (Windows 10 ab SAC 1709, die verschiedenen LTSC-/IoT-Enterprise-Varianten, Windows 11), zu Windows Server (LTSC 2016 / 2019 / 2022, SAC), zu den unterstützten Entwicklungsumgebungen (Win32 C/C++, .NET Framework 4.6.2 oder neuer, .NET Core 3.1 oder neuer, .NET 5 oder neuer, WinUI 2.0 / 3.0) sowie dazu, dass es auch auf Xbox und HoloLens 2 nutzbar ist. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Get started with WebView2 in WinForms apps. Dazu, dass Visual Studio 2017 oder neuer benötigt wird und Visual Studio Code nicht Gegenstand des Tutorials ist, dass das SDK
Microsoft.Web.WebView2per NuGet pro Projekt hinzugefügt wird, zur Initialisierungsreihenfolge, bei derWebMessageReceivederst nach Abschluss vonEnsureCoreWebView2Asyncabonniert wird, sowie zur wechselseitigen Kommunikation überwindow.chrome.webview.postMessageundPostWebMessageAsString/PostWebMessageAsJson. ↩ ↩2 -
Microsoft Learn, Development best practices for WebView2 apps. Zur Empfehlung von Evergreen, zum Umgang mit Laufzeit-Updates, zur Feature-Erkennung sowie zur Notwendigkeit regelmäßiger Updates bei Nutzung von Fixed Version. ↩ ↩2 ↩3
-
Microsoft Learn, Using local content in WebView2 apps. Zum Laden lokaler Inhalte per virtueller Hostnamen-Zuordnung, zu den Vorteilen eines zugewiesenen Ursprungs sowie zur Angabe der Zugriffsart (etwa DenyCors). ↩
-
Microsoft Learn, Debug WebView2 apps with Microsoft Edge DevTools. Dazu, dass es drei Wege gibt, die DevTools zu öffnen — F12, Strg+Umschalt+I und Rechtsklick auf die Seite mit „Untersuchen“ —, und dass sich das Fenster bei entfernten Tastenkürzeln oder entferntem Rechtsklickmenü über die API
OpenDevToolsWindowprogrammatisch öffnen lässt. ↩
Verwandte Artikel
Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.
Entra-ID-Authentifizierung in WinForms/WPF-Apps integrieren — Eine praxistaugliche Architektur mit MSAL.NET und dem WAM-Broker
Ein praxisnaher Blick auf die Integration der Entra-ID-Authentifizierung (früher Azure AD) in WinForms/WPF-Desktop-Apps: das Public-Clien...
High-DPI-Unterstützung in WPF — Warum es trotz „eigentlich DPI-bewusst“ immer noch verschwimmt und durchblutet, und wie Sie es beheben
WPF layoutet die UI in DIPs (1/96 Zoll) und ist von Anfang an System DPI Aware, doch das Verschieben eines Fensters auf einen Monitor mit...
Windows-App-Outsourcing und Auftragsentwicklung: Was Sie vor der Beauftragung klären sollten
Bevor Sie die Entwicklung einer Windows-App outsourcen oder in Auftrag geben, sollten Sie folgende Punkte klären: Überarbeitung bestehend...
Infobereich-Symbole und Toast-Benachrichtigungen in Windows-Apps — Fallstricke von NotifyIcon und die richtige AppNotification-Wahl
Ein praktischer Leitfaden dafür, eine geschäftliche Windows-Anwendung im Infobereich (System Tray) resident zu halten und den Benutzer üb...
Mehrsprachigkeit für WinForms/WPF-Anwendungen ── resx, Satelliten-Assemblies und Kulturumschaltung in der Praxis
Dieser Artikel behandelt die Mehrsprachigkeit von Windows-Desktopanwendungen aus Praxissicht: den Unterschied zwischen CurrentCulture und...
Verwandte Themen
Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.
Technische Windows-Themen
Portal zu Windows-Entwicklung, Fehleranalyse und der Nutzung bestehender Assets.
ActiveX-Migration
Entscheidungen zum Beibehalten, Kapseln oder Ersetzen von COM / ActiveX / OCX.
UI-Threading und Timer
WPF-/WinForms-UI-Thread, asynchrone Abläufe, Dispatcher und Timer-Entscheidungen.
Leistungen zu diesem Thema
Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.
Windows-App-Entwicklung
Geschäftsanwendungen, Geräteintegration und Kommunikationstools von den Anforderungen bis zur Umsetzung.
Nutzung und Migration bestehender Assets
Wiederverwendung und Migration von COM / ActiveX / OCX sowie 32-/64-Bit-Abhängigkeiten.
Häufige Fragen
Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.
- Funktionieren ActiveX-Steuerelemente in WebView2?
- Nein. Der IE-Modus überlebt genau deshalb, weil in Edge ein echtes IE11 (die Trident-Engine) läuft und ActiveX-Steuerelemente unverändert funktionieren, während WebView2 auf Chromium basiert und über keinen Mechanismus verfügt, um ActiveX zu hosten. Ein ActiveX-abhängiges Bildschirmbild lässt sich deshalb nicht einfach durch „Umstieg auf WebView2“ ablösen — die Funktionen, die ActiveX übernommen hat, etwa serielle Kommunikation, Dateizugriff oder die Steuerung von Spezialgeräten, müssen auf die native Seite (die Hostanwendung) verlagert und über Webnachrichten aufgerufen werden. Genau dieses Redesign ist der eigentliche Aufwand bei der Einführung von WebView2.
- Sollte man für die WebView2-Laufzeit Evergreen oder Fixed Version wählen?
- Im Regelfall Evergreen (die gemeinsam genutzte, sich automatisch aktualisierende Laufzeit), da Sicherheitspatches automatisch eingespielt werden und der Plattenplatzbedarf gering bleibt — das wird offiziell klar empfohlen. Windows 11 bringt sie standardmäßig mit, doch da es auch Geräte ohne sie gibt, sollte der Installer eine Existenzprüfung und einen Bootstrap-Schritt enthalten. Fixed Version (der Anwendung beigelegt) überschreitet mit dem mitgelieferten Paket 250 MB und verpflichtet dazu, Sicherheitskorrekturen der Browser-Engine über die eigenen Releases auszuliefern — deshalb sollte diese Variante nur in begrenzten Fällen gewählt werden, etwa bei Offline-Fertigungsanlagen oder Umgebungen mit strengem Änderungsmanagement.
- Warum startet eine WebView2-Anwendung nach der Installation nicht?
- Der klassische erste Stolperstein ist das Problem des Benutzerdatenordners (UDF). WebView2 speichert Cookies, Cache und Berechtigungen im UDF, doch ohne Angabe eines Speicherorts versucht es standardmäßig, ihn direkt neben der exe anzulegen — bei einer unter Program Files installierten Anwendung schlägt das Schreiben dann fehl und es kommt zu einem Initialisierungsfehler. Auf dem Entwicklungsrechner funktioniert es, aber sobald die Anwendung installiert ist, funktioniert sie nicht mehr — ein typischer Fehler, der erst nach der Auslieferung auffällt. Die Abhilfe besteht darin, bei der Erstellung von CoreWebView2Environment immer ausdrücklich einen anwendungseigenen Ordner unter %LOCALAPPDATA% anzugeben. Auch die Ablage auf einem Netzlaufwerk sollte vermieden werden, da sie zu Geschwindigkeitseinbußen und Beschädigungen führt.
- Wie kommunizieren nativer Code und Webseite in WebView2 miteinander?
- Grundsätzlich über eine lose gekoppelte Kommunikation mittels Webnachrichten. Die native Seite sendet mit PostWebMessageAsJson JSON, und die Webseite empfängt es über das message-Ereignis von window.chrome.webview. In der Gegenrichtung sind es postMessage und das WebMessageReceived-Ereignis. Auf der Empfängerseite ist es wichtig, mit e.Source die Herkunfts-URI zu prüfen und den type der Nachricht gegen eine Whitelist zu validieren. Mit AddHostObjectToScript lässt sich auch ein .NET-/COM-Objekt direkt freigeben, doch da die Auswirkungen bei einer kompromittierten Seite groß sind, sollte das auf selbst verwaltete Inhalte beschränkt und die Zahl der freigegebenen Methoden minimal gehalten werden.
Autorenprofil
Profilseite des Artikelautors.
Go Komura
Geschäftsführer von KomuraSoft LLC
Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.