Arbeiten mit lokal erstellten Webseiten in CefSharp

8

Ich habe einen CefSharp-Browser in meinem WinForm erstellt und ich muss dynamisch eine HTML-Seite im Speicher erstellen und dann CefSharp es rendern lassen.

Idealerweise möchte ich dem Konstruktor eine Zeichenfolge mit dem darin enthaltenen HTML übergeben, aber es erwartet eine URL. Die Antwort ist wahrscheinlich nein, aber gibt es eine Direktive, der Sie die Zeichenfolge voranstellen können, damit CefSharp weiß, dass es sich um eine Zeichenfolge handelt, die eine Webseite enthält? Dann wird CefSharp eine temporäre Datei erstellen?

Wenn nicht, wo ist der Chromium-Temp-Ordner auf? Funktioniert es, wenn ich eine Datei dorthin schreibe und diese dann als vollqualifizierten Pfad übergebe? Ich weiß, dass Chrome etwas wie file: ///Users/dmacdonald/Documents/myFile.htm als URL unterstützt, aber nicht sicher ist, wie man eine URL formt, wenn man die temporäre Struktur verwendet.

Hier ist mein neuer Code, aber mein Browser-Objekt hat keine ResourceHandler-Eigenschaft. Ich sehe es hat eine ResourceHandlerFactory

%Vor%     
user461051 24.02.2015, 13:53
quelle

3 Antworten

7

Der einfache Ansatz (eine "Datei", eine Seite)

LoadString () kann verwendet werden, um direkt aus einer Zeichenfolge zu laden:

%Vor%

Alternativ kann LoadHtml () aus einer Zeichenfolge in einer bestimmten Codierung geladen werden:

%Vor%

Ich habe beides versucht, und beide scheinen zu funktionieren, zumindest mit CefSharp.Wpf v51.0.0 . Laut WebBrowserExtensions.cs verwendet LoadHtml() RegisterHandler() , um eine% co_de zu registrieren %. Es ist mir nicht klar, wie ResourceHandler funktioniert, aber beide Funktionen scheinen die gleiche Wirkung zu haben.

Achten Sie darauf, ein gültiges URL-Format für die gefälschte URL zu verwenden, beispielsweise:

%Vor%

