Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coming from Webbrowser , Winforms DOM Document Access in Webview2 Clearing of Cookies Inprivate #176

Open
igotbass opened this issue May 15, 2020 · 30 comments
Labels
feature request feature request tracked We are tracking this work internally.

Comments

@igotbass
Copy link

igotbass commented May 15, 2020

Sorry if this has been discussed before, i cannot find the subject anywhere.

webbrowser.document object what is the equivalent in Webview2 ?
Can we access the DOM like we did with webbrowser control ?

How can all of the cookies and user data be cleared when the winform program is run ?
All of the cookies and data are still in the browser from prior sessions ?
with Webbrowser control we used wininet method

public static bool SupressCookiePersist()
{
// 3 = INTERNET_SUPPRESS_COOKIE_PERSIST
// 81 = INTERNET_OPTION_SUPPRESS_BEHAVIOR
return SetOption(81, 3);
}

    public static bool EndBrowserSession()
    {
        // 42 = INTERNET_OPTION_END_BROWSER_SESSION 
        return SetOption(42, null);
    }

    static bool SetOption(int settingCode, int? option)
    {
        IntPtr optionPtr = IntPtr.Zero;
        int size = 0;
        if (option.HasValue)
        {
            size = sizeof(int);
            optionPtr = Marshal.AllocCoTaskMem(size);
            Marshal.WriteInt32(optionPtr, option.Value);
        }

        bool success = InternetSetOption(0, settingCode, optionPtr, size);

        if (optionPtr != IntPtr.Zero) Marshal.Release(optionPtr);
        return success;
    }

This does not work with Webview2, is there any way to get a fresh browser session when the program is executed ????

Any help would be appreciated.

AB#28556146

@igotbass igotbass changed the title Coming from Webbrowser , Winforms DOM Document Access in Webview2 Coming from Webbrowser , Winforms DOM Document Access in Webview2 Clearing of Cookies Inprivate May 15, 2020
@ukandrewc
Copy link

There isn't a DOM (Document) implementation for WebView2, but I am working on one here.

@igotbass
Copy link
Author

There isn't a DOM (Document) implementation for WebView2, but I am working on one here.

There is no native way to access DOM objects from Winforms app ?
How is that even possible ?

@ukandrewc
Copy link

Create a .Net DOM framework and update it from JS.

@igotbass
Copy link
Author

Create a .Net DOM framework and update it from JS.

The documentation does not explain how to get values out of the control into .net. I mean this is the most basic functionality of a webbrowser control ? How is this not explained in depth in the documentation?

@ukandrewc
Copy link

It is far more flexible and cross browser/platform and more secure to do it in JS.
It is explained how to communicate between .Net and JS, it's up to us what we do with it.

@david-risney
Copy link
Contributor

Hi @igotbass, thanks for these great questions! Looks like we need some documentation regarding how to interact with the DOM.

@igotbass, Regarding interacting with the DOM, yes what @ukandrewc is true. You can use ExecuteScript to execute script and you'll get back the result of that script as JSON. Or you can use PostWebMessageAsJson/chrome.webview.addEventListener('message',...) to send messages into the document and chrome.webview.postMessage/WebMessageReceived to send messages from the document back to the host app.

Regarding clearing cookies or other state, that's a great feature request which we don't support yet.

To get a fresh browser session, when you create the CoreWebView2Environment you specify the user data folder. The user data folder holds all state including cookies, http cache, and so on. If you delete the user data folder or specify a new user data folder you will get a fresh environment.

@igotbass
Copy link
Author

igotbass commented May 15, 2020

Hi @igotbass, thanks for these great questions! Looks like we need some documentation regarding how to interact with the DOM.

@igotbass, Regarding interacting with the DOM, yes what @ukandrewc is true. You can use ExecuteScript to execute script and you'll get back the result of that script as JSON. Or you can use PostWebMessageAsJson/chrome.webview.addEventListener('message',...) to send messages into the document and chrome.webview.postMessage/WebMessageReceived to send messages from the document back to the host app.

