Webbrowser control not working with attachEvent() [duplicate] - c#

This question already has answers here:
How can I get the WebBrowser control to show modern contents?
(4 answers)
Closed 6 years ago.
My webbrowser control displays an intranet site. It was working fine, until the admin changed a setting in iis that forces ie11 to render in Edge mode. Now my webbrowser control comes up with the script error "object doesn't support property or method attachEvent."
Yes, I know attachEvent is deprecated in ie11. No, I do not have control over the webpage code. No, I can't force the admin to change the setting back again.
I tried using registry settings for my application under browser emulation, using all the codes starting with ie9 up through ie10. None of them had any effect.
Can anyone tell me how to force my webbrowser control to render in such a way as to avoid that script error and continue logging in? The call to attachEvent must be called upon successful login, because when I used bad credentials on the login page the error doesn't come up. When my application was working, the page defaulted to ie 9 compatibility. But it seems the admin's IIS setting has nullified that.

Since you cannot alter the code, I recommend implementing a attachEvent/detachEvent polyfill, like this
HTMLElement.prototype.attachEvent = function(event, cb) {
var onEventName = "on" + event,
obj = this;
if (obj.addEventListener) {
obj.addEventListener(event, cb, false);
} else if (obj.attachEvent) {
obj.attachEvent(onEventName, cb);
} else {
var currentEventHandler = obj[onEventName];
obj[onEventName] = function() {
if (typeof currentEventHandler === 'function') {
currentEventHandler.apply(obj, arguments);
}
cb.apply(obj, arguments);
};
}
};
HTMLElement.prototype.detachEvent = function(event, cb) {
var onEventName = "on" + event,
obj = this;
if (obj.removeEventListener) {
obj.removeEventListener(event, cb, false);
} else if (obj.detachEvent) {
obj.detachEvent(onEventName, cb);
} else {
delete obj[onEventName];
}
};
Here's a working plnkr demonstration (apologies for not using a snippet). I based this code using this old git.
Do note the code is incomplete and not for production, e.g. it is not checking whether HTMLElement, attachEvent, detachEvent exist.

Related

Re-using a specific iexpore window by updating its URL

I have an application that monitors a file, and based on its contents launches a browser using this code:
Process.Start("iexplore", "-nomerge " + fullUrl);
Now as with many small projects, the requirements have changed. The change is that only one browser can be launched from my program at a time.
Also, another program is capable of launching a browser with another url, and I cannot shut it down, eliminating the option of just closing down all instances of iexplore and then launching mine. ( which is what I did originally )
Is there a way to launch a browser and continue to keep control of it so you can update the URL of that specific instance of iexplore using c#?
This code is close to what is in the answer on the duplicate post, but is slightly different, so I am sharing it here.
foreach (SHDocVw.InternetExplorer ie in new SHDocVw.ShellWindowsClass())
{
if (ie.FullName.ToLower().Contains("iexplore") &
ie.LocationURL.ToLower().Contains("&qtype=mine"))
{
ie.Visible = true;
ie.Navigate(fullUrl);
openNewBrowserWindowWindow = false;
}
}
if (openNewBrowserWindowWindow) {
SHDocVw.InternetExplorerClass IE = new SHDocVw.InternetExplorerClass();
IE.Visible = true;
IE.Navigate(fullUrl);
}

Check if browser closed manually

In visual studio 2010, working with c#;
I open a browser with:
private IE browser;
private void Set_Browser()
{
string splashUrl = "google.com";
browser= new IE(splashUrl);
}
If a user(person) closes the browser by accident, then my application will not be able to work anymore.
QUESTIONS:
So how do I check if a user closed the browser manually?
Can I unable a user from closing the browser by adding the browser to my
application GUI as a control? [using Windows Forms]
-> How do I do that?
Last question related to this post How to use watin with WebBrowser control? (2 years old, but no decent answer too)
EDIT: The solution in give URL seems to work. Problem is that if I try to send the WebBrowser.ActivateX.. as an object to other class. Then my browser = new IE(..) returns null. It does work when I instantiate it in the form class though. Any solutions?
You can search for the process of internet explorer every x seconds and see if the browser is already running using this code:
bool isRunning = false;
foreach (Process clsProcess in Process.GetProcesses()) {
if (clsProcess.ProcessName.Contains("iexplore"))
{
isRunning = true;
break;
}
}
You can use this article
Or you can add a browser control to your application using this article
One thing you can do is hide the browser to avoid users closing it .. See this SO question.
Hiding Internet Explorer when WatiN is run

