2012-02-15 22 views
10

Próbuję dowiedzieć się, jak wywołać metody C# w moim obiekcie BHO z JavaScript na stronie. Znalazłem wiele stron na temat, jak to zrobić w C++/ATL/COM, takich jak:Wywołanie metod C# BHO z Javascript

Browser Helper Objects and Scripts Options

Calling BHO method from Javascript?

starałem się podążać i wdrożyć go prawidłowo w C#, ale nie mogę zmusić go do działania prawdopodobnie ze względu na pewne oczywiste problemy z COM, które mam, których nie w pełni rozumiem.

Używam C# 4.0.

Oto odpowiednie fragmenty kodu:

using SHDocVw; 
using mshtml; 
using System.Runtime.InteropServices; 

[ComVisible(true), 
Guid("300736C4-DCDA-4DB0-90AD-4510A12EBBC6"), 
ClassInterface(ClassInterfaceType.None), 
ProgId("My Extension")] 
public class BrowserHelperObject : IObjectWithSite 
{ 
    const int DISPATCH_PROPERTYPUT = 4; 
    const int FDEX_NAME_ENSURE = 2; 
    const uint LOCALE_USER_DEFAULT = 0x0400; 

    WebBrowser browser; 

    ... 
    public void OnDocumentComplete(dynamic frame, ref dynamic url) 
    { 
     ... 
     var window = browser.Document.parentWindow; 

     int pid = 0; 
     window.GetDispId("myExtension", FDEX_NAME_ENSURE, ref pid); 

     System.Runtime.InteropServices.ComTypes.DISPPARAMS dispParms = new System.Runtime.InteropServices.ComTypes.DISPPARAMS(); 
     dispParms.cArgs = 1; 
     dispParms.cNamedArgs = 0; 
     dispParms.rgvarg = ???; 
     dispParms.rgdispidNamedArgs = IntPtr.Zero; 
     System.Runtime.InteropServices.ComTypes.EXCEPINFO einfo = new System.Runtime.InteropServices.ComTypes.EXCEPINFO(); 
     window.Invoke(pid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ref dispParms, this, ref einfo);    
     ... 
    } 

Odpowiedz

21

Nienawidzę odpowiedzieć na moje własne pytanie, ale naprawdę czuję się jak społeczność powinna znać odpowiedź, ponieważ jest krótki, prosty i piękny z C# 4.0 i SO wiele osób wydaje się mieć ten problem.

Upewnij się, że prawidłowo wystawiać Browser Helper Object:

[ComVisible(true), 
Guid("DA8EA345-02AE-434E-82E9-448E3DB7629E"), 
ClassInterface(ClassInterfaceType.None), ProgId("MyExtension"), 
ComDefaultInterface(typeof(IExtension))] 
public class BrowserHelperObject : IObjectWithSite, IExtension 
{ 
    ... 
    public int Foo(string s) { ... } 
    ... 
    public void OnDocumentComplete(dynamic frame, ref dynamic url) 
    { 
     ... 
     dynamic window = browser.Document.parentWindow; 
     IExpando windowEx = (IExpando)window; 
     windowEx.AddProperty("myExtension"); 
     window.myExtension = this; 
     ... 
    } 
    ... 
} 

i trzeba będzie definicję rozszerzeń:

[ComVisible(true), 
Guid("4C1D2E51-018B-4A7C-8A07-618452573E42"), 
InterfaceType(ComInterfaceType.InterfaceIsDual)] 
public interface IExtension 
{ 
    [DispId(1)] 
    int Foo(string s); 
    ... 
} 

można uzyskać dostęp do Browser Helper Object w javascript w następujący sposób:

var result = window.myExtension.Foo("bar"); 

lub po prostu

var result = myExtension.Foo("bar"); 

To wszystko. Przestań walić głową o ścianę i idź świętować!

+6

Nie żal za odpowiedzi na swoje pytanie .. Bo i) ludzie szukają odpowiedzi, a nie za osobę i odpowiedziałeś, ii) Masz problem z wiadomością i jesteś w stanie na nie odpowiedzieć, to znaczy, że nad tym pracowałeś ... To naprawdę dobra rzecz ... gratulacje .... – Tirumudi

+1

Cześć punkt stały. Czy mógłbyś opublikować działający prototyp? Próbowałem dokładnie to zaszkodzić, a moje okno.myExtension pozostaje "niezdefiniowane" Wysłałem to pytanie z moim pełnym źródłem [tutaj] (http://stackoverflow.com/questions/15068872/calling-c-sharp-bho-methods- from-javascript-still-not-working) –

+0

Dla mnie to nie powiedzie się, gdy tylko załaduję trochę javascript na moją stronę - na stronach bez zewnętrznych odnośników do skryptów wszystko jest w porządku, gdy tylko mam zewnętrzne odwołanie do skryptu, to się nie powiedzie. Również dziwne, gdy zaczyna się nie udać, ciągle kończy się na stronach, na których wcześniej pracował. –

0

Ponadto, po dodaniu właściwość trzeba się upewnić, aby zwolnić Odsyłacze COM okiennych i windowEx