2013-02-25 12 views
6

this cevabını tam olarak takip ettim ve tüm google bulgularını okudum ve okudum. Ne yazık ki çoğunlukla bunların hepsi sadece başvurulan cevabın kopyasını ve yapıştırmalarını ('Kafanızı duvara çarpmayı bırak ve kutla!') Dahil olmak üzere ve benim için işe yaramıyor ... Bu yüzden yarım gün çalışıyorum kafamı becermeye başlamak üzereyim…Javascript'ten C# BHO yöntemlerini çağırmak (hala çalışmıyor)

Basit hatam: javascript windows.myExtension nesnesi 'undefined', bu yüzden Foo çağırmak hata veriyor. Aşağıdaki tam kaynağa bakın. Özellik kümesi javascript tarafında görüntülenemez gibi görünüyor.

Bazı daha fazla bilgi:

  • benim uzantısı hata ayıklamak için uygun bir yol Debugger.Launch() deyimini kullanır ve kesme isabet ve tüm BHO uzatma düzgün denilen ve çalışma vardır.
  • yorumlar alternatif (property.SetProperty ile) de aynı hata ile çalışmaz:

    console.log (window.myExtension); // 'undefined' yazıyor, neden?

    <!DOCTYPE html> 
    <html> 
    <head> 
        <script type="text/javascript"> 
        console.log(window.myExtension); // Writes undefined why? It should be an object... 
        var result = window.myExtension.Foo("bar"); // Obviously throws and error if window.myExtension is undefined 
        </script> 
        <title></title> 
    </head> 
    <body> 
    
    </body> 
    </html> 
    
    : VS 2010, Windows 7 x64 kullanma

  • IE 9

beni

basit bir test sayfası önceden bu ... Thx çalışan yardım edelim

BrowserHelperObject.cs

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.Expando; 

using Microsoft.Win32; 

using SHDocVw; 

namespace IEExtensionTest 
{ 
[ComVisible(true)] 
[Guid("DA8EA345-02AE-434E-82E9-448E3DB7629E")] 
[ClassInterface(ClassInterfaceType.None)] 
[ProgId("MyExtension")] 
[ComDefaultInterface(typeof(IExtension))] 
public class BrowserHelperObject : IObjectWithSite, IExtension 
{ 
    private WebBrowser webBrowser; 

    public int Foo(string s) 
    { 
     return 0; 
    } 

    public void OnDocumentComplete(dynamic frame, ref dynamic url) 
    { 
     Debugger.Launch(); 
     dynamic window = webBrowser.Document.parentWindow; 
     var windowEx = (IExpando)window; 
     windowEx.AddProperty("myExtension"); 
     window.myExtension = this; 
     //var property = windowEx.AddProperty("MyExtension"); 
     //property.SetValue(windowEx, this, null); 
    } 


    public static string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects"; 

    [ComRegisterFunction] 
    public static void RegisterBHO(Type type) 
    { 
     RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true); 

     if (registryKey == null) 
      registryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME); 

     string guid = type.GUID.ToString("B"); 
     RegistryKey ourKey = registryKey.OpenSubKey(guid); 

     if (ourKey == null) 
      ourKey = registryKey.CreateSubKey(guid); 

     ourKey.SetValue("Alright", 1); 
     registryKey.Close(); 
     ourKey.Close(); 
    } 

    [ComUnregisterFunction] 
    public static void UnregisterBHO(Type type) 
    { 
     RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true); 
     string guid = type.GUID.ToString("B"); 

     if (registryKey != null) 
      registryKey.DeleteSubKey(guid, false); 
    } 

    public int SetSite(object site) 
    { 

     if (site != null) 
     { 
      webBrowser = (WebBrowser)site; 
      webBrowser.DocumentComplete += OnDocumentComplete; 
     } 
     else 
     { 
      webBrowser.DocumentComplete -= OnDocumentComplete; 
      webBrowser = null; 
     } 

     return 0; 

    } 

    public int GetSite(ref Guid guid, out IntPtr ppvSite) 
    { 
     IntPtr punk = Marshal.GetIUnknownForObject(webBrowser); 
     int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite); 
     Marshal.Release(punk); 

     return hr; 
    } 
} 

IObjectWithSite.cs

using System; 
using System.Runtime.InteropServices; 

namespace IEExtensionTest 
{ 
[ComVisible(true)] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")] 
public interface IObjectWithSite 
{ 
    [PreserveSig] 
    int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site); 

    [PreserveSig] 
    int GetSite(ref Guid guid, out IntPtr ppvSite); 
} 
} 

IExtension.cs

izler (ve düzgün çalışır) olarak Mesaj yapı adım yapılandırıldığı
using System; 
using System.Runtime.InteropServices; 

