I'm trying to run an webpage inside a Webbrowser control wich contains a connection to an Websocket. The control can't connect to the Websocket.
When I tested in IE, everything runs ok, but in the Webbrowser control inside Visual Studio, the page can't connect to the Websocket.
I tried other pages that contains script to detect browser support for Websockets, when it runs in IE, the page show that Websocket runs with success, but when I'm try to run the same page on Webbrowser control, the page says that webcontrol can't run. How can I do to solve this problem?
Very thank you.
The problem is that the webbrowser control, while using the local IE as a basis, is more locked down (or maybe better to say "differently configured") by default.
The ability to control this is called Feature Control and you can read about it on MSDN here
In terms of solving your actual problems, a similar question has been solved with code provided in this answer to an equivalent question on C#. Note the tweaks in the subsequent answer as well.
Related
Corodva, Javascript and HTML5 developers.
I need to intercep all get requests made by the WebBrowser component in Windows Phone 8.0 at any point and be able to view the resource that it's requesting. To give an example of "all", this is what I mean.
I have a simple application that contains a cordova(WebBrowser control with Decorators that allows XHRrequests to be retrieved from local storage) view, and navigates to an index.html file.
The index.html contains only the following in the body
<img src="logo.png" />
This file is loaded and displayed by the web browser but there is not interceptable request made through the web browser to the Windows Phone that I can see. The file just appears in the browser magically. I know that cordova overwrites all XHRrequests to swap out for local files. No method in the XHRHelper.cs is being hit with a request for logo.png. Here is everything I have tried just so we can all be on the same page.
Subscribed to the Navigating, Navigated and NavigationFailed (Just because there's no other option) events to see if it fires at any point to load logo.png. This turned out nothing, it only fired for actual navigation calls made within the application. I also subscribed to all, I literally mean all events available from the WebBrowser control. Even ones that are inherited from UIElement.
Tried to wrap the WebBrowser in a COM Wrapper that "monitors" all outgoing traffic using http://www.codeproject.com/Articles/157329/Http-Monitor-for-Webbrowser-Control which does not work for Windows Phone 8.0 Web browser control. Was still a good exercise. It also does not get requests made for local files.
The next option I checked out is a way of intercepting all requests from JavaScript for anything, but found many posts that only explain how to intercept all AJAX requests, which is not what I want to do.
I then implemented the ways of intercepting all AJAX requests to see if it will give some insight on what I could possibly do. Nothing panned out from this exercise. I then also did this [How do you 'intercept' all HTTP requests in an EmberJs app?. Ant that also did not help, I then looked at intercept.js and tried to use that, but again the logo.png slipped the grasp of intercept.js aswell
Me being a Windows Phone .NET developer and not at all experienced in JavaScript except for 6 months of wrapping HTML5 apps into cordova I returned back to the windows phone code trying to catch the navigation as it leaves the WebBrowser control. I tried to override all the methods that were specific to a WebBrowser and tried to cancel any and all requests, just to see if logo.png would still appear in the browser and it did :(
I wouldn't ask this question if I didn't do any research on this subject. Some of the JavaScript devs said that they don't think it's possible from inside the application, many of the C++ developers said I should look at the native code implementation for the WebBrowser control, find out what interfaces it extends and get hold of it for extension somehow. I will be attempting to do this tomorrow all day, but would like to not overkil the situation if there's (hopefully) an easy way of doing this.
My next step is to use a tool like fiddler or charles to monitor all packets through a proxy. If I can see requests made for the local files through any of these tools then there must be a way to intercept those requests in code. If this is successfull I will attempt to set up a local proxy at runtime and redirect through my filehandler.
I spoke to some iOS developers and they used NSURLProtocol, which you just have to set up then you can monitor all you traffic (Lucky). Is there anything like this for Windows Phone 8.0? Does anyone have suggestions on how I could implement this for Windows Phone 8.0? Is there any way I can intercept all requests from a html5 app. Any way would be fine, I'm fairly confident that I'll be able to implement any suggestion and give feedback if it does not work. The biggest question would be if it's even possible.
Any feedback would be appreciated, and any suggestions will be followed through. And I will provide feedback on that suggestion.
Thank you in advance, I know there are some serious Code Ninjas on here that will give me a million options :)
I have found a very simple solution to this problem. Since Mobile IE10 does not provide functionality to intercept requests made by a webpage I moved off that path and chose to not intercept the requests but rather redirect it.
I did this by setting up a socket server on the phone and requesting the assets in the HTML5 application from the localhost. Here's an example:
A file that I used in the index.html like below
<img src="logo.png" />
I changed to
<img src="http://localhost:99/logo.png" />
This way you get a Process request event fired in the socket server where you can handle your asset request appropriately. You can take the logo.png and give back a image with a different name by using a simple mapping in the socket server, which is what I needed to do.
I hope this helps someone dealing with the same problem :)
I've looked through several similar questions on SO but haven't found something quite like what I need, so my question is this:
I want to take a screenshot (thumbnail) of a URL after the user provides one. I was going to use Awesomium because they provide a fairly simple solution for screengrabs. Unfortunately, Awesomium won't compile in an x64 application, and since I'm building this with ASP.NET for Windows Azure, I can't switch to x86.
So I'm left with a less-elegant solution, using Windows.Forms WebBrowser to load the url and take the screenshot (as shown here: http://www.codeproject.com/Articles/95439/Get-ASP-NET-C-2-0-Website-Thumbnail-Screenshot ).
Ugly, I know, but it works with most pages (there is the occasional white screenshot), but now I'm concerned with security.
If the user inputs a malicious URL and the WebBrowser loads it, what is to stop it from running harmful code and downloading a virus to the server where the app is hosted?
There are several services and websites that offer similar functionality, albeit with different approaches, but the core idea is the same: the site must open up the URL and render the page in order to grab the screenshot. So what kind of measures would one expect them to take to thwart viruses and malicious URLs?
The biggest threat to your application would be client script executing in your browser control (i.e. JavaScript and client-side VBScript). It appears it is not possible to disable JavaScript programmatically in the WebBrowser object:
VB.NET WebBrowser disable javascript
Disable javascript in
WinForms WebBrowser control?
Stripping <script> tags in the first question's first answer is not the way to go for security, as there are so many other ways script can get inserted.
Changing window.alert in the second answer won't work as it needs the page to load fully first, and it is possible for script to execute before then. Also, this would only stop the alert function and not prevent script code in any other way.
Changing the registry settings as suggested in this answer may be the way to go, but this appears to be the same as changing Internet Explorer settings to high security for the internet zone (or selecting custom and disabling Active Scripting). If you are always in control of the machine where your app is loaded from, then manually disabling scripting in Internet Explorer options could be a viable solution.
Most client-side internet threats such as drive-by downloads involve script in some way, so this approach will go a long way in protecting your app.
However, there are other exploits such as the Windows Metafile vulnerability that can harm a client machine.
Viewing a website in a web browser that automatically opens WMF files, in which case any potential malicious code may be automatically downloaded and opened. Internet Explorer, the default Web browser for all versions of Microsoft Windows since 1996, does this.
However, making sure your machines are patched with the latest Windows Updates will secure you against threats like these. This will leave zero-day attacks against Internet Explorer or the WebBrowser object, which you will not be able to do much about. I would suggest running your app on an isolated machine (or VM) which would then upload the screenshot to another server (e.g. via the web) which would help mitigate threats in this scenario.
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.
Background:
I am creating a Windows Form App that automates order entry on a intranet Web Application. We have a large amount of order entry that needs to be done that will cost us a lot of money so I volenteered to automate the task.
Problem:
I am using the webbrowser class to navigate the web app. I have gotten very far but reached a road block. There is a part in the app that opens a web dialog page. How do I interact with the web dialog. My instance of the webbrowser class is still with the parent page. I am hoping someone can point me in the right direction.
You've got a number of options. To expand on the answers from others and add a new idea...
Do it using the webbrowser control: This is technically possible by either injecting javascript into the target page as demonstrated here or creating a JavaScript object and using it as a bridge via the webbrowser.objectforscripting property. This is very fragile - something as simple as the website changing an element's Id could break it. You also need to make sure your code doesn't interfere with the functioning of the form (clashing function names, etc...)
Do it using a postback: Monitor the communications between the web browser and the server (I personally prefer Firfox/Firebug but ie/Fiddler or Chrome/F12 are both good too). As long as you can replicate the actions of the browser exactly, the server can't know the difference. The problem here is that browsers are complex and the more secure a form is, the more demanding servers are. This means you may have to fake a login, get cookies, send them back on subsequnt requests, Handle Viewstate data and xss prevention variables. It's possible and it's far more robust than the first option but can be a pain to get working. If it's not a highly secure form,, this is your best bet. More information here
Do it by browser automation: Selenium is probably the best option here (as mentioned by others) but suffers from a similar flaw to the webbrowser control in that it's sensitive to changes on the form itself (But not as mcuh so as the webbrowser control).
Incidentally, if you have Visual Studio Ultimate/Test edition (and some others, not sure which), it includes a suite of testing tools including an excellent engine to automate load testing a website. This is also superb for tracking down what exactly a form does as you can see every step of the emulation.
Hope this helps
You have two choices depending of the level of complexity you need:
Use a HTTP Debugger like Fiddler to find out the POST data you
need to send to each page and mimic it via a HttpWebRequest.
Use a Browser Automation Tool like Selenium and do the job.
NOTE: Your action may be considered as spamming by the website so be ready for IP blocking, CAPTCHA...
You could give Selenium a go: http://seleniumhq.org/
UI automation is a far more intuitive approach to these types of tasks.
i wish to interact with my browser window may be IE great if it works on Firefox too, using C#.
I want to make a software which can fill the entries in a webform automatically. In old times there was gator now is roboform, where it can fill in the values automatically.
I actually have users who are comfortable working on an old windows forms application, so i want to make a solution where they can still enter the data in their windows application and it actually fills in the entries at the web form and acts as if the request had generated from the browser itself.
I know i can merge both the databases, since it is a legacy application re writing the database for windows app is a trouble..
Any suggestion?
WatiN is designed to make testing web applications easy from .NET, and it sounds like it could be handy for what you want to do:
Following is the Hello world example
of web test automation; searching
Google.
[Test] public void
SearchForWatiNOnGoogle() { using (IE
ie = new IE("http://www.google.com"))
{
ie.TextField(Find.ByName("q")).TypeText("WatiN");
ie.Button(Find.ByName("btnG")).Click();
Assert.IsTrue(ie.ContainsText("WatiN"));
} }
WatiN Feature List
Automates all major HTML elements
Find elements by multiple attributes
Supports AJAX website testing
Supports frames (cross domain) and iframes
Supports popup dialogs like alert, confirm, login etc..
Supports HTML dialogs (modal and modeless)
Works with Internet Explorer 6, 7, 8 and FireFox 2 and 3
It's billed as a testing application, but Selenium RC can be used to fill in forms and is fairly easy to setup. You could also check out WatiN. Don't know anything about what security issues you might see though.
You might also want to check out Selenium which is a web application testing framework that you can programmitically interact the web UI.
If you use fiddler you may be able to see what the browser sends back to the server, and so you could write C# code to generate the same kind of HTTP request.
If the interaction is very complex (it often is with modern webapps), you could instead automate the browser, as you suggested.
I've had some success automating IE by using the InternetExplorer.Application object. It basically launches a copy of IE and lets you control it from code. I wrote a script this way a few years ago to search for cheap train ticket reservations for me on the Virgin Trains website.
The problem was that with some IE installs, it would sometimes stop to give security warnings that I couldn't skip automatically. There didn't seem to be a pattern to this.
If your users are simply using the application via a WindForms application, then is there any particular reason why you have to manipulate the user interface of an existing web browser, such as Internet Explorer, rather than just making the necessary HTTP requests yourself in your WinForms application? You can use the WebRequest class by setting the Method property to "POST" and writing the field data to the Stream, which you can get using the httpRequest.GetRequestStream() method.