I am trying to have spellcheck work in a Winforms web browser control.
This is my current C# code:
try
{
String appname = Process.GetCurrentProcess().ProcessName + ".exe";
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree);
object ieVal = key.GetValue(appname, null);
MessageBox.Show(ieVal.ToString());
if (ieVal == null || (int)ieVal != 11001)
{
key.SetValue(appname, 11001, RegistryValueKind.DWord);
}
key.Close();
}
catch
{
MessageBox.Show("Registry stuff didn't work");
}
MessageBox.Show(webBrowser1.Version.ToString());
webBrowser1.DocumentText = "<html><head><body><div spellcheck=\"true\" style=\"width:100%; height:100%;\" contenteditable=\"true\"></div>"
+"<script>alert(navigator.userAgent);</script>"
+"</body></html>";
So first I set the proper registry key so that the browser emulates IE11
Then I add a div tag with spellcheck attribute set to true.
The version that the MessageBox.Show(webBrowser1.Version.ToString()) shows is:
11.0.9600.18525
The navigator.userAgent that the Javascript displays is:
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
So it seems like the web browser control is using IE11. But when I type the spell check doesn't work.
Note: When I run that html code with the real IE everything works properly.
Also, the navigator.userAgent displayed on the actual browser is:
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
Note2: When I run my application on Windows 10 machine the spellcheck works. But I need to make it work on Windows 7 machines.
I had very similar problems using a WebBrowser control on a form and found 2 solutions, each with differing effects, which could both be used.
Using spellcheck=true in the HTML:
Adding the attribute spellcheck=true to the HTML or BODY or TEXTAREA tags, depending on where you want it implemented, will allow spelling checking on text input boxes (my tests were on Windows 10).
Note that any EXISTING text in the text boxes was not spell checked - you had to type NEW text in. This caught me out when running test EXEs with a pre-filled text box, which never got the little red underlines on its spelling mistakes.
Registry entry for FEATURE_SPELLCHECK
This did something different. It allowed spell checking in TinyMCE to work in our embedded web browser control. On its own, it did not enable spell checking in text areas.
See the link below for references to a registry key close to the one you were setting. However, it requires a new key and then a value that matches the name of the EXE you're running. In my case, this involved creating the FEATURE_SPELLCHECKING registry key, and then a DWORD with name TEST123.EXE and value 1.
https://msdn.microsoft.com/en-us/library/ee330735%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#spellchecking
I found this through the page linked below, where someone reports it not working for Windows 7. Note that this person also tries it with a "local user" key, which does not work in my experience:
https://social.msdn.microsoft.com/Forums/ie/en-US/515fa4b1-2b85-46e4-a041-7dc27c4539c4/how-to-enable-spell-checker-in-web-browser-control-for-ie10?forum=ieextensiondevelopment
Use both of the above.
We found that approach 2 above met most of our needs, as we were using TinyMCE. However, in other applications, both 1 and 2 can be used in conjunction to provide the most functionality.
Related
I am trying to access a webpage (that is not under my control) namely allscripts sandbox via a WebBrowser control. My computer's internet explorer is correctly set up for said webpage (Added in Trusted Sites, Allowed and installed all active-x addons, running in compatibility mode, etc).
The webbrowser control displays the following error:
This webpage wants to run 'Some ActiveX control' which isn't compatible with Internet Explorer's enhanced security features. If you trust this site you can disable Enchanced Protected Mode for this site and allow the control to run.
I have not enabled (to the best of my knowledge) the enhanced protected mode.
Also trying to ignore the errors and continue with log-in displays a Message
The Centricity's container for .NET-based pages failed to initialize. Make sure your .NET environment is configured to grant Full Trust to this Website.
The above was also an error on the default IE until i run the command %WINDIR%\Microsoft.NET\Framework\v2.0.50727\caspol -q -m -cg Trusted_Zone FullTrust.
I have tried various registry keys but none seemed to work.
I have also tried implementing a custom IInternetSecurityManager that Maps all urls to zone Trusted and returns URLPOLICY_ALLOW on all ProcessUrlAction calls.
Any suggestion would be appreciated.
The problem could be that webbrowser uses by default an old version of the IE. Take a look at Use latest version of Internet Explorer in the webbrowser control
The webbrowser control is ie11 wrapped with a com wrapper that throttles back ie11 to ie7 mode. There's not a lot else going on there that I can imagine would cause your issue.
Since this page works for you when you run ie11 externally then the most likely explanation seems to be your attempt to force the control into ie11 mode is the problem.
I suggest you try Mentor's code here:
Set WPF webbrowser control to use IE10 mode
Which will automate adding the name of the running program to the registry.
var pricipal = new System.Security.Principal.WindowsPrincipal(
System.Security.Principal.WindowsIdentity.GetCurrent());
if(pricipal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)) {
RegistryKey registrybrowser = Registry.LocalMachine.OpenSubKey
(#"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", true);
string myProgramName = Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var currentValue = registrybrowser.GetValue(myProgramName);
if (currentValue == null || (int)currentValue != 0x00002af9)
registrybrowser.SetValue(myProgramName, 0x00002af9, RegistryValueKind.DWord);
}
else
this.Title += " ( Первый раз запускать с правами админа )";
I am rendering a SSRS ServerReport to PDF and in the ReportViewer WebForm Control in a ASP.NET 3.5 Application with a SQL Server Report Service 2008.
Some people using Internet Explorer 11 reported that they cannot open generated PDF files or see anything in the viewer.
The rendering fails with this error:
library!ReportServer_0-403!7c8!01/02/2014-11:07:37:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException: , Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException: Interner Fehler beim Berichtsserver. Weitere Informationen finden Sie im Fehlerprotokoll. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: String
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Web.Configuration.HttpCapabilitiesBase.get_MajorVersion()
at Microsoft.ReportingServices.Diagnostics.Utilities.BrowserDetectionUtility.GetBrowserInfoFromRequest(HttpRequest request)
at Microsoft.ReportingServices.Diagnostics.RSRequestParameters.SetBrowserCapabilities(HttpRequest request)
at Microsoft.ReportingServices.Library.RenderReportAction.SetBrowserCapabilities()
at Microsoft.ReportingServices.Library.RenderReportAction.PerformExecution()
at Microsoft.ReportingServices.Library.RenderReportAction.Render()
--- End of inner exception stack trace ---;
I could track these errors down to a OEM string used in the UserAgent of IE11.
Examples:
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MALC; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MATM; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; NP06; rv:11.0) like Gecko
MALC, MATM and NP06 appear to be OEM strings and are not part of the usual IE11 UserAgent.
Removing these strings in IEs developer tools user agent settings makes everything work normally, but is not a solution for the end user.
Things I have tried:
Overriding the UserAgent of the incoming Request in the ASP.NET application, but it appeared to never change regardless what I was setting. (I might have done this wrong, all I found was that I cannot change it so I tried anyway)
Override the header at the Begin-/EndRequest event in the Global.asax
Adding a custom .browser file in the App_Browser directory of the application itself and on the SSRS Server Application
What does work:
Intercepting the request and making a custom Request using HttpWebRequest with a different UserAgent, copying cookies (session id) and request/response headers back and forth.
I feel like this is a horrible solution and should not be done like this.
How can I make SSRS not throw an error while parsing IE11s UserAgent?
Is there a way to disable it or add a custom Regular Expression to parse it manually?
You can override the user agent to the report server by supplying additional device information.
This can be done when calling the Render method of the SOAP API by supplying this XML fragment as a parameter
<DeviceInfo>
<UserAgent>custom_user_agent_here</UserAgent>
</DeviceInfo>
Or using URL access like this
http://<Server Name>/reportserver?/SampleReports/Sales Order Detail&rs:Command=Render&rs:Format=HTML4.0&rc:UserAgent=custom_user_agent_here
.
References
Reporting Services Device Information Settings
http://msdn.microsoft.com/en-us/library/ms155397(v=sql.110).aspx
HTML Device Information Settings
http://msdn.microsoft.com/en-us/library/ms155395(v=sql.110).aspx
I have an web application where mobile phone users see a mobile optimized website. The new Samsung Galaxy SIII user agent provides no clue that the request is coming from a mobile phone. What are the best pratices to detect mobile phones?
I'm aware of javascript feature detection (ie. modernizer) but am hoping for something better. Below is the Samsung Galaxy SIII user agent:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
EDIT: The SIII has two possible user agents. Above is the 'desktop' version. Fun stuff. See link below for details.
http://www.anandtech.com/Show/Index/5310?cPage=19&all=False&sort=0&page=5&slug=samsung-galaxy-nexus-ice-cream-sandwich-review
Looking at that user agent, I'd have to say that, that would be extremely difficult to differentiate from a non-handheld device.
The problem with browser detection is that it's obviously easy to tweak the user agent string, and thus you never really know if what the server is telling you is honest or not.
You have two options in this case:
You can check every single header the phone sends and maybe see if there is one that could make it unique
Or find some type of work-around by testing page load time etc..., As a whimsical example, browsers on handheld devices usually render pages a bit slower than their desktop counterparts, so after testing every possible mobile device with something like:
-
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
// some code..
}
You can see if a page with nothing else but a simple script is not loading in it's ideal time.
You get the point.
Also, try going here and see if it can detect you: http://detectmobilebrowsers.com/
The "desktop mode" user agent is designed so that the web server doesn't deliver a mobile/tablet interface when the user has deliberately chosen to have the desktop mode - it is a usability anti-pattern to remove that choice from the user.
If you absolutely *must* override the user's choice, then in JavaScript currently (2013) if all the following are true then it very likely is an Android device:
'ontouchstart' in document.documentElement
navigator.vendor === 'Google Inc.'
/^Linux armv/.test(navigator.platform)
However the above will give false positives and negatives with some less common browser setups e.g. an ARM based ChromeBook with touch, e.g. maybe Chromium running on Linux with an ARM processor (although perhaps that is Linux/ARM), e.g. maybe other browsers Firefox/Opera etc e.g. an Android device that is not touch based like a TV e.g. can Chrome run on Windows RT with an ARM processor? e.g. an Android running on Intel.
I have to detect "desktop view" after all, so similar to robocat's answer this is what I'm using to detect 'desktop view'. It's not perfect but it seems to provide the right balance of avoiding false positives:
if (userAgent.indexOf('X11; Linux x86_64') !== -1
&& 'ontouchstart' in document.documentElement
&& /^Linux armv/.test(navigator.platform)
&& _constructor.isChrome) {
if ((window.outerWidth < 500 && window.outerHeight < 800) || (window.outerWidth < 800 && window.outerHeight < 500)) {
// do stuff.
}
}
Helped me decide what the width / height filter should be
http://mydevice.io/devices/
http://viewportsizes.com/?filter=
I want that the WebBrowser control to use IE9. IE9 is installed on the computer, but the WebBrowser control is still using IE8.
I verified with http://www.whatbrowser.org/en/. I try to make some changes to the registry (found a solution here) but is not working.
I think it is the user agent string that is being passed to the site. It is misidentifying it as IE8 as it might not be meeting the requirements in their logic to match as IE9. I can see the same thing happen on my box as well. You could specify the user agent string to use if you want. Add this to your project
In your using statements add ...
using System.Runtime.InteropServices;
Within your form class add ....
[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);
const int URLMON_OPTION_USERAGENT = 0x10000001;
public void ChangeUserAgent(String Agent)
{
UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, Agent, Agent.Length, 0);
}
Then just call it somewhere in your code ... maybe the constructor, or the form_load event.
ChangeUserAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
Browsers lie about their "user agent" to give web sites a break. You're running 9, you cannot have 8 and 9 installed at the same time unless you used the beta version. See this blog post for details about the user agent string.
If you want to make sure then look at the DLL version that gets loaded. Project + Properties, Debug, tick "Unmanaged code debugging". Start your program, Debug + Break All. Debug + Windows + Modules and locate ieframe.dll in the list. The version number column should tell you. I'm getting "8.00.7600.16385 (win7_rtm.090713-1255)", the Win7 release version. I don't have IE9 installed yet.
Use this in the HTML head:
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
Otherwise:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION\yourexename.exe - REG_DWORD = 9000
(decimal)
You can try to add registry value that informs your WebBrowser control witch version of IE you would like to run for your application.
I had similar problem - more here
It seems it might be your page detection script. Try this site (http://www.whatismybrowser.com/). I know other sites gave me the wrong information, but this site correctly identified the browser as the version of IE that was installed on my machine.
When I access the page with the browser (ie9), the browser is rendering ok.
When I use the WebBrowser control I have JavaScript errors.
I know I can suppress the scripts errors, but I want them to run correctly, because they affect the rendering and the functionality of the page.
How can I solve this problem ? Can I integrate IE9 directly in the Windows Form and use similar methods like with the WebBrowser control (navigate,get id, invoke click) ?
Thanks.
What I would do is assign an object to webbrowser.ObjectForScripting and then inject a javascript function that assigns windown.onerror to a wrapper that calls the external script in the host app. Like:
window.onerror = function(message, url, lineNumber)
{
window.external.errorHandler(message, url, lineNumber);
}
Refere to:
http://notions.okuda.ca/2009/06/11/calling-javascript-in-a-webbrowser-control-from-c/
If you have IE9 installed, the WebBrowser will still use IE7 mode unless you override this behaviour with a registry setting - as described in this StackOverflow answer. This is the most likely cause of the JavaScript errors you're getting in the WebBrowser (because you're not seeing the same errors in IE9).
You can make the registry setting using the following c# code (which sets IE10 mode if Windows 8 is detected) and changing app-name.exe to match your own application. You should add an error handler for the case where there are insufficient privileges (admin privileges are required to write to this registry key).
string installkey = #"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
string entryLabel = "app-name.exe";
System.OperatingSystem osInfo = System.Environment.OSVersion;
string version = osInfo.Version.Major.ToString() + '.' + osInfo.Version.Minor.ToString();
uint editFlag = (uint)((version == "6.2") ? 0x2710 : 0x2328); // 6.2 = Windows 8 and therefore IE10
RegistryKey existingSubKey = Registry.LocalMachine.OpenSubKey(installkey, false); // readonly key
if (existingSubKey.GetValue(entryLabel) == null)
{
existingSubKey = Registry.LocalMachine.OpenSubKey(installkey, true); // writable key
existingSubKey.SetValue(entryLabel, unchecked((int)editFlag), RegistryValueKind.DWord);
}
You can use the following code line to get rid of those types of errors:
webBrowser1.ScriptErrorsSuppressed = true;
It will prevent getting JavaScript errors.
So i know the post is old, but it was a recent problem for me and i had to do some serious digging and thinking outside the box.
basically like most replies here - you cannot alter the webbrowser control to use the most recent IE engine. mine uses IE7 by default, i have seen some replies that basically changes/ adds stuff to registry, am always not comfy when it comes to the registry, a cleaner way to address this issue would be to append code on your website that forces it to use the most current IE engine on any pc and works like a charm.
if you have access to the web.config file of the page you intend to browse, simple append:
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="X-UA-Compatible" value="IE=edge" />
</customHeaders>
</httpProtocol>
</system.webServer>
and your site would force webbrowser control to run the most current IE engine on your computer. Other options are found here:
https://www.leapinggorilla.com/Blog/Read/1016/ie-ate-my-css---disabling-compatability-mode
I should state that this would only work if you have access to the page / web.config of the website/ application you are trying to access- which was my case.
THe WebBrowser control uses IE7. So if there is a problem then your script does not work for IE7 and you will have to fix that.
You cannot integrate IE9 as it depends on it being installed on the computer and not everyone has IE9 installed.
As a help to whoever else may have this problem, I tried all these things and nothing worked for me. Here's what does work. I am not sure exactly what causes this error, but apparently when you just press "F5" in VS to debug your app, it runs YourProject.vshost.exe as the process name. If you run the same app from the command line, it will show up as YourProject.exe, and the javascript errors vanish. I think IE sees the app running visa via VSHOST and decides this is fishy and disables javascript from loading correctly.
So... go into your project setting for your executable.
Select "Debug" options.
Select "Start External Program".
Browse to and select Debug\YourProgram.exe (NOT YourProgram.vshost.exe).
Save, recompile, and hit F5.
Everything should work as per usual now, and Visual Studio even attaches to the process for you automatically.
Enjoy!
Grego