How can you programmatically detect if javascript is enabled/disabled in a Windows Desktop Application? (WebBrowser Control)

I have an application which writes HTML to a WebBrowser control in a .NET winforms application.
I want to detect somehow programatically if the Internet Settings have Javascript (or Active Scripting rather) disabled.
I'm guessing you need to use something like WMI to query the IE Security Settings.
EDIT #1: It's important I know if javascript is enabled prior to displaying the HTML so solutions which modify the DOM to display a warning or that use tags are not applicable in my particular case. In my case, if javascript isn't available i'll display content in a native RichTextBox instead and I also want to report whether JS is enabled back to the server application so I can tell the admin who sends alerts that 5% or 75% of users have JS enabled or not.
Thanks to #Kickaha's suggestion. Here's a simple method which checks the registry to see if it's set. Probably some cases where this could throw an exception so be sure to handle them.
const string DWORD_FOR_ACTIVE_SCRIPTING = "1400";
const string VALUE_FOR_DISABLED = "3";
const string VALUE_FOR_ENABLED = "0";
public static bool IsJavascriptEnabled( )
{
bool retVal = true;
//get the registry key for Zone 3(Internet Zone)
Microsoft.Win32.RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3", true);
if (key != null)
{
Object value = key.GetValue(DWORD_FOR_ACTIVE_SCRIPTING, VALUE_FOR_ENABLED);
if( value.ToString().Equals(VALUE_FOR_DISABLED) )
{
retVal = false;
}
}
return retVal;
}
Note: in the interest of keep this code sample short (and because I only cared about the Internet Zone) - this method only checks the internet zone. You can modify the 3 at end of OpenSubKey line to change the zone.
If you are having troubles with popups popping up, i've included a solution for you, and if you want to disable/enable javascript on th client machine (or even just read/query if it is enabled/disabled) ive included that answer for you as well, here we go:
Which popup message do you want to disable? If it's the alert message, try this, obviously resolving the window or frame object to your particular needs, I’ve just assumed top-level document, but if you need an iframe you can access it using window.frames(0). for the first frame and so on... (re the JavaScript part)... here is some code, assuming WB is your webbrowser control...
WB.Document.parentWindow.execScript "window.alert = function () { };", "JScript"
You must run the above code only after the entire page is done loading, i understand this is very difficult to do (and a full-proof version hasn't been published yet) however I have been doing it (full proof) for some time now, and you can gather hints on how to do this accurately if you read some of my previous answers labelled "webbrowser" and "webbrowser-control", but getting back to the question at hand, if you want to cancel the .confirm JavaScript message, just replace window.alert with window.confirm (of course, qualifying your window. object with the correct object to reach the document hierarchy you are working with). You can also disable the .print method with the above technique and the new IE9 .prompt method as well.
If you want to disable JavaScript entirely, you can use the registry to do this, and you must make the registry change before the webbrowser control loads into memory, and every time you change it (on & off) you must reload the webbrowser control out and into memory (or just restart your application).
The registry key is \HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\ - the keyname is 1400 and the value to disable it is 3, and to enable it is 0.
Of course, because there are 5 zones under the Zones key, you need to either change it for the active zone or for all zones to be sure. However, you really don't need to do this if all you want to do is supress js dialog popup messages.
Let me know how you go, and if I can help further.
Here is a suggestion - Encode the warning into your webpage as default. Create a javascript that runs on page load which removes that element. The warning will be there when ever javascript is not allowed to run.
It's a long while since I coded client side HTML javascript to interact with the DOM so I may be a little out of date. i.e. you will need to fix details, but I hope I get the general idea across.
<script>
document.getElemntByID("noJavascriptWarning").innerHTML="";
</script>
and in your HTML body
<DIV id="noJavascriptWarning" name="noJavaScriptWarning">Please enable Javascript</DIV>

Why does WatiN Freeze the application

I have been working on a project and noticed the watin library freezing the application. Here is the code:
using(var browser = new IE(url))
{
if(!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password))
{
browser.Link(Find.ById("overridelink")).Click();
}
}
The code above works fine if the ID "overidelink" attribute is found. If its not found the whole application freezes up. How can I prevent this?
First check if it's exists and then excecute the click
if (Browser.Link(Find.ById("overridelink")).Exists)
{
Browser.Link(Find.ById("overridelink")).Click();
}