Regarding clearing cookies or other state, that's a great feature request which we don't support yet.

To get a fresh browser session, when you create the CoreWebView2Environment you specify the user data folder. The user data folder holds all state including cookies, http cache, and so on. If you delete the user data folder or specify a new user data folder you will get a fresh environment.

So if I want something as simple as the oldschool webbrowser.document.getelementbyid("xxx").value its now a massive process to get a element value ?

@ukandrewc
Copy link

ukandrewc commented May 15, 2020

I suppose that's part of the point, this is newschool ;-) but if you use this version that implements a DOM.

It is still a work in progress, so don't expect too much, but you can access most of Window, Document, Element, Attribute, Style and Node.

@igotbass
Copy link
Author

I suppose that's part of the point, this is newschool ;-) but if you use this version that implements a DOM.

It is still a work in progress, so don't expect too much, but you can access most of Window, Document, Element, Attribute, Style and Node.

Ok thanks I will check it out.

@igotbass
Copy link
Author

I just tried @ukandrewc browser and this is the functionality that MUST be built into webview2 from MS, not exactly sure how a 3rd party has managed to put this together but we should not have to inject javascript to get a simple value of a element. Webbrowser control 1 line of code

string TheValue = webbrowser1.document.getelementbyid("xxx").value

Now its setting up and receiving JSON messages ect, guys this should be basic functionality of the control, hands down.

Thanks

@ukandrewc
Copy link

ukandrewc commented May 15, 2020

not exactly sure how a 3rd party has managed to put this together

Ones and zeros, that's all there is to it. At least until we have quantum processing, then it will be ones and or possibly maybe zeros (ah now you've looked at it, so we'll have to start again ;-)

@mphacker
Copy link

mphacker commented Jun 6, 2020

100% agree that having DOM access without having to do a bunch of Javascript injecting is the right way to do it. I hope they incorporate what @ukandrewc has created.

@Sulquendi
Copy link

