fisadmaster Ответов: 1

Как использовать библиотеку классов C# с webbrowser и rgiesecke.dllexport


Если я попытаюсь создать библиотеку классов C#, которая показывает форму с веб-браузером в ней, выполнение библиотеки покажет ошибку: System.Нарезание резьбы.ThreadStateException: элемент управления ActiveX, и он не позволяет показать форму и приложение заканчивается.

У меня есть консольное приложение, сделанное на C++, которое загружает библиотеку классов C#, которая при запуске должна показывать форму с веб-браузером в ней, но при выполнении кода для отображения формы приложение показывает предыдущую ошибку и готово.

Я считаю, что неуправляемый пакет использует RGiesecke.С атрибутом dllexport несовместима с нормальной темы аппликации

Что я уже пробовал:

Я стараюсь:

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class MainModule
{
    [DllExport(ExportName = "ObjectWebJS", CallingConvention =
    CallingConvention.StdCall)]
    static public int ObjectWebJS(int a, int b)
    {
        LoadForm();
        return 0;
    }
    [STAThread]
    public static void LoadForm()
    {
        ObjectForm form1 = new ObjectForm();
        form1.ShowDialog();
    }
}

KarstenK

Причина в том, что для отображения пользовательского интерфейса исполняющему потоку нужны эти права. Приложение имеет эти права, но не dll.

fisadmaster

Спасибо за комментарий, но вы ошибаетесь, потому что, когда я не использую пакет RGiesecke, библиотека классов C# работает так, как должна, и я могу загрузить ее из консольного приложения на C++ и показать форму с помощью webbrowser.

Я понимаю, что пакет RGiesecke заставляет библиотеку классов C# работать в многопоточном режиме, а это несовместимо с компонентом webbrowser.

1 Ответов

Рейтинг:
8

Richard Deeming

Примените этот атрибут к методу точки входа (the Main() метод в C# и Visual Basic). На другие методы это не влияет.

Ваш вызывающий код находится в потоке MTA. Применение [STAThread] атрибут метода, который он вызывает, не будет иметь никакого эффекта.

Вам нужно проверить состояние квартиры текущего потока и при необходимости раскрутить новый поток STA.
public static void LoadForm()
{
    if (Thread.CurrentThread.ApartmentState == ApartmentState.STA)
    {
        LoadFormCore();
    }
    else
    {
        ThreadStart run = LoadFormCore;
        Thread t = new Thread(run);
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
        t.Join();
    }
}

private static void LoadFormCore()
{
    ObjectForm form1 = new ObjectForm();
    form1.ShowDialog();
}


fisadmaster

Спасибо ваше предложение работает идеально