namespace IEExtensionTest 
{ 
[ComVisible(true)] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")] 
public interface IObjectWithSite 
{ 
    [PreserveSig] 
    int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site); 

    [PreserveSig] 
    int GetSite(ref Guid guid, out IntPtr ppvSite); 
} 
} 

:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)" 
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)" 
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)" 
+1

Sadece bu bir bıçak alarak, ama buna sadece ekler gibi görünüyor 'myExtension Belge tamamlandı. Bu hack testini deneyin: 'setTimeout (function() {console.log (window.myExtension);}, 1000);' 1 saniye sonra konsola bir şey çıkarmalı. Bu noktada, belge yüklenmeli ve cevabınızı almalısınız. Lütfen bu testten sonra tekrar rapor verin. Fikriniz için –

+0

Thx. Çoktan denedim ve şimdi tekrar. Zamanlama problemi değil. window.myExtension, gecikmeli çağrıda hala tanımlanmamış :-( –

+0

@Dalorzo Lütfen gerekli olmayan etiketler eklemek gibi önemsiz düzenlemelerle durun. Geçmişinize göz attım ve en son önerilen düzenlemelerinizin çoğu reddedilmiş olmalıdır. Bu türden önemsiz (ve genellikle yanlış ve/veya eksik) düzenlemeler yaparak eski soruları gereksiz yere çarpar hale getiriyorlardı .. –

cevap

0

pencere ile deneyin. harici .myExtension(); Harici, formunuzu tutan nesneyi hatırladığım kadarıyla. Ayrıca bu işe yaramazsa - önce basit şeyleri denediğinizden emin olun ve tersine çalışın.

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")] // Note full trust. 
[System.Runtime.InteropServices.ComVisibleAttribute(true)] 
public partial class BasicJSScriptableForm : Form 
{ 
    private void BasicJSScriptableForm _Load(object sender, EventArgs e){ 
    this.WebBrowser1.Navigate("yourpage"); 
    } 
    public string TestMethod(string input){ 
    return string.Format("echo: {0}", input); 
    } 
} 

Ardından sayfasında:

$(document).ready(function() { 
    alert(window.external.TestMethod("It will hopefully work.")); 
} 
0

Bunun için kesmek-y çözüm

İşte sizin için çalışmalı basit formudur. Şu an benim için çalışıyor, bu yüzden buraya gönderiyorum. Bununla ilgili herhangi bir sorunla karşılaşırsam, bu gönderiyi güncellerim.

@Eli Gassert sorunu doğru bir şekilde tanımlar. SetSite işlevinde, DocumentComplete olayına bir işleyici ekliyoruz. Yani, $.ready()’da olduğumuzda idam edilmeyecekti.

Yaptığım şey, BeforeScriptExecute olayına işleyici eklemek. Bu benim BHO.cs

public int SetSite(object site) 
    { 
     this.site = site; 
     if(site != null) 
     { 
      webBrowser = (IWebBrowser2)site; 
      ((DWebBrowserEvents2_Event)webBrowser).BeforeScriptExecute += S2_BeforeScriptExecute; 
      //((DWebBrowserEvents2_Event)webBrowser).DocumentComplete += S2_DocumentComplete; 
     } 
     else 
     { 
      ((DWebBrowserEvents2_Event)webBrowser).BeforeScriptExecute -= S2_BeforeScriptExecute; 
      //((DWebBrowserEvents2_Event)webBrowser).DocumentComplete -= S2_DocumentComplete; 
      webBrowser = null; 
     } 
     return 0; 
    } 

işleyicisi için imza farklıdır ve burada işleyici kodudur ilgili kısmıdır. Bu sadece DocumentComplete yönteminden kod yapıştırılan ve üstündeki durumunu dışarı yorumladı BHO.cs

private void S2_BeforeScriptExecute(object pDispWindow) 
    { 
     //if (pDisp != this.site) { return; } 

     dynamic window = webBrowser.Document.parentWindow; 
     IExpando windowEx = (IExpando)window; 
     windowEx.AddProperty("myprop"); 
     window.myprop = this; 
    } 

hala. Sonuç olarak, myprop jquery $.ready() numaralı belgede görebildiğim görülebilir. Bu benim acil sorunumu çözdü ve ben kodumla ilerliyorum.

Eklentim, yalnızca javascript'ten çağrılacak ve belge içeriği ile ilgili herhangi bir şey yapması gerekmeyen yöntemleri sağlamaktır.

Henüz pDispWindow için kullanılmasıdır ve boş olup olmadığını kontrol etmiyor etkisi nedir bilmiyorum

vb

İlgili konular