I'm testing WebView2 (1.0.774.44) to see if it can replace old IE embedded web browser for my wpf project. What I'm doing is simply navigate to wherever the domain I hardcoded. And it works fine on my Dev environment. But when I test my app (the same .exe) on one of my virtual machines, it does not work.
On the testing environment, the web viewer only displays blank pages. When I run DevTools on the page, it looks like it loads html strings. I can even click links or buttons on the page. I just cannot see them.
There are not much to share either. I just simply made a new window that is declared like below.
//TestWebViewWindow.xaml
<window
...some declarations
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
...more declarations
>
<Border>
<wv2:WebView2 Name="xWebView" Source="https://microsoft.com">
<wv2:WebView2.CreationProperties>
<wv2:CoreWebView2CreationProperties UserDataFolder="C:\Temp\webview2"/>
</wv2:WebView2.CreationProperties>
</wv2:WebView2>
</Border>
</window>
At first, I thought it was a browser problem but then the problem persisted on my testing VM, even when I installed the latest compatible Webview2 Runtime.
Both of my testing and dev environment have WebView2 Runtime (89.0.774.68) installed. And I have copied WebView2Loader.dll on the testing environment.
Any guidance?
EDIT: I have not tried Disabling one of Display adapter, but unfortunately, that option is not a way I'm trying to pursue. What I found so far is that, stated problem does not seem to reproduce on latest release of Windows 10.
We experienced a similar issue and finally discovered that it could reproduce only whenever we worked with more than one graphics card adapter. Perhaps it's also your case.
The same problem here,
Finally I found a solution by disabling one of my display adapters and changing the main display in Windows settings.
As a less aggressive method, you can also try to change the main monitor on Windows
It's completely odd but it's working now.
Related
I'm trying to control a browser using C#. The way that used to work was OLE/interop. This seems to be missing from modern browsers. All I need it to do is be able to navigate to a URL and then change the URL from time to time. The problem using Process.Start("http://example.com") is this usually spawns several children processes and I can't determine the exact process to kill later. Calling it several times simply creates new children. I tried using the WebBrowser and WebView controls. Yes, these give me the control I want, but the rendering engine is embedded in the application and is so old, no sites allow these controls to work anymore.
I found something called WebDriver. At first this seemed like a good solution, except it appears to be very dependent on the exact build of the browser and has dependencies on Selenium. It probably works great for automated testing, I'm not convinced it will work well for long term browser control if the browser updates itself.
Next comes CefSharp. I've used this in the past, but it also seems to have an embedded and outdated rendering engine and many sites complain it too is out of date. And even if CefSharp gets updated from time to time, I need to rebuild my application each time. The problem I see here is, the rendering engine is embedded into an assembly that gets distributed with my app. Yes, I've seen a huge list of other embedded solutions. Many of them haven't been updated in years.
Ideally, I could control a browser using something like WebDriver that worked on any browser version. I could launch an external browser like FireFox or Chrome. Do any browsers have an API? Here's exactly the pseudo code I'd like to implement using a modern browser:
ModernBrowser br = new ModernBrowser();
br.Navigate("about:blank"); // clear out last page
if(some_flag)
br.Navigate(Url); // navigate to new page.
If(done)
br.Close();
br = null;
That is all I need. Dead simple.
I'm trying to implement a media playback system. All the code works fine except where I need a modern browser to play back Pandora, Spotify or any other web based systems. They all require the latest browser versions or they simply don't work. Embedding a rendering engine in my application is a nightmare. Sure, I can get it to work today. I'm just not sure about tomorrow.
I decided to try CefSharp and it works. I realize I'll have to update this from time to time. I want to point out that if you decide to use CefSharp as an embedded browser, don't use NuGet on your live project. Create a throw-away project and install the CefSharp assemblies. As of the date of this entry, the Nuget install breaks your C# project and makes every assembly unusable. What I did was I created a throw-away project, added the CefSharp assemblies and then took the dependent binaries and put them in a new folder. I made my live project an X86 target and that works.
I have a very strange situation here with CEF Sharp x86 (67 with latest cef.redist 3.3497.1841), but originally reported with v49. It's very crazy, so I'm just looking, maybe somebody have stumbled upon anything similar. We host WPF ChromiumWebBrowser inside WinForms UserControl (via ElementHost) and it's running inside 3rd party application, with which it does not interact in any way (so it's a plugin to this host application). For about 100 or so users everything is ok, but for a single person this happens: webpage loads and displays correctly, but the ChromiumWebBrowser.IsBrowserInitialized flag is always false.
Now, by 'user' I don't mean Windows account, just a user in totally unrelated 3rd party application, logging-in against 3rd party userid/password verification - unrelated to any windows settings. So as crazy as it sounds we've tried it on multiple computers on multiple windows accounts, using different user ids for the application, and the result is still the same - for this one userid there is a problem, for others - all ok.
I wonder if anyone has had such crazy experience with CEF. I'm betting on some bug in .NET layer, as the actual browser works fine - webpage is rendered, you can browse normally. Also this has sth to do with CEF run as plugin to this exact 3rd party app - if I run a test winform app with same setup - user control -> element host -> WPF ChromiumWebBrowser, all is ok. CEF log is not much help, no errors other than in OK situation.
I'm not attaching any code or logs, I don't think it'd be helpful in this case. Just for more background the plugin has been around for almost 3 years with not a single bug reported, except this case. Just to make it clear - I need this flag to be true to be able to inject JS calls into the plugin.
Ok, so it turned out to be a case of opening 2 instances of browser within single process. One browser window was initializing and working fine, second was was displaying page, but reporting 'not initialized'. It became clear only when I went to customer and actually saw the scenario, because they did not report that they opened 2nd instance. I this case, they don't need 2nd instance, so that was the fix, maybe there is an error I our code, I'll follow up this issue once we do more through analysis.
My WinForms project involves a C# web browser control - and I am getting the dreaded scripting error (like this image, different error though) when I visit different webpages:
I have read, and done, all the stuff about updating the browser emulation mode from IE7 to IE9 (or 11) in the windows registry (a la this stuff Use latest version of Internet Explorer in the webbrowser control) and the error still persists.
Now this is really frustrating due to the fact the the web page I am visiting works fine in IE itself, it is just my embedded one that has the error.
In desperation, I renamed my generated exe file "iexplore.exe" and bingo, the app works, with no scripting errors.
So this tells me there must be other settings in the registry or somewhere that cause this error, if anyone knows what these are I'd be most grateful if you could share them please!
N.B. I don't want to suppress the errors, I want to run the script.
Set the WebBrowser.ScriptErrorsSuppressed property to true disable the alerts for errors. Documentation here.
You can also change the IE version used by your WebBrowser as seen here, though I recommend doing this in the installer as editing the registry requires admin permissions.
I would also recommend navigating to http://detectmybrowser.com/ from your WinForms browser to make sure that the changes you made to your registry are correct.
I'm at the point of giving up.
I need to view pdfs in my Winforms application, so I've tried using Adobe's ActiveX control, and the vanilla WebBrowser control. The pdfs are local, and can be opened from Explorer with no problems at all.
The weird thing is that the application views the pdfs fine when running in Visual Studio, but the built application simply shows a grey area where the pdf is supposed to be. The exact same thing happens with both the Adobe control and the WebBrowser control. After a while, I usually get an Adobe error saying There is a problem with Adobe Acrobat/Reader. If it is running, please exit and try again. (103:103). I've looked this error up, which advised me to do things that didn't work (turning off a security setting).
Moreover, if the WebBrowser control is called with a .Navigate(path, true), the application opens an IE window that displays the pdf just fine.
I've tried running as administrator, which makes no difference. I'm at wits' end, so any help would be greatly appreciated. Maybe going for a 3rd party control?
Some further detail: I tried both Adobe 11 and Adobe DC, on Windows 10 and 8.1 VMs, .Net 4.6. Only a Win7 VM seems to work fine.
I solved this by building to x86 targets. Apparently AcroPDF.dll doesn't support x64. Of course, the error messages weren't at all helpful.
My previous answer was incorrect. The real issue is Adobe's Protected Startup mode. This has to be turned off for the application to use the viewer directly without problems.
I am using .NET 4 and trying to use the desktop authentication for the StackApps site via the web-browser control (WPF and/or WinForms) to develop a NNTP Bridge for accessing StackOverflow (https://stackapps.com/questions/4215/stackapp-nntp-bridge-for-accessing-stackexchange-forums-like-stackoverflow).
It seems that the login cannot be done, because the web browser hangs up, after the page from "StackExchange Login" is displayed.
I use the following URL:
https://stackexchange.com/oauth/dialog?client_id=1736&scope=no_expiry&redirect_uri=https://stackexchange.com/oauth/login_success
It works in the normal IE browser, but not in a WinForms or WPF window... Does anyone know what the problem is?
It is simple to repoduce:
Create a WinForms-Project
Add the "WebBrowser" control to the dialog
Double-Click on the Form1
Add the following code
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("https://stackexchange.com/oauth/dialog?client_id=1736&scope=no_expiry&redirect_uri=https://stackexchange.com/oauth/login_success");
}
Start the application
Login by pressing the "login with Stack Exchange" account symbol
A new page gets loaded; it is displayed correctly, but you cannot enter your login name; the window hangs...
The same happens, if I use WPF-App and the WPF-WebBrowser-Control... it seems that it is stuck in an endless-loop in JavaScript...
Any hint on how to solve ths problem?
Or is it possible to debug the JavaScript in the WebBrowser-Control???
Fixing WebBrowser Control
I also had the issue of the WebBrowser control handing when trying to login.
Although requesting a token in IE (11) works, I found that IE itself also hangs when I put it in IE 7 emulation mode. This suggested to me that my previous attempt to make the WebBrowser control use a newer version had failed.
I found this article, Web Browser Control Specifying the IE Version, which suggests that for 32 bit applications in 64 bit mode, you need to set a different registry value.
So now, I've added two values in the registry:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
and
HKEY_CURRENT_USER\Software\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
In both of them, I added a DWORD value named 'MyExecutable.exe' (where MyExecutable is the actual name of my executable). The value for each of them is 9000 which will work for IE9 and above. Watch out when using RegEdit to test this, it will default to hexadecimal instead of decimal. Also, make sure it is a DWORD value, not any other type.
This seems to do the trick. I can now run the application, go through the login process, and eventually I am redirected to the url specified by me, which I can then capture using the OnNavigate event of the webbrowser control.
Remaining issue
It doesn't really work perfectly. The first time I was redirected to some OpenID page as well, but at least the form didn't hang. With subsequent attempts, apparently the login (which succeeded before) is remembered and I get the message "Navigation to the webpage was cancelled" with a link to refresh the page. When I click that link, I am immediately redirected to the redirect_url I specified when requesting the login form. At least that part works, and I get an actual access_token and an expiry time, so for now I'm happy.
Update: After some testing, it turned out that the previous login was remembered. That causes the request uri to direct to the redirect_uri immediately. I used the OnBeforeNavigate event to detect this, but it isn't fired in this case. I now linked the NavigateComplete2 event, and that one is triggered in this scenario.
Fix for .NET?
I think for .NET the solution should be the same: add the executable (and MyExecutabl.vshost.exe as well, for debugging purposes in Visual Studio) to the first key. If it's a 32 bit executable running on 62 bit Windows, you might also need to add it to the second key, although I'm sure if that rule applies to .NET as well. I don't do C# on a daily basis, and I'm trying to get it to work in Delphi first, but if I find time to test this in C# I will post the update here.
In the end, it would be nice if the actual issue would be solved, and the JavaScript would work in IE7 mode as well, but at least this seems to be a proper work-around.
Unfortunately, I'm not a JavaScript developer, so I only could try to explain you how to debug a JavaScript that executes in the WebBrowser control.
This approach is for the Microsoft Visual Studio, I don't know if Delphi can provide similar functionality.
Enable Script Debugging (both Internet Explorer and Other) in Internet Explorer settings.
Disable Friendly HTTP messages in Internet Explorer settings.
Enable Display a notification about every script error in Internet Explorer settings.
From Visual Studio, start your WebBrowser hosting application without debugging (i. e., Ctrl + F5).
In Visual Studio, go to Debug → Attach to Process… and select your application in the list.
Hit the Select… button to the right of Attach to: field and choose Script code.
Hit the Attach button. Visual Studio starts the script debugger.
In your application, navigate to the deadlocking page by pressing the Login with Stack Exchange account symbol.
Go to Visual Studio and press the Pause button on the debugging toolbar.
Now you can look into your script code and investigate the code itself, the call stack, the variable values and so on. You can set breakpoints too. Perhaps you can then find the place where the script hangs. As I said before, I'm not a web developer and cannot help you with this…
Update:
I guess I can propose you a working solution.
My investigation shows that the WebBrowser hangs when it renders the content in the IE7 mode (what is the default mode even if you have IE10 in your system). You should force it to switch into IE9 mode. In IE9 mode, the page renders well and does not cause the script to stuck in an endless loop.
You can switch your WebBrowser to the IE9 mode using one of the following methods:
Define the global browser emulation mode for your application in Windows registry.
For 32 bit OS, go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION.
For 64 bit OS, use HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION.
In this node, create a new DWORD parameter called YourApplicationExeName.exe with a value 9000 (0x2710). You can create another entries for your *.vshost.exe executables, if you want this to work in Visual Studio debug mode.
Manipulate the source for the WebBrowser to switch it in the IE9 mode.
This will be more complicated. You need to alter the <head> tag of the html document adding a new <meta> tag preferably as a first element: <meta http-equiv="X-UA-Compatible" content="IE=9"/>.
This will cause the WebBrowser to switch its mode on document rendering. Since you can't change the compatibility mode after the document is rendered, you could use a proxy as a source for your WebBrowser, so this proxy will add the header.
I`ve successfully tested this with the 1st approach, and the second one should work too.
Hope that helps!
Project + Properties, Debug tab, tick the "Enable native code debugging" option. Ensure that you've got the Microsoft Symbol server enabled (Tools + Options, Debugging, Symbols), I know you do :)
You can now use Debug + Break All and see what's going on inside the browser. Do so repeatedly to get the lay of the land. You'll see that Javascript is executing (jscript8.dll) and constantly forcing the layout engine to recalculate layout, never getting the job done.
Browsers in general are vulnerable to Javascript that's stuck in an endless loop. A regular browser tends to put up a dialog after several dozen seconds to allow the user to abort the JS, but WebBrowser doesn't have that feature. Nor does it have the dev tools so debugging the JS isn't going to be a great joy either. This is going to be difficult to get fixed.
You might consider using the OAuth 2.0 api instead. Notes on usage are on this web page. Exactly how to integrate that with WebBrowser is a bit murky to me, I don't have a key to test this. Find help for this at the Stackapps site. You are probably not the first SE api user that ran into this problem.