CoInitialize error when trying to initialize a webview2 component from a DLL

Viewed 23

First off I would just like to mention that I am by no means a C# or a windows developer expert. The following code is kind of a mish-mash I've slap together from examples and tutorials I found on the internet.

The premise of the code is to create a webview2 component in a winform, where the winform is a DLL that gets loaded by a third-party application.

Now, the third-party application loads my DLL and calls this function:

Integrations::ShowForm("Form1");

My winform is a basic C# Windows Forms App using .Net Framework.

My Form1.cs looks as follows:

namespace GuiIntegrations
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            string webview2DllPath = @"C:\TestFolder\runtimes\win-x64\native";
            CoreWebView2Environment.SetLoaderDllFolderPath(webview2DllPath);
            Environment.SetEnvironmentVariable("WEBVIEW2_USER_DATA_FOLDER", @"C:\TestFolder\user-data");
            InitializeComponent();
            _ = InitializeAsync();
        }
    }
}

My Form1.Designer.cs file looks like:

namespace GuiIntegrations
{
    public partial class Form1 : Form
    {
        private System.ComponentModel.IContainer components = null;
        #region Windows Form Designer generated code
        ...
        #endregion

        private Microsoft.Web.WebView2.WinForms.WebView2 webView21;
        
        async Task InitializeAsync()
        {
            try
            {
                string webview2FixedPath = @"C:\TestFolder\Microsoft.WebView2.FixedVersionRuntime.105.0.1343.33.x64";

                var env = await CoreWebView2Environment.CreateAsync(browserExecutableFolder: webview2FixedPath , userDataFolder: @"C:\TestFolder\user-data");

                await webView21.EnsureCoreWebView2Async(env);

                webView21.Source = new Uri("https://www.google.com");
            }
            catch (Exception e)
            {
                // The exception goes into an event-list that can be processed outside the DLL
            }
        }
    }
}

(The excluded #region is just your normal winform generated code). Also in the DLL is a class called Integrations.cs, that looks like this:

namespace GuiIntegrations
{
    public static class Integrations
    {
        private static Form1 form;
        private static Thread formThread;

        [STAThread]
        public static void ShowForm(string formName)
        {
            try
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                Type[] types = assembly.GetTypes();
                foreach (Type type in types)
                {
                    if (type.BaseType == typeof(Form) && type.Name == formName)
                    {
                        object obj_form = type.Assembly.CreateInstance(type.FullName);
                        form = (Form1)obj_form;
                        formThread = new Thread(() => Application.Run(form));
                        formThread.SetApartmentState(ApartmentState.STA);
                        formThread.Start();
                        Thread.Sleep(200);
                    }
                }
            } catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
    }
}

Apologies that its not the most eloquent source, but I kind of did it on the fly.

FYI:

  1. C:\TestFolder\runtimes\win-x64\native is the location for the 'WebView2Loader.dll' DLL of the webview2 component.
  2. my winform DLL location also contains the 3 other webview2 DLLs Microsoft.Web.WebView2.Core.dll, Microsoft.Web.WebView2.WinForms.dll, Microsoft.Web.WebView2.Wpf.dll
  3. C:\TestFolder\Microsoft.WebView2.FixedVersionRuntime.105.0.1343.33.x64 is the extracted location of the fixed runtime for webview2.

The problem occurs when 'CoreWebView2Environment.CreateAsync' is called. As soon as its executed, it throws an exception 'Exception: CoInitialize has not been called. (Exception from HRESULT: 0x800401F0 (CO_E_NOTINITIALIZED)'.

As far as I could determine from the error, its not entering the single-apartment state, which is strange considering that I am setting the thread-state that starts the form as STA.

I've also checked that my component doesn't contain a 'Source' field: ComponentProperties

Any help would be greatly appreciate.

PS. When I compile the program as a Windows Application and run it, the component loads fine and shows the google page.

0 Answers
Related