Webbrowser control ignores FEATURE_BROWSER_EMULATION reg entry

Im developing a custom browser solution with .net's Webbrowser control.
To disable the IE-Compatibilty View, I set the registry entry
Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION:
[Sreenshot regedit] http://zbirk.mirk.at/browserreg.png "Screenshot"
i tried to use the values: dword=8000,dword=8888,dword=9000, but the webbrowser control seems to ignore these reg entries.
Maybe someone had this problems too and may help me.
The WebBrowser control definately DOES respect these keys.
Remember that while taskman may show application.exe in the name column, if you are debugging the exe name is application.vshost.exe
So in my application sI just attempt to create the key every time the app runs. If it fails to create it (because it already exists) then I continue running, if it creates the key then I inform the user that they need to restart the application.
ensure that you are not running within vshost
the app name would be different ie appname.vshost.exe
Thx for your reply, now its working.
Her is my working peace of code:
public void setIEcomp()
{
String appname = Process.GetCurrentProcess().ProcessName+".exe";
RegistryKey RK8 = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION",RegistryKeyPermissionCheck.ReadWriteSubTree);
int value9 = 9999;
int value8 = 8888;
Version ver = webBrowser1.Version;
int value = value9;
try
{
string[] parts = ver.ToString().Split('.');
int vn = 0;
int.TryParse(parts[0], out vn);
if (vn != 0)
{
if (vn == 9)
value = value9;
else
value = value8;
}
}
catch
{
value = value9;
}
//Setting the key in LocalMachine
if (RK8 != null)
{
try
{
RK8.SetValue(appname, value, RegistryValueKind.DWord);
RK8.Close();
}
catch(Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
}
I too could not see that FEATURE_BROWSER_EMULATION made any difference in my application.
I was testing the FEATURE_BROWSER_EMULATION functionality by manually editing the registry with regedit. Nothing I did made any difference. My hosted page was still failing on any new-ish JavaScript and could not load external libraries.
I found my mistake:
I was editing the 64-bit view of the registry with regedit. My app was running as a 32-bit app and looking at the 32-bit view of the registry. That's why my changes to the registry seemed to have no impact on my application. By the way, the WPF project template defaults to "Prefer 32-bit."
Manually editing with regedit within the Wow6432Node key worked:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION
Of course, setting the DWORD value programmatically within your application will also work, since your 32-bit application will edit within the Wow6432Node.
An older post and solution is no longer accurate.
Running procmon and watching for FEATURE_BROWSER_EMULATION shows the following registry variables actually checked. This was for WINWORD.exe but other than that - take your pick...
HKU\S-1-5-21-[my-sid-paws-off]\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION\WINWORD.EXE
HKU\S-1-5-21-[my-sid-paws-off]\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION*
HKLM\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION(Default)
HKLM\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION\WINWORD.EXE
HKLM\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION\WINWORD.EXE
HKLM\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION*
HKLM\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION*

Categories

Resources