I need to have the touch keyboard popping up when a user tap (or mouse click) an input field. This is automatically performed when the computer has no physical keyboard, or when it's a slate configured in tablet mode. But since it's not always the case, i had to do the following with my former WebBrowser control :

 protected override void WndProc(ref Message m)
        {
            const int WM_PARENTNOTIFY = 0x0210,
                      WM_POINTERDOWN = 0x0246;

            if (KioskConfig.TouchEnabledPc && m.Msg == WM_PARENTNOTIFY && Loword(m.WParam) == WM_POINTERDOWN)
            {
                var x = Loword(m.LParam);
                var y = Hiword(m.LParam);
                if (_wb.Document != null)
                {
                    Point coords = new Point(x, y);
                    Point cliCoords = _wb.PointToClient(coords);
                    HtmlElement clickedElement = _wb.Document.GetElementFromPoint(cliCoords);

                    // Only on INPUT tags                      
                    if (clickedElement != null && clickedElement.TagName == "INPUT")
                    { ....

And also hooking mouse clicks :

        private void MouseEventProc(object sender, EventArgs e)
        {
            if (_wb.Document != null)
            {
                HtmlElement clickedElement = _wb.Document.GetElementFromPoint(_wb.PointToClient(Cursor.Position));
                if (clickedElement != null && clickedElement.TagName == "INPUT")
                {

Question is : since no easy DOM with WebView2, is there any way of getting the html tag at click/tab coords without having to exec some JS (could probably be very intensive at each click/tap) ?

@ukandrewc
Copy link

This experimental DOM allows that: https://github.com/ukandrewc/Webview2.Winforms.DOM
There's no need for GetElementFromPoint because in the DOMClickEvent, Document.ActiveElement will give you any editable element.

@Sulquendi
Copy link

@ukandrewc thank you ! I will check this out

@GoncerAl
Copy link

I am in complete agreement with the person who initiated this thread. How can Microsoft release WebView2 without an equivalent function to "WebBrowser.Document"?? This is like GM producing a car without seats and expecting each consumer to implement their own custom seat solution.

Some of us are not expert Java Script developers. We all will waste a lot of time trying to reproduce the basic functionality we enjoyed in WebBrowser. I for one spent the last three days trying to find a solution with no luck. My searches on the internet show me that I am not alone. I would like to request that someone provide a clear and concise example that illustrates how we would duplicate the WebServer.Document functionality. This should include any needed Java Script code, as well as, code for decrypting the data using the new System.Text.JSON libraries.

I included my working source below. This is a wrapper class for interfacing with WebView2. I would appreciate any comments/suggestions you might have.

'Option Explicit On
'Option Strict On

Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms

' This class serves as a wrapper for the Microsoft Edge browser.
Public Class EdgeBrowser
' Constant variable definitions.
Private Const HTTP As String = "http://"
Private Const HTTPS As String = "https://"

' Private member data.
Private m_browser As WebView2 = Nothing
Private m_isDebugModeEnabled As Boolean = False
Private m_isInitialized As Boolean = False
Private m_isNavigating As Boolean = False
Private m_isScriptProcessing As Boolean = False
Private m_message As String = Nothing


' Public class methods.


' These methods provide access to class properties.
Public ReadOnly Property Browser() As WebView2
    Get
        Return m_browser
    End Get
End Property
Public Property IsDebugModeEnabled() As Boolean
    Get
        Return m_isDebugModeEnabled
    End Get
    Set(value As Boolean)
        m_isDebugModeEnabled = value
    End Set
End Property
Public ReadOnly Property IsInitialized() As Boolean
    Get
        Return m_isInitialized
    End Get
End Property
Public ReadOnly Property IsNavigating() As Boolean
    Get
        Return m_isNavigating
    End Get
End Property


' This method navigates to the given URL and returns the results.
Public Function NavigateTo(urlAddress As String) As String
    ' Wait for the browser to finish processing, if needed.
    Dim waitUntil As Date = Date.Now.AddSeconds(30)
    While Date.Now < waitUntil
        If m_isInitialized = True And m_isNavigating = False Then
            Exit While
        Else
            Application.DoEvents()
        End If
    End While

    ' Ensure the browser is ready.
    Dim msg As String = Nothing
    If m_isInitialized = False Then
        msg = "Unable to initialize the Microsoft Edge browser."
        GSL.FileOperations.logWarning(msg)
        Throw New Exception(msg)
    ElseIf m_isNavigating = True Then
        m_isNavigating = False
        msg = "Error while navigating."
        GSL.FileOperations.logWarning(msg)
        Throw New Exception(msg)
    Else
        m_isNavigating = True
    End If

    ' Navigate to the given address.
    urlAddress = FixURLAddress(urlAddress)
    Log("#New Navigation Request To : " & urlAddress)
    m_browser.Source = New System.Uri(
        urlAddress,
                                      UriKind.Absolute
                                      )

    ' Wait for the navigation to complete.
    waitUntil = Date.Now.AddSeconds(30)
    While Date.Now < waitUntil
        If m_isNavigating = False Then
            Exit While
        Else
            Application.DoEvents()
        End If
    End While

    ' See if the navigation timed out.
    If m_isNavigating = True Then
        m_isNavigating = False
        msg = "Timed out while navigating to : " & urlAddress
        GSL.FileOperations.logWarning(msg)
        Throw New Exception(msg)
    End If

    ' Access the web content.
    Log("#Navigation Results..." & vbCrLf &

"Document Title|" & m_browser.CoreWebView2.DocumentTitle & vbCrLf &
""
)

    ' Execute a script to get the webpage contents.
    Me.ExecuteScriptAsync("document.documentElement.outerHTML;")
    waitUntil = Date.Now.AddSeconds(15)
    While m_isScriptProcessing = True And Date.Now < waitUntil
        Application.DoEvents()
    End While

    ' See if the script timed out.
    If m_isScriptProcessing = True Then
        m_isScriptProcessing = False
        msg = "Timed out while executing script to extract webpage contents."
        GSL.FileOperations.logWarning(msg)
        Throw New Exception(msg)
    End If

    ' Return results.
    Return m_message
End Function


' Class constructor.
Public Sub New()
    ' instantiate the browser object.
    m_browser = New WebView2
    With m_browser
        .ZoomFactor = 0.5
    End With

    ' Initialize the browser.
    AddHandler m_browser.CoreWebView2Ready, AddressOf EventCoreWebView2Ready
    InitializeBrowserAsync()
End Sub


' Private class methods.


' This method initializes the object and only needs to be called once per object instantiation.
Private Async Sub InitializeBrowserAsync()
    Await m_browser.EnsureCoreWebView2Async()
End Sub


' This method checks/resolves issues with a URL address, as needed.
Private Function FixURLAddress(urlAddress As String) As String
    ' Ensure input is valid.
    If String.IsNullOrWhiteSpace(urlAddress) = True Then
        Return HTTPS & "www.Google.com/"
    Else
        urlAddress = urlAddress.Trim
    End If

    ' Check for an incomplete URL address.
    Dim checkURLAddress As String = urlAddress.ToLower
    If checkURLAddress.StartsWith(HTTP) = False AndAlso checkURLAddress.StartsWith(HTTPS) = False Then
        urlAddress = HTTPS & urlAddress
    End If

    ' Place a trailing "/", if needed.
    If urlAddress.EndsWith("/") = False Then
        urlAddress &= "/"
    End If

    ' Return results.
    Return urlAddress
End Function


' This method is used to log messages while debug mode is enabled.
Private Sub Log(msg As String)
    ' Ensure input is valid.
    If String.IsNullOrWhiteSpace(msg) = True Or m_isDebugModeEnabled = False Then
        Exit Sub
    End If

    ' Reformat the message, as needed.
    Dim fields() As String = Nothing
    Dim lines() As String = Split(msg, vbCrLf)
    msg = Nothing
    For Each line As String In lines
        ' Get the next line to process.
        If String.IsNullOrWhiteSpace(line) = True Then
            Continue For
        ElseIf msg IsNot Nothing Then
            msg &= vbCrLf
        End If

        ' See if this is a new header.
        If line.StartsWith("#") = True Then
            msg &= "==============================" & vbCrLf & line.Replace("#", Nothing)
            Continue For
        End If

        ' See if this line contains text to be formatted.
        If line.IndexOf("|") > 0 Then
            If line.EndsWith("|") = True Then line &= " "
            fields = Split(line, "|")
            msg &= GSL.FormattingOperations.JustifyText(fields(0), 25, GSL.TextAlignment.Left) & " : " & fields(1)
            Continue For
        End If

        ' When we get to here, this is text that is simply appended as is.
        msg &= line
    Next line

    ' Log the message.
    GSL.FileOperations.logMessage(msg)
End Sub


' This method executes a script and cleans up the results.
Private Async Sub ExecuteScriptAsync(scriptName As String)
    ' Initialize variables.
    m_isScriptProcessing = True
    m_message = Nothing

    ' Execute the script and wait for the results.
    Dim msg As String = Await m_browser.ExecuteScriptAsync(scriptName)
    If String.IsNullOrWhiteSpace(msg) = True Then
        Exit Sub
    End If

    ' Cleanup the results.
    ' Note the line below was causing an exception, so I had to bail on using JSON for now.
    ' Ideally I would like to use JSON and somehow get an HTMLDocument object.
    ' Dim o As Object = System.Text.Json.JsonSerializer.Deserialize(msg, msg.GetType)
    msg = System.Text.RegularExpressions.Regex.Unescape(msg)
    msg = msg.Remove(0, 1)
    msg = msg.Remove(msg.Length - 1, 1)

    ' Make the results available to the object.
    m_isScriptProcessing = False
    m_message = msg
End Sub


' These are event callback functions.
Private Sub EventCoreWebView2Ready(sender As Object, e As EventArgs)
    ' The browser core has been initialized.
    m_isInitialized = True
    Log("#Browser object initialization completed.")

    ' Some of these listeners can't be added until the core browser objects have been instantiated.
    AddHandler m_browser.NavigationStarting, AddressOf EventNavigationStarting
    AddHandler m_browser.NavigationCompleted, AddressOf EventNavigationCompleted
    AddHandler m_browser.ContentLoading, AddressOf EventContentLoading
    AddHandler m_browser.SourceChanged, AddressOf EventSourceChanged
    AddHandler m_browser.WebMessageReceived, AddressOf EventWebMessageReceived
    AddHandler m_browser.CoreWebView2.FrameNavigationStarting, AddressOf EventFrameNavigationStarting
    AddHandler m_browser.CoreWebView2.FrameNavigationCompleted, AddressOf EventFrameNavigationCompleted
    AddHandler m_browser.CoreWebView2.ProcessFailed, AddressOf EventProcessFailed
End Sub
Private Sub EventNavigationStarting(sender As Object, e As CoreWebView2NavigationStartingEventArgs)
    m_isNavigating = True
    Log("#Navigation starting..." & vbCrLf &
        "is Redirected|" & e.IsRedirected & vbCrLf &
        "Is User Initiated|" & e.IsUserInitiated & vbCrLf &
                    "Navigation ID|" & e.NavigationId & vbCrLf &
                    "Cancel Request Flag|" & e.Cancel & vbCrLf &
                    "Request Headers|" & vbCrLf &
                                            "   From|" & e.RequestHeaders.From & vbCrLf &
                    "   Host|" & e.RequestHeaders.Host & vbCrLf &
                    "URL Address|" & e.Uri & vbCrLf &
                    ""
                                    )
End Sub
Private Sub EventNavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
    m_isNavigating = False
    Log("#Navigation Completed..." & vbCrLf &
        "URL Address|" & m_browser.Source.AbsoluteUri & vbCrLf &
        "Is Success|" & e.IsSuccess & vbCrLf &
                                "Navigation ID|" & e.NavigationId & vbCrLf &
                                "Error Status|" & e.WebErrorStatus.ToString & vbCrLf &
                    ""
                                    )
End Sub
Private Sub EventContentLoading(sender As Object, e As CoreWebView2ContentLoadingEventArgs)
    Log("#Content Loading..." & vbCrLf &
        "Is Error Page|" & e.IsErrorPage & vbCrLf &
        "Navigation ID|" & e.NavigationId & vbCrLf &
        ""
        )
End Sub
Private Sub EventSourceChanged(sender As Object, e As CoreWebView2SourceChangedEventArgs)
    Log("#Source Changed" & vbCrLf &
        "Is New Document|" & e.IsNewDocument & vbCrLf &
        ""
        )
End Sub
Private Sub EventWebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
    Log("#Message Recieved" & vbCrLf &
                    "Error Status|" &
                                      "JASON Message|" & e.WebMessageAsJson & vbCrLf &
                    ""
                    )
    Try
        Log("Try Message|" & e.TryGetWebMessageAsString)
    Catch ex As Exception
    End Try
End Sub
Private Sub EventFrameNavigationStarting(sender As Object, e As CoreWebView2NavigationStartingEventArgs)
    Log("#Frame Navigation Starting...")
End Sub
Private Sub EventFrameNavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
    Log("#Frame Navigation Completed")
End Sub
Private Sub EventProcessFailed(sender As Object, e As CoreWebView2ProcessFailedEventArgs)
    Log("#Process Failed" & vbCrLf &
        "Failure Type|" & e.ProcessFailedKind.ToString & vbCrLf &
        ""
        )
End Sub

End Class

@ukandrewc
Copy link

@GoncerAl I do appreciate your pain, but there is no direct way to access the DOM from .Net.
You will have to learn Javascript (not that hard, as all high level languages are convergent).
Exact examples will be hard because results are not objects, only JSON.
For your code, can I suggest not using DoEvents while waiting, check your processor usage during a DoEvents to see why.

Here's a generic example to access Javascript, and wait for the result, that I use in this control.

Dim Text = Execute("document.getElementById('myId').innerText")

Function Execute(Script As String) As String
	Return Wait(WebView2.ExecuteScriptAsync(Script))
End Function

Function Wait(Task As Task(Of String)) As String
	Wait = ""
	Task.ContinueWith(
		Sub()
			If Task.IsFaulted Then
				Wait = Task.Exception.Message
			Else
				Wait = Task.Result
			End If
			Frame.Continue = False
		End Sub)
	'Timeout if takes too long
	Timer.Enabled = True
	Frame.Continue = True
	Dispatcher.PushFrame(Frame)
	Timer.Enabled = False
End Function

@ukandrewc
Copy link

@GoncerAl If you use the control, I have created, it will give you what you need.
It inherits from WebView2 so can be used directly in it's place. email me: ukandrewc@gmail.com if you need help getting started with it.

@ygoe
Copy link

ygoe commented Sep 28, 2020

Oops, no DOM access anymore? (Last time I used this was with the IE-based control. I only come back to this when there's a proper HTML engine behind this, what WebView2 seems to be.) I need to disable JavaScript on the content for security reasons. How can I edit and manipulate the HTML content then? Is this impossible? If I wanted to use JavaScript to manipulate the HTML on the page, I'd be using Electron or another framework that lets me write my application in JavaScript altogether.

@kirsan31
Copy link

No DOM - really??? 😭 😭 😭
The Webbrowser is outdated and I ended up here hoping to replace it with WebView2. But it turns out that the migration process is just a PAIN, especially if you don't know the javascript: ((((

@ukandrewc
Copy link

There is an experimental one for .Net here: https://github.com/ukandrewc/Webview2.Winforms.DOM

@evanhsu179
Copy link

This experimental DOM allows that: https://github.com/ukandrewc/Webview2.Winforms.DOM
There's no need for GetElementFromPoint because in the DOMClickEvent, Document.ActiveElement will give you any editable element.

DOMClickEvent?
How can I not find it?
Thank you

@pbogre
Copy link

pbogre commented Nov 21, 2020

There is an experimental one for .Net here: https://github.com/ukandrewc/Webview2.Winforms.DOM

Might be late but how can I use this?

@blakepell
Copy link

I don't think a ton of JavaScript knowledge is necessary. Break it down to the very simplest things you need JS to do (e.g. get an element, write to an element).

I would probably just write a few small JavaScript wrapper functions that allow for reading and writing from the page and then I would leverage other libraries like HtmlAgilityPack if I wanted to use C# instead of JavaScript inspecting the DOM. As purely thrown together example here I load in a copy of jQuery slim, use it to select an element by ID and then return an HtmlNode (I probably didn't even need jQuery other than you can use it to select in different ways behond getElementById). With a few more lines a call could be made into a snippit of jQuery to update the DOM in the browser.

Again, I understand this is limited in the sense that, it's a snapshot in time but I'm mainly sharing as a way to show different ways you can interact with the page.

/// <summary>
/// Gets an HTML element by ID.
/// </summary>
/// <param name="id"></param>
public async Task<HtmlNode> GetElementById(string id)
{
    // Load in jQuery slim/minified
    string jQuery = await System.IO.File.ReadAllTextAsync(@"T:\JavaScript\jquery-3.5.1.slim.min.js");
    await webView.CoreWebView2.ExecuteScriptAsync(jQuery);

    // Get the element via jQuery.
    string html = await webView.CoreWebView2.ExecuteScriptAsync($"$('#{id}').html()");

    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(html);
    return htmlDoc.DocumentNode;
}

@ukandrewc
Copy link

ukandrewc commented Nov 22, 2020

Using this control, you get direct .Net access to the DOM: https://github.com/ukandrewc/Webview2.Winforms.DOM

If you have any questions about using the control, please post in issues for the control, Rather than here which is for pure WebView2

@TheWerewolf
Copy link

Ugh. Ok... Rant ON

  1. JavaScript is NOT a "modern language". It predates .Net languages (almost predates VB6).
  2. Speaking of... What the hell is with the VB.Net code? People still use VB intentionally?
  3. On a related note: It's 2021 - Who still uses .Net Forms?
  4. JavaScript is a terrible language to try to link to .Net as it's dynamic, not strongly typed which means we're back to "strings for everything" - yay... 1995 all over again like everything web oriented.
  5. It's clear that the intention of WebView2 is an embeddable mini web content renderer, not a programmable web interface, which is short-sighted and redundant.
  6. "It is far more flexible and cross browser/platform and more secure to do it in JS." Excuse me???? How is injecting JavaScript into a live web page to read the DOM more secure? Cross browser is irrelevant - we're using WebView2 and that's Edge/Chrome - there are no other choices AND if it's cross-platform (and I'm sure it's not) then the CONTROL will automatically be cross-platform.
  7. "It is explained how to communicate between .Net and JS, it's up to us what we do with it." Because we all have tons of free time to spend on complicated solutions to problems that were already solved in previous incarnations of this control.

Reading the DOM is no more or less secure than JS injection, but it IS vastly easier to do and for many people the entire goal is just to READ the content, not programmatically change it.

Sorry for sounding pissy, but I've been trying literally for weeks to find a sane solution to what should be a simple problem that WebBrowser actually could do except that Microsoft permanently glued it to IE11 and so can't run a lot of (wait for it) JavaScript routines that aren't properly formed and then they abandoned it. If they just took that control and updated it to use the WebView 2 engine - problem solved (And on that - really - we have to install a freaking second browser engine to make this work? They couldn't have made this use the Edge browser's engine to handle rendering? I mean crappy IE could do it...).

It's cool that someone found a hacky way around this and it kinda works (I mean - come ON - injecting JS and then using Win32's messaging system to get the results back and you seriously brought up cross-platform compatibility?) but this is kinda sad, even by open source standards - and this isn't even open source! (If it were, I'd go fix this.)

There. Rant OFF.

Feel much better.

Now, pardon me while I go bang my head against CEFSharp for a while. It's a cannon to swat a fly but at least it's massively feature complete.

@ukandrewc
Copy link

ukandrewc commented Feb 4, 2021

@TheWerewolf Hope you don't mind, but couldn't resist ;-)

  1. Yes it is, it has radically changed since it's first incarnation, and standardised
  2. Yes we do, it's the fastest way to develop in Windows
  3. Please see item 3 above
  4. Most cross language communication has been standardised to JSON and Base64, the internet runs on those
  5. Nah, it's a fully fledged modern browser
  6. Agreed, not sure what security has to do with JS/.Net accessibility
  7. True, it's been time consuming, but all innovation is.

One day we'll look back and consider pre webView2 as the good old days. While they were actually worse, nostalgia will make them seem better.

It is possible to create a DOM wrapper that gives you good access to the DOM. I'd offer you mine, but it's Winforms and VB.Net, so you'd hate it ;-)

@kirsan31
Copy link

kirsan31 commented Feb 4, 2021

@TheWerewolf
3. Why not? WinForms is actively developing.
It's the only option for .net if your need fast and responsive windows gui.
And I agree with @ukandrewc - it's fastest gui in terms of development.

@darbid
Copy link

darbid commented Feb 17, 2021

Just wanted to give a thumbs up for clearing cookies which is a part of the original question.

@Laicure
Copy link

Laicure commented Oct 18, 2021

So, I came here finding out that I can't fully convert my WebBrowser control codes to WebView2 because of the ExecuteScript JS DOM implementation. Sucks though but I hope they implement the easy-DOM way.

@champnic champnic removed the question label Dec 2, 2021
@champnic champnic added the tracked We are tracking this work internally. label May 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request feature request tracked We are tracking this work internally.
Projects
None yet
Development

No branches or pull requests