IE webrowser control doesn't display CSS box shadow [duplicate] - html

I've created a Winforms app that uses a WebBrowser control; I dynamically assign its Uri. It worked fine for awhile, but now I'm getting this msg:
You seem to be using an unsupported browser. Older browsers can put your security at risk, are slow and don't work with newer Google Maps features. To access Google Maps, you'll need to update to a modern browser.
The last two words are a link, and following that link, I see:
You are currently using...
IE 11
So, okay, the WebBrowser component uses IE 11; how can I change that?
My machine is set to use Chrome as its browser; perhaps the control should use whatever your current browser is? I don't know if that's possible/feasible.
UPDATE
Okay, I'm willing to give Reza's suggestion a try. But when I navigate to the specified spot in regedit, and right-click in the right pane to add a New entry, it has three options:
Key, String Value, Binary Value
I reckon the string values are the ".exe" strings, and the Binary values are the "dword" vals, but what should the "Key" values be?

Note: The post is about WebBrowser control, however, for all the new
.NET projects the main solution is using
WebView2.
To learn more, take a look at this post:
Getting started with WebView2.
WebBrowser Control
The WebBrowser control uses the same Internet Explorer version which is installed on your OS but it doesn't use the latest document mode by default and shows content in compatibility mode.
Symptom - As a symptom, the site works properly in Internet Explorer or other browsers, but WebBrowser control doesn't show the site well and for some sites it shows script errors.
Solution - You can tell the WebBrowser control to use the latest document mode without compatibility mode in WebBrowser control. You can follow instructions here to disable the setting using registry.
[Reference: Browser Emulation]
Apply Browser Emulation setting using code
If you want to apply the settings using code, run the following code once:
using (var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
#"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
true))
{
var app = System.IO.Path.GetFileName(Application.ExecutablePath);
key.SetValue(app, 11001, Microsoft.Win32.RegistryValueKind.DWord);
key.Close();
}
In above code, I've used 11001 which means IE11 Edge mode.
Internet Explorer 11. Webpages are displayed in IE11 edge mode,
regardless of the declared !DOCTYPE directive. Failing to declare a
!DOCTYPE directive causes the page to load in Quirks.
Apply the Browser Emulation setting manually
Open Registry editor and browse HKEY_CURRENT_USER, go to the following key:
Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
Add the following values:
"YourApplicationFileName.exe"=dword:00002af9
"YourApplicationFileName.vshost.exe"=dword:00002af9
(In older versions of Visual Studio you needed to add vshost.exe value as well, when you run your program in Visual Studio.)
To create entries right click on an empty area of the right pane, then in the window which appears after selecting dword value, choose hexadecimal and enter 2af9:
In above steps, I've used 11001 which means IE11 Edge mode.
Use WebViewCompatible Control for Windows Forms
You can also use the new WebViewCompatible control for Windows Forms. You can see simple steps to use here: Replace WebBrowser control by new WebView Compatible control for Windows Forms.
WebViewCompatible uses one of two rendering engines to support a broader set of Windows clients:
On Windows 10 devices, the newer Microsoft Edge rendering engine is used to embed a view that renders richly formatted HTML content from a remote web server, dynamically generated code, or content files.
On devices running older versions of Windows, the System.Windows.Controls.WebBrowser is used, which provides Internet Explorer engine-based rendering.
Note: WebView2 is a replacement for WebView and WebViewCompatible.
Set X-UA-Compatibile meta tag
In case that you have access to the html content of the page and you can change the content (for example it's a local html file, or the site belong to yourself) then you can set X-UA-Compatibile meta tag in the head like: <meta http-equiv="X-UA-Compatible" content="IE=Edge" />.
Use other Browser Controls
You can rely on other browser controls like CefSharp.

In my case for embedded custom protocol on an application, I will allow only to browse pages served by the application, and no content from the outside, so I wanted to skip saving to the Windows Registry. When I tested after following Reza Aghaei answer and found that you can change the compatibility mode from within the content page. This will skip the need to configure a registry key, but you will have to add it to every page.
For changing the compatibility mode of a page, you must add a meta tag for it to be applied by the rendering engine:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
</head>
<body>
...
</body>
</html>

The below procedures will add the correct key and remove it again.
Call the CreateBrowserKey upon loading the form that your web browser is in.
Then when closing the form, call the RemoveBrowserKey
Private Sub CreateBrowserKey(Optional ByVal IgnoreIDocDirective As Boolean = False)
' Dim basekey As String = Microsoft.Win32.Registry.CurrentUser.ToString
Dim value As Int32
' Dim thisAppsName As String = My.Application.Info.AssemblyName & ".exe"
' Value reference: http://msdn.microsoft.com/en-us/library/ee330730%28v=VS.85%29.aspx
' IDOC Reference: http://msdn.microsoft.com/en-us/library/ms535242%28v=vs.85%29.aspx
Select Case (New WebBrowser).Version.Major
Case 8
If IgnoreIDocDirective Then
value = 8888
Else
value = 8000
End If
Case 9
If IgnoreIDocDirective Then
value = 9999
Else
value = 9000
End If
Case 10
If IgnoreIDocDirective Then
value = 10001
Else
value = 10000
End If
Case 11
If IgnoreIDocDirective Then
value = 11001
Else
value = 11000
End If
Case Else
Exit Sub
End Select
Microsoft.Win32.Registry.SetValue(Microsoft.Win32.Registry.CurrentUser.ToString & BrowserKeyPath, _
Process.GetCurrentProcess.ProcessName & ".exe", _
value, _
Microsoft.Win32.RegistryValueKind.DWord)
End Sub
Private Sub RemoveBrowserKey()
Dim key As Microsoft.Win32.RegistryKey
key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(BrowserKeyPath.Substring(1), True)
key.DeleteValue(Process.GetCurrentProcess.ProcessName & ".exe", False)
End Sub

The C# WebBrowser class is a basically a IE wrapper and because of this it cannot be changed.
See this link:
The WebBrowser control is a managed wrapper around a component installed with Internet Explorer.
For alternatives you can check out
WebKit.NET
GeckoFX

Related

Interact with Edge/HTML through vbscript

I'm new with VBS and I can't find how to interact (basic functions such as clic, write something) with a webpage after having load the URL in Edge.
Here is how I open my webpage for instance
dim objShell, strPath1, strAttr1, strAttr2
Set objShell = WScript.CreateObject("WScript.Shell")
strPath1 = """C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"""
strAttr1 = " -inprivate "
strAttr2 = " http://www.someWebPage.com/ "
objShell.Run strPath1 & strAttr1 & strAttr2
I've found many things like that :
Set IE = WScript.CreateObject("InternetExplorer.Application", "IE_")
IE.Visible = True
IE.Navigate "https://www.somepage.com/"
With this object IE, it seems possible to modify forms, click here and there ... But it only worked with Internet Explorer.
I think I can manage to find the right HTLM piece of code that is useful (at least this is not what I'm looking for right now ^^ ).
Do you have any advise ?
Thanks a lot in advance
Microsoft Edge browser doesn't support the COM automation interface that used in VBS. If you want to automate Microsoft Edge, you should use WebDriver.
To get started using WebDriver, you will need to download a testing framework of your choice along with an appropriate language binding and the MicrosoftWebDriver server.
We usually use Selenium and you could download the language binding in this page. At the same time, you could download Microsof Edge WebDriver in this page.
Reference link:
Programmatically create Edge browser instance
Will Microsoft Edge support COM automation (InternetExplorer object)?

Cannot refresh <object/> when changing from application/pdf to text/html

I am trying to refresh an element in the DOM tree. Basically the typescript code simply update the data & type of an existing HTMLObjectElement. Here is the pseudocode:
const textCanvas: HTMLObjectElement = <HTMLObjectElement>(curElement.children.namedItem('text-canvas'));
// Populate both the actual data as well as the associated mime/type:
textCanvas.data = enabledTextElement.textData; // 'blob:http://localhost:8081/d3c9a0ac-8e40-4e0e-aeb8-91656273837c'
textCanvas.type = enabledTextElement.mimeType; // 'application/pdf'
Which then gets updated with:
textCanvas.data = enabledTextElement.textData; // 'blob:http://localhost:8081/3c5ad888-0a7f-41d0-8ec9-35c334ef3f20'
textCanvas.type = enabledTextElement.mimeType; // 'text/html'
My chrome simply display the PDF version:
The funny part is if I do the opposite (html first), then the element gets properly updated (html text is displayed, then the PDF box is displayed). I tried to verify if this is supposed to work at:
https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element
And it seems it should. I also found an old bug report:
https://bugs.chromium.org/p/chromium/issues/detail?id=123536
-> <object> works in every browser except Google Chrome
Using:
Google Chrome 80.0.3987.163 (Official Build) (64-bit) (cohort: 81_Win_122)
Revision e7fbe071abe9328cdce4ffedac9822435fbd3656-refs/branch-heads/3987#{#1037}
OS Windows 8.1 (Build 9600.19676)
JavaScript V8 8.0.426.30
If that help the URL are created from a Blob which is then passed to URL.createObjectURL.
I am currently using the following work-around:
textCanvas.data = '';
textCanvas.type = enabledTextElement.mimeType;
textCanvas.data = enabledTextElement.textData;
Seems to make the symptoms go away. I've filled a bug report just in case:
https://bugs.chromium.org/p/chromium/issues/detail?id=1076373

fill out form using vba and chrome

currently i can accomplish this using IE
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "www.google.com"
ie.document.getElementByID("blah").value = "blah"
im curious if there is a way to navigate to website and fill out info using other than IE with VBA for example with FireFox or Chrome
i know how to navigate to other websites using any of the explorers for example Chrome as per below, but i would like to know how can fill out fields like search field on www.google.com using Chrome
call Shell("C:\Program Files\Google\Chrome\Application\chrome.exe"& " " & URL)
You can use this Selenium wrapper to drive Chrome or Firefox (or PhantomJS). Note that it is currently in beta. Once it is installed, either add a reference to Selenium Type Library or use late binding (example below).
In my (very) limited tests, the only noticeable difference is the couple seconds it takes to load the driver.
Here is a simple example from the link above (modified to use late binding) that fills out the search field in Google and clicks the search button:
Dim selDriver As Object
Set selDriver = CreateObject("Selenium.WebDriver")
selDriver.Start "chrome", "http://www.google.com/"
selDriver.Open "http://www.google.com"
selDriver.Type "name=q", "Eiffel Tower"
selDriver.Click "name=btnG"
selDriver.stop
As of 2016, the Selenium wrapper was moved to Github instead of the above Google address. Additionally, if you're using Chrome you'll want to update the web driver for Google Chrome here.
Selenium Basic
After downloading these items you'll then need to follow the instructions above for adding the library to in your Visual Basic Editor from within Excel. Afer doing so, you should be able fill out a web form using vba and chrome as originally requested.

How to Modify AJAX Based site Content OnDocumentComplete Event

I have an IE tool bar application under the DocumentComplete Event of the Page , i was disabling the HTML links using Concept of BHO(Browser Helper Object) that is working well for some of the sites but when i browse some AJAX/JQUERY based sites ,where the data will be popuplated dynamically and more over source code is also not vsible for dynamic data,this link disabling feature is not working.....
How To Disable or Modify the Content Of Dynamic Data When We load into browser??
HTMLDocument document = (HTMLDocument)webBrowser.Document;
IHTMLElementCollection hh = ((IHTMLElementCollection)document.getElementsByTagName("a"));
foreach (IHTMLElement ht in hh)
{
((HTMLAnchorElement)ht).removeAttribute("href", 1);
((HTMLAnchorElement)ht).style.color = "#b9b0b0";
}
Any Help ?
It depends on your IE version. Till IE 8 there is no DOM Mutation event generated but there is an alternative approach as mentioned here. Although IE 9 supports some basic dom mutation events as mentioned in this IE blog. Also, see this MSDN entry for the supported interface in IE9.
A very crude approach is to use a timer event for monitoring any changes in the DOM content. But you have to take care of threading issues and have to keep per window text information (by window I mean tabs and also IFrame content).
Another approach is to use Asynchronous Pluggable Protocols for monitoring any Ajax request and then accordingly notifying the appropriate tab/window. This is harder then the previous crude approach.
I got answer for the above mentioned problem. The following are the resolution steps what I have followed for the issue.
I just read the whole page content into "MSHTML" object as mentioned in the question
HTMLDocument document = (HTMLDocument)webBrowser.Document;
and again I just loaded it into a Web Browser control.
From there I can read the data easily and I just removed "href" property.

HTML / Javascript One Click Print (no dialogs)

Is it possible to have a print option that bypasses the print dialog?
I am working on a closed system and would like to be able to pre-define the print dialog settings; and process the print as soon as I click the button.
From what I am reading, the way to do this varies for each browser. For example, IE would use ActiveX. Chrome / Firefox would require extensions. Based on this, it appears I'll have to write an application in C++ that can handle parameters passed by the browser to auto print with proper formatting (for labels). Then i'll have to rewrite it as an extension for Chrome / Firefox. End result being that users on our closed system will have to download / install these features depending on which browser they use.
I'm hoping there is another way to go about this, but this task most likely violates browser security issues.
I ended up implementing a custom application that works very similar to the Nexus Mod Manager. I wrote a C# application that registers a custom Application URI Scheme. Here's how it works:
User clicks "Print" on the website.
Website links user to "CustomURL://Print/{ID}
Application is launched by windows via the custom uri scheme.
Application communicates with the pre-configured server to confirm the print request and in my case get the actual print command.
The application then uses the C# RawPrinterHelper class to send commands directly to the printer.
This approach required an initial download from the user, and a single security prompt from windows when launching the application the first time. I also implemented some Javascript magic to make it detect whether the print job was handled or not. If it wasn't it asks them to download the application.
I know this is a late reply, but here's a solution I'm using. I have only used this with IE, and have not tested it with any other browser.
This Sub Print blow effectively replaces the default print function.
<script language='VBScript'>
Sub Print()
OLECMDID_PRINT = 6
OLECMDEXECOPT_DONTPROMPTUSER = 2
OLECMDEXECOPT_PROMPTUSER = 1
call WB.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,1)
End Sub
document.write "<object ID='WB' WIDTH=0 HEIGHT=0 CLASSID='CLSID:8856F961-340A-11D0-A96B-00C04FD705A2'></object>"
</script>
Then use Javascript's window.print(); ties to a hyperlink or a button to execute the print command.
If you want to automatically print when the page loads, then put the code below near tag.
<script type="text/javascript">
window.onload=function(){self.print();}
</script>
I am writing this answer for firefox browser.
Open File > Page Setup
Make all the headers and footers blank
Set the margins to 0 (zero)
In the address bar of Firefox, type about:config
Search for print.always_print_silent and double click it
Change it from false to true
This lets you skip the Print pop up box that comes up, as well as skipping the step where you have to click OK, automatically printing the right sized slip.
If print.always_print_silent does not come up
Right click on a blank area of the preference window
Select new > Boolean
Enter "print.always_print_silent" as the name (without quotes)
Click OK
Select true for the value
You may also want to check what is listed for print.print_printer
You may have to choose Generic/Text Only (or whatever your receipt printer might be named)
The general answer is: NO you cannot do this in the general case but there some cases where you might do it.
Check
http://justtalkaboutweb.com/2008/05/09/javascript-print-bypass-printer-dialog-in-ie-and-firefox/
If you where allowed to do such a thing anyway, it would be a security issue since a malware script could silently sent printing jobs to visitor's printer.
I found a awesome plugin by Firefox which solve this issue. try seamless printing plugin of firefox which will print something from a web application without showing a print dialog.
Open Firefox
Search addon name seamless printing and install it
After successful installation the printing window will get bypassed when user wants to print anything.
I was able to solve the problem with this library: html2pdf.js (https://github.com/eKoopmans/html2pdf.js)
Considering that you have access to it, you could do something like that (taken from the github repository):
var element = document.getElementById('element-to-print');
html2pdf(element);