"Object doesn't support property or method fireEvent."
I get this error when I try to invoke a script on a WebBrowser control with the InvokeScript(); method. I'm trying to simulate a click on a link element, and instead I get a MessageBox with this error.
Make sure that the document is fully loaded.
From msdn:
InvokeScript(String) should not be called before the document that
implements it has finished loading. You can detect when a document has
finished loading by handling the LoadCompleted event.
http://msdn.microsoft.com/en-us/library/cc491132.aspx
Based upon the information you provided, we can only make guesses about what's wrong. However, if you're calling a JavaScript function with InvokeScript, you can easily figure out the problem yourself: use script debugger and set a breakpoint in your JavaScript code. Here's how to do that (originally for AOL Browser, but it's also a WebBrowser hosting app, so the same technique should work for your app as well).
Related
I am having a problem but I am not sure where.
I have created a website which uses Angular, this might not be pertinent but then again it might be. Of the many features of this site one of them is the ability to upload a file and then get back a response. The response is a simple amount of JSON. The only browser I have to get this working with at this point in time in IE8. avoiding incoming thrown objects - I have tried everything to change this fact, but it is what it is.
I have gotten the site to mimic AJAX uploads by submitting a form and having the response redirected to an iframe. In fact I am using a module that does most of this for me.
So far all this works better than you would believe in IE8. I know right? Unbelievable!
But… there’s always a but…
I need to get this page working when running in a Webbrowser control in a winforms project. I get as far as uploading the file which happens successfully. My REST service gets it, saves it, and returns the correct response. When debugging I can even see that the response is available. But for some reason the load method for the iframe is never called. The iframe which I have made visible on the page is never populated with the JSON.
Again this works when running in IE but not when in the webbrowser control. I get no errors and have breakpoints and debugger statements everywhere. It’s like the response falls in a crack and is ignored.
Would anyone have any suggestions as to why this is happening? crossing fingers
Sorry for the delay I have been ..., well there is no adjective for how busy I have been.
The answer lied in the module that was chosen to help upload files. It worked for IE 8 straight up, but not when running in the web browser control. The module was dynamically binding an onload event to an iFrame which was also being dynamically create to handle the post back. Anyone that has worked with IE and needed to upload files might know of this method. This worked in IE8 but not in the web browser control. We modified it to add the onload event when the iFrame is created and that fixed the issue.
I know how to inject my own scripts into web pages on load event, but it doesn't always work as expected. Sometimes the page succeeds to run its own scripts before mine and it makes my whole app fail. I try do disable the possibility the page spawns another browser window. I have an app running on my server, when it starts Internet Explorer instances randomly - it soon crashes the whole machine which is a disaster.
I made a script which changes window.open method and it does the trick perfectly - except the case when the page pops up another window BEFORE my code is executed. Is there a way to freeze JS before I finish injecting my script? Maybe is there a way to inject my script in an earlier point, before DocumentCompleted event? But how?
This doesn't directly answer your question about how to do it in the browser - but I'm aware of a similar thing that is done by Avast internet security and it does it using an HTTP proxy.
The idea is to intercept HTML pages as they are received over the wire, and inject your script into the HTML itself; thus there's no way that any other script can execute before it.
Whilst that might sound scary - you can do it using the technology underpinning the very excellent Fiddler HTTP debugger - the FiddlerCore API
I building a C# application with a WebBrowser control in it and and I am trying to figure out a way to get the flash content within the web page to not display as it is sucking up a ton of my CPU and memory. I've been trying to remove the <object> tag within the page (there's only one) by getting it via browser.Document.GetElementsByTagName("object") and setting its outerHtml to an empty string. It returns one element (confirmed by the Count property) but accessing the first element ([0]) gives an index out of range error. I've tried doing it via a foreach loop but nothing happens at all and there are no errors. If I try to retrieve <div> elements instead of <object> elements, the foreach loop runs. Am I doing something wrong here, is there a bug, or is there a better way to remove the flash content? Any help greatly appreciated.
My code:
HtmlElementCollection flashElements = webBrowser.Document.GetElementsByTagName("object");
foreach (HtmlElement element in flashElements)
{
element.OuterHtml = "";
MessageBox.Show("Deleted");
}
By the way, this is being run after the DocumentCompleted event has been fired.
EDIT: I just figured out that while the DocumentCompleted event is being called, it is being called before JavaScript injects the flash content onto the page. I've tried a few "sleeping"-like methods but they all stop the web page from processing too. Any way to wait for more time (5 seconds or so) while the webpage continues to render?
Option 1:
You could use a System.Threading.Timer to try and wait extra time for the dynamically injected Flash. That shouldn't hold up the WebBrowser from running while you wait.
Option 2:
Try something like FiddlerCore (you would add this to your app), privoxy (this would run outside of your app on your local machine) or some other proxy to actually block the Flash (.swf) content from ever getting to your local machine. With FiddlerCore, you would monitor each web request/response and kill the request/response based on the HTTP content type, for instance. This option would incur the CPU/memory hit of proxying the network, but is still likely less than the Flash is using itself.
Why not use inject JavaScript on the page to disable writing the flash before it ever exists? I don't know what flash library the page is using, but it'd be fairly easy to rewrite the main method to do nothing.
e.g.
swfobject.embedSWF = function(){}
I've got a modal dialog created using ModalPopupExtender. There is an UI created in it using Webservices and a JQuery Templates. There is also a hidden ASP.NET button which is called from the javascript using the __doPostback() technique. The javascript hides the modal popup and __doPostback is called on the button (which is inside of the ModalPopupExtender)
I use this technique to pass some parameters are from the javascript. The server-side event handler does some processing and transfers to a page (in some cases, back to itself)
This works fine when the page it transfers to is a different one but if it transfers to the same page, the postback happens over and over again until the stack blows.
How do i stop the postback from re-occurring when I postback to the same page. I guess it doesn't happen the first time around because it posts to a different page and the postback is invalidated.
Code samples are difficult to provide as it's a fairly complicated system and it's difficult to break it apart.
It sounds horrible I know, all I want to do, however, it to call a server side function from javascript with some variables. Is there a better way to do this?
Well, you're posting back, so you have server-side control over your markup. Just stick your javascript that does the repost in a container and in the case that the page posts to itself, hide that container so it's not loaded into the page....
That or you could do client cookies or a querystring param. Both might be wonky.
With out a code sample I can only speculate and hopefully point you in the right direction.
When you transfer to a new page the old page (and therefore the javascript on that page) passes out of scope and therefore does not continue to execute. If, however, the page is reloaded and the condition that invoked the __doPostback continues then you have created the circular reference that causes your problem. Before you invoke __doPostback, but while you are still on the client, you need to clear whatever condition might be causing the chain of events.
If you can not uncover what is invoking your event chain then you might consider that instead of transferring back to the same page transfer to a new page (bounce.aspx) which in turn invokes a response.redirect BACK to the page so that it is not a Postback when it is being reloaded, but a fresh instance of the page. (Yes, this is a kludge, but it might be an effective stop gap...)
Cheers,
CEC
Thanks for the responses. I think i've found the solution.
In the server-side callback I was doing this:
setupPage();
Server.Transfer("mypage.aspx", true);
changing it to this:
setupPage();
Server.Transfer("mypage.aspx");
fixes the problem.
SetupPage() stores all of the data in hidden fields and I assumed that preserving the form state would be necessary so that this resided after the transfer. This doesn't seem to be the case as all of the setup I've done in the page before the transfer seems to still be present.
Odd or perhaps I'm misunderstanding something fundamental about .NET
Edit - Yes, I do misunderstand a lot about .NET. It makes my head hurt sometimes.
Thanks for the help
I'm trying to make a wrapper around last.fm and need to invoke some of the javascript functions in the page. Particularly the ones for Stop, Skip, Ban and Love.
InvokeScript seems to work fine with any script function that is within the page HTML itself, but not with scripts loaded from external script files.
For example, the actual call to the skip function is LFM.Flash.Player.skip(), so I tried the following:
_browser.Document.InvokeScript("LFM.Flash.Player.skip");
But all it does is return null and nothing happens on the page.
I've confirmed that that call at least works as typed using the Chrome inspector and the console. (Haven't figured out if there is a way to invoke arbitrary javascript in IE... any suggestions are appreciated)
Is there some special way that that function must be invoked?
Also, yes, I have tried it with and without the parentheses in the script call... still no luck.
Edit: To be clear, I am doing this in the WinForms Browser Control not in an ASP.NET page.
I had the same problem and that solved it for me:
Make sure there's no error in the console by manually loading the page in an external browser
IE Control seems to be caching the pages/scripts ==> I found that refreshing the page in the actual IE browser also refresh the page in .NET IE Control. You can also clear the cache with the debugging tools. I do this for everychange and it works ...
Hope this helps !
Aren't you missing parenthesis when calling skip? Otherwise this only "references" the function, it doesn't call it.