• 0

"Function Expected" IE10 Script Error on Disposing of WebBrowser ST


Question

Point of application,

Render Provided html string and print it using Internet Explorer, quickly in the background.

Problem,

WebBrowser control requires to be run in an STA thread stopping this thread (after Disposing the Web Browser) causes an IE script error.

I have a class which starts a WebBrowser Control in an STA thread,

    class RenderHtml : System.Windows.Forms.ApplicationContext
    {
// stuff
        private WebBrowser browser = null;
// more stuff
        public RenderHtml()
        {
            renderThread = new Thread(Run);
            renderThread.SetApartmentState(System.Threading.ApartmentState.STA);
            renderThread.Start();
        }

        private void Run()
        {
// Error Checking Omitted
                    browser = new WebBrowser();
                    browser.DocumentCompleted += HasRendered;
                    browser.ScriptErrorsSuppressed = true;
            Application.Run(this);

Then, I give pipe it Html to load,

        public void RenderNew(string html, AutoResetEvent resultEvent)
        {
// Error Checking Omitted
                    browser.DocumentText = html;
                    browser.Refresh();
// AutoResetEvent Logic Omitted
        }

Then after it finished rendering, I tell it to print to a specific virtual printer.

That all works.

So now, I need to dispose of it.

This is what I have right now

        protected override void Dispose(bool disposing)
        {
            lock (locko)
            {
                if (renderThread != null)
                {
                    renderThread.Abort();
                    renderThread = null;
                    return;
                }
            }
            browser.DocumentCompleted -= HasRendered;
            System.Runtime.InteropServices.Marshal.Release(browser.Handle);
            browser.Dispose();
            base.Dispose(disposing);
        }

        public void Stop()
        {
            resultEvent.Dispose();

            browser.Stop();
            ExitThread();
            Dispose();
        }

The problem is with both renderThread.Abort() and ExitThread() - I have to commit both out not to get an error.

Both of these fail due to the WebBrowser control.

I don't feel like providing a screenshot, so here is the text,

The error comes from IE itself,

Script Error
An error has occurred in the script on this page.
Line: 289
Char: 1
Error: Function Expected
Code: 0
URL: res://ieframe.dll/preview.js

Do you want to continue running scripts on this page?

So, after calling Dispose methods including the WebBrowsers dispose method.

I try to stop the thread. Which gives me this error.

If I did NOT provide any html to render I think (been a long time) there is no Script Error.

But then, it completely kills the point of the application!

Note I do suppress Script Errors - when I created the WebBrowser.

                    browser.ScriptErrorsSuppressed = true;

Also, does anyone know of a way to provide images to the WebBrowser control without going through saving them to disk?

2 answers to this question

Recommended Posts

  • 0

EDIT: Code is Available if you have no f-ing idea what I am talking about.

Now to dispose a WebBrowser,

I can do it from the STA Thread Which runs the Web Browser using Application.run(this).

So I can dispose the WebBrowser when it triggers an even such as a DocumentCompleted event.

Additionally, I can dispose of the Web Browser by using .Invoke(...) method.

Sadly WebBrowser cannot be disposed of from another thread by simply calling the Dispose() method.

I can also set the reference to the STA thread to null as well well as the reference to the WebBrowser

and set the thread to be a background thread.

The issue is, the thread does not terminate.

And to release all memory I have to terminate the damn thread.

Whether before or after dispose, whether from a separate thread or the STA Thread itself (during the DocumentCompleted event)

I get this error.

I guess I am asking is, how am I supposed to properly stop a ApplicationContext with a Web Browser Control properly and dispose of it WITHOUT any errors?

1. Why doesn't the renderThread exit itself (Abort is bad from what I understand)?

2. From where do I Abort the renderThread (STA Thread)? The calling thread (which uses the code)? renderThread itself?

3. Do I abort the thread before or after disposing of the WebBrowser?

4. Is the most proper way to dispose of a WebBrowser from another (calling) thread is to use browser.Invoke(...)?

5. Now there is Exit() ExitThread() renderThread.Abort() ExitThreadCore() - they all give me the same error... where am I supposed to call them to avoid bull?

Also this error may help,

A first chance exception of type 'System.Runtime.InteropServices.InvalidComObjectException' occurred in System.Windows.Forms.dll

Edited by _Alexander
  • 0

Workaround Solution

Even after calling browser.Dispose(),

waiting for the browser.Disposed event handler to finish,

and checking browser.IsDisposed before calling renderThread.Abort()

I still got the dreaded Script Error - An error has occurred in the script on this page Line 289 Char 1 Function Expected Code 0 URL res://ieframe.dll/preview.js

You may also get Script Error - An error has occurred in the script on this page Line 518 Char 1 Error The callee (server [not server application]) is not available and disappeared; all connections are invalid. The call did not execute. Code 0 URL res://ieframe.dll/preview.js

Create Separate Thread Which Waits 1 Second After The WebBrowser is Disposed and the calls renderThread.Abort()

Here is the code for this,

        public void TryDispose()
        {
            //
            // Do not Dispose Twice
            //

            if (_doDispose)
                return;

            _doDispose = true;

            //
            // Dispose Browser
            //

            browser.Invoke(
                new MethodInvoker
                    (
                        () =>
                        {
                            browser.Stop();

                            browser.DocumentCompleted -= HasRendered;
                            browser.Disposed += SetDisposeEvent;

                            if (browser.ActiveXInstance != null)
                                Marshal.ReleaseComObject(browser.ActiveXInstance);
                            if (browser.Handle != null)
                                Marshal.Release(browser.Handle);

                            browser.Dispose();

                        }
                    )
                );

            //
            // Hack Around - Create a Thread which Waits for 1 second before disposing the Web Browser
            //

            var browserDisposeThread = new Thread
                (
                    () =>
                    {
                        disposeEvent.WaitOne(1000);
                        Thread.Sleep(1000); // Wait to Avoid Script Error <:::::::::::::::::::::::
                        if (renderThread.IsAlive)
                        {
                            renderThread.Abort();
                            renderThread = null;
                            browser = null;

                            _applicationThreadReady.Dispose();
                            disposeEvent.Dispose();
                            if (resultEvent != null) resultEvent.Dispose();
                        }
                    }
                );
            browserDisposeThread.Name = "Browser Dispose Thread For " + renderThread.Name;
            browserDisposeThread.IsBackground = true;
            browserDisposeThread.Start();

            Console.WriteLine("TryDispose");
        }

Suggestions, Comments welcome.

Edited by _Alexander
This topic is now closed to further replies.
  • Posts

    • That would have been a so much better UX that what it is right now. I know that after a few moment of trying/failing to recognize you in the dark it goes back to PIN selection. But if the light sensor would detect the dark light, showing the PIN field while continuing for a brief moment to register your face would work better.
    • Oh ! This is why... Like some of you, i used Windows Hello since the Surface Pro 4. It worked really well for so long on many devices and still use it everyday with my desktop and laptop. I couldn't understand why it wasn't working as well as before in the dark. Why is Microsoft (as a company) in its UX decisions so anti-consumer right now ? -_-"
    • Zen Browser 1.13.2b is out.
    • KDE Plasma 6.4 launches, bringing better window management, improved KRunner, and more by David Uzondu It's finally here. After several weeks of development, KDE Plasma 6.4 has been rolled out, delivering a ton of significant refinements across the entire UX, from how you manage windows to how you see notifications. The biggest deal for power users is probably the increased flexibility in window management. Plasma 6.4 now allows you to set a completely different tiling layout for each virtual desktop. You can have a simple 50/50 split screen on one desktop for writing, and on another, have a complex grid with two apps snapped to the sides and two others floating in the middle. On the visual side, the default Breeze Dark theme got a little darker for better contrast, and when a password box pops up, the rest of the screen dims to help you focus. There is also a new Animations page in System Settings, which groups all the purely visual effects in one place so you can find them easily. The file transfer notification now shows a speed graph, giving you a much better idea of how a download is progressing. The system will even pop up a notice if you try talking into a muted microphone, and you can install system updates right from the notification that tells you they are ready. When you are in a full-screen application like a game or watching a movie, Plasma automatically enters a Do Not Disturb mode, holding back notifications until you are done. Plasma 6.3, which was released last February, brought several features, including a "Help" category to the launcher after getting rid of the "Settings" one. Now, Plasma 6.4 gives the application launcher a green New! tag next to recently installed apps to help you find them. KRunner and Spectacle, two of the most powerful utilities in Plasma, also received some serious attention. KRunner now lets you visualize colors just by typing in their hex code or even CSS names like "MintCream" or the ridiculous "PapayaWhip." The tool will then show you what that color looks like and give you its code in other formats. Spectacle, the screenshot tool, has been completely overhauled. Pressing the Print Screen key now immediately puts you in selection mode, letting you grab a region or the whole screen much faster before jumping straight into the annotation tools. Screen recordings made in the WebM format or on screens with fractional scaling have also seen a massive quality boost. The Bluetooth widget is getting smarter with better device recognition and easier pairing (we touched on this last month). People with nice monitors will appreciate the new HDR calibration wizard in the display settings. Plasma can also now handle Extended Dynamic Range and the P010 video format, improving power efficiency with HDR content. Digital artists were not left out either. Configuring the buttons on a stylus is "much more intuitive," and you can easily reset your tablet's calibration if you mess it up. Finally, there is a lot of work under the hood. The System Monitor can now show GPU usage for Intel and AMD hardware on a per-process basis and has a new Sensors page for nerds who want to see raw temperature data. When you drag and drop files on the same disk, you can now set it to always move them instead of asking what to do every time. The browser integration feature now supports the Flatpak versions of Firefox and Chromium-based browsers. All of this is built on top of support for a slew of new Wayland protocols, like "FIFO", "toplevel tag," and more. For more information, you can check out the official announcement post, as well as the full changelog.
    • Zoom Workplace 6.5.0.6118 by Razvan Serea Zoom Workplace for Windows is a reliable video conferencing tool that makes it easy to connect and collaborate. With features like messaging, file sharing, and app integrations, it’s designed to streamline teamwork. You’ll get high-quality audio and video, strong security with end-to-end encryption, and an intuitive interface—all of which help remote teams and businesses stay productive and connected. Zoom Workplace key features: High-Definition Video & Audio: Provides clear, reliable communication for virtual meetings. End-to-End Encryption: Ensures secure communication with strong data protection. Multi-Factor Authentication: Adds an extra layer of security for user accounts. Integration with Productivity Apps: Supports seamless integration with Microsoft Office, Google Workspace, and more. File Sharing: Easily share files during meetings for efficient collaboration. Real-Time Messaging: Enables team chat for ongoing communication. Collaborative Whiteboarding: Allows teams to brainstorm and collaborate visually. Webinar Support: Host large webinars with interactive features. Administrative Controls: Manage user permissions, meeting settings, and security features. Cloud Storage: Automatically stores meetings and files in the cloud for easy access. Cross-Platform Support: Available on Windows, macOS, and mobile devices. Meeting features: Virtual Backgrounds: Customize your background for meetings to maintain privacy or enhance professionalism. Touch Up My Appearance: Automatically smoothens skin tone for a more polished video appearance. Breakout Rooms: Divide meetings into smaller sessions for group discussions or workshops. Live Transcription: Automatically generate real-time captions during meetings for accessibility. Zoom Apps: Integrate third-party applications directly into Zoom for enhanced functionality. Meeting Reactions: Participants can use emojis for quick, non-verbal feedback during meetings. Polling: Conduct live polls during meetings to gather instant feedback from participants. Attention Tracking: Monitors participant attention during meetings to ensure engagement. Closed Captioning: Enable manual or automatic captions for a more inclusive experience. Webinar Replay: Record and share webinars with analytics for audience engagement. Download: Zoom 64-bit | Zoom 32-bit (Free, paid upgrade available) Links: Zoom Website | Zoom ARM64 | Zoom Installers | Release Notes Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • Week One Done
      Rhydderch earned a badge
      Week One Done
    • Experienced
      dismuter went up a rank
      Experienced
    • One Month Later
      mevinyavin earned a badge
      One Month Later
    • Week One Done
      rozermack875 earned a badge
      Week One Done
    • Week One Done
      oneworldtechnologies earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      699
    2. 2
      ATLien_0
      273
    3. 3
      Michael Scrip
      214
    4. 4
      +FloatingFatMan
      186
    5. 5
      Steven P.
      145
  • Tell a friend

    Love Neowin? Tell a friend!