Der komplexe Ansatz (mehrere "Dateien", zB doc + images)

  1. Erstellen Sie eine Klasse, die von LoadString() stammt. Wenn VS2015 verwendet wird, sollte die Maus über den rot unterstrichenen Namen die Option Schnittstelle implementieren enthalten. Diese Option zur automatischen Vervollständigung vereinfacht die Erstellung der Klasse erheblich, also verwenden Sie sie unbedingt.

  2. Erstellen Sie ähnlich wie in Schritt 1 eine Klasse, die von IResourceHandlerFactory abgeleitet ist. Stellen Sie sicher, dass Sie die Option Implementieren der Schnittstelle für die automatische Vervollständigung verwenden, falls möglich.

  3. In der in Schritt 1 erstellten Klasse (abgeleitet von IResourceHandler ) gibt es eine Funktion namens IResourceHandlerFactory . Übergeben Sie innerhalb dieser Funktion eine neue Instanz Ihrer abgeleiteten Klasse von Schritt 2 (basierend auf GetResourceHandler() ). Die Verwendung von IResourceHandler ist wichtig, da der Webbrowser mehrere Dateien gleichzeitig anfordern kann. Jede new -Instanz sollte eine Anfrage aus dem Browser bearbeiten (keine Sorge, das ist für Sie erledigt).

  4. Wie von OP erwähnt, hat das Browser-Steuerelement ein Mitglied namens IResourceHandler . Setzen Sie dieses Mitglied auf eine neue Instanz Ihrer Klasse, die Sie in Schritt 1 erstellt haben (abgeleitet von ResourceHandlerFactory ). Dadurch wird das Chromium Web Browser-Steuerelement mit Ihren Schnittstellenklassen verknüpft. In Schritt 3 haben Sie beide Klassen verknüpft, sodass wir eine vollständige Kette haben.

  5. Innerhalb der Klasse von Schritt 2 gibt es eine Funktion namens IResourceHandlerFactory . Dies ist die erste Funktion, die aufgerufen wird, wenn eine Anfrage von einer Webseite gestellt wird. Ihr Ziel besteht darin, die angeforderte URL und alle POST-Daten aufzuzeichnen und anschließend zu entscheiden, ob die Anfrage zulässig ist, indem Sie entweder ProcessRequest() oder callback.Continue() aufrufen. Geben Sie true zurück, um fortzufahren.

  6. Auch in der Klasse von Schritt 2 gibt es eine Funktion namens callback.Cancel() . Dies ist die zweite aufgerufene Funktion. Ihr Ziel ist es, die URL zu überprüfen, möglicherweise Dateidaten von wo auch immer Sie es abholen (aber noch nicht senden), bestimmen Sie die Antwortlänge (Datei oder Zeichenfolge Größe), und setzen Sie eine entsprechende Statuscode innerhalb der Antwortobjekt. Stellen Sie sicher, dass alle diese Variablen gesetzt sind, damit die Anfrage korrekt ausgeführt werden kann.

  7. Ihr letzter Schritt, wieder in der Klasse von Schritt 2, besteht darin, die Anfrage innerhalb der dritten aufgerufenen Funktion zu vervollständigen: GetResponseHeaders() . Schreiben Sie in dieser Funktion Ihre in Schritt 6 abgerufenen Daten in den Stream ReadResponse() . Wenn Ihre Daten ungefähr 32 KB überschreiten, müssen Sie sie möglicherweise in mehreren Blöcken senden. Beschränken Sie unbedingt die Menge, die Sie in einem bestimmten Aufruf auf die Länge des dataOut -Streams schreiben. Setzen Sie dataOut auf das, was Sie in diesem bestimmten Aufruf geschrieben haben. Wenn beim letzten Aufruf keine Daten mehr vorhanden sind, setzen Sie einfach bytesRead auf Null und geben Sie bytesRead zurück. Da Sie möglicherweise mehrmals für eine bestimmte Datei aufgerufen werden, müssen Sie Ihren aktuellen Leseort verfolgen, damit Sie wissen, wo Sie sich befinden und wie viele Daten gesendet wurden.

Für diejenigen, die nicht damit vertraut sind, können Sie direkt in Ihre EXE kompilierte Datendateien speichern, indem Sie sie zu Ihrem Projekt hinzufügen und ihre "Build Action" auf "Embedded Resource" setzen. Anschließend laden Sie ihre Daten programmgesteuert mit false . Mit den oben genannten Methoden müssen keine Dateien von der Festplatte erstellt oder gelesen werden .

    
Michael 18.09.2016, 17:22
quelle
1

Siehe Ссылка für ein Beispiel der Registrierung a ResourceHandler für eine In-Memory-Zeichenfolge.

Wie Sie sehen können, hat es immer noch eine URL (Web-Ressourcen neigen dazu, dies zu haben), aber es kann ein Dummy Ihrer Wahl sein.

Hier ist die GitHub-Suche nach dem Namen in den WinForms- (und WPF-) Beispiel-Apps: Ссылка

Eine andere, wahrscheinlich weniger günstige Option mit einer temporären Datei (irgendwo?) im lokalen Dateisystem ist die Verwendung von FileAccessFromFileUrlsAllowed

Aktualisieren aus den folgenden Kommentaren:

In welcher CefSharp Version bist du jetzt? Hinweis: Wenn Sie sich github.com/cefsharp/CefSharp/releases ansehen und nach resource suchen, sehen Sie, dass sich die API in Version 49 geändert hat (sehen Sie unter brechende Änderungen für diese Version) - siehe unten stehende Kommentare für weitere gotchas

    
jornh 24.02.2015 16:06
quelle
0

Hier ist ein Beispiel für eine benutzerdefinierte Factory, die Ressourcen aus dem Dateisystem lädt:

%Vor%

Und so würden Sie es anwenden:

%Vor%     
Luis Perez 14.12.2017 03:19
quelle

Tags und Links