2009-09-13 22 views
56

Potrzebuję uzyskać informacje o zastosowanych stylach CSS na stronie HTML. Użyłem AxWebBrowser i iterowałem IHTMLDOMNode. Jestem w stanie uzyskać wszystkie potrzebne dane i przenieść kod do mojej aplikacji. Problem polega na tym, że ta część działa wewnątrz działającego w tle i otrzymałem wyjątek podczas próby utworzenia instancji kontrolki.Mieszkanie z pojedynczym gwintem - nie można utworzyć instancji kontrolki ActiveX

AxWebBrowser browser = new AxWebBrowser(); 

ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated 
because the current thread is not in a single-threaded apartment. 

Czy istnieje sposób rozwiązania tej lub innej opcji niż AxWebBrowser?

Odpowiedz

68

Problem polega na tym, że większość interfejsów API wątków/robotów w tle utworzy wątek w stanie Apartament wielowątkowy. Komunikat o błędzie wskazuje, że kontrola wymaga, aby wątek był pojedynczym mieszkaniem z gwintem.

Możesz obejść to, tworząc sam wątek i określając stan mieszkania STA w wątku.

var t = new Thread(MyThreadStartMethod); 
t.SetApartmentState(ApartmentState.STA); 
t.Start(); 
+1

Dzięki, świetnie, że to działa. Jeszcze jedno pytanie/problem. Klasa, której używam, jest po prostu klasą, a AxWebBrowser wygląda tak, jakby musiał być dodany do this.Controls(). Czy istnieje sposób na podrabianie kontroli? Czy będę musiał od tego oddzielić formularz? –

+0

@ martin.malek Nie ma świetnego sposobu na sfałszowanie tego. Najlepiej jest utworzyć nowy formularz. – JaredPar

+1

Witam, kod powinien być t.SetApartmentState (ApartmentState.STA); –

50

Śmiało i dodać [STAThread] do głównego wejścia aplikacji, oznacza to model COM gwintowania jest jednowątkowy apartament (STA)

przykład:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new WebBrowser()); 
    } 
} 
+0

ładne i szybkie rozwiązanie dla mojej aplikacji konsolowej do pracy – Esen

+0

fajne rozwiązanie! dzięki –

+0

nie działa w frameworku 4.5 - podaje nieprawidłowe argumenty na ostatniej linii –

3

Jeśli użyłeś [STAThread] do głównego wpisu swojej aplikacji i nadal otrzymujesz błąd, który może być potrzebny do wykonania wątku bezpiecznego połączenia do kontroli ... coś jak poniżej. W moim przypadku z tym samym problemem działało poniższe rozwiązanie!

Private void YourFunc(..) 
{ 
    if (this.InvokeRequired) 
    { 
     Invoke(new MethodInvoker(delegate() 
     { 
      // Call your method YourFunc(..); 
     })); 
    } 
    else 
    { 
     /// 
    } 
+0

Co powinieneś tu przywołać? Przeglądarka? W jakim stanie? W moim przypadku przeglądarka znajduje się w oknie dialogowym. – C4u