2012-02-15 23 views
10

Sto cercando di capire come chiamare i metodi C# nel mio oggetto BHO da Javascript all'interno della pagina. Ho trovato molte pagine su come farlo in C++/ATL/Com come ad esempio:Chiamare i metodi C# BHO da Javascript

Browser Helper Objects and Scripts Options

Calling BHO method from Javascript?

ho cercato di seguire e implementare correttamente in C#, ma non posso farlo funzionare probabilmente a causa di alcuni ovvi problemi di COM che ho, che non comprendo appieno.

Sto usando C# 4.0.

Qui ci sono le parti rilevanti del codice:

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);    
     ... 
    } 

risposta

21

odio rispondere alla mia domanda, ma mi sento come la comunità dovrebbe conoscere la risposta, perché è breve, semplice e bella con C# 4.0 e così tante persone sembrano avere questo problema.

Assicurarsi che si espone correttamente il 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; 
     ... 
    } 
    ... 
} 

e avrete bisogno di una definizione per le estensioni:

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

Puoi accedere al tuo Browser Helper Object in javascript in tal modo:

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

o semplicemente

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

Questo è tutto. Smettila di sbattere la testa contro il muro e vai a festeggiare!

+6

Non dispiace per rispondere alla tua domanda .. Perché, i) le persone cercano risposte e non per la persona chi ha risposto, ii) hai un problema pubblicato e sei in grado di rispondere significa che hai lavorato su di esso .. che 'seriamente una buona cosa .. complimenti .... – Tirumudi

+1

Ciao punto fisso. Potresti pubblicare un prototipo funzionante completo? Ho provato esattamente a ripro questa e la mia window.myExtension rimane 'indefinito' Ho postato questa domanda con la mia fonte completa [qui] (http://stackoverflow.com/questions/15068872/calling-c-sharp-bho-methods- da-javascript-ancora-non-funzionante) –

+0

Per me questo fallisce non appena carico qualche javascript nella mia pagina - nelle pagine senza riferimenti di script esterni va bene, non appena ho un riferimento di script esterno fallisce. Anche strano, una volta che inizia a fallire, continua a non riuscire nelle pagine per cui aveva precedentemente funzionato. –

0

Inoltre, dopo aver aggiunto proprietà è necessario fare in modo di rilasciare i riferimenti COM di finestra e windowEx