gpt4 book ai didi

c# - 从 Javascript 调用 C# BHO 方法(仍然不工作)

转载 作者:太空狗 更新时间:2023-10-29 22:01:13 25 4
gpt4 key购买 nike

我关注了this准确回答并阅读并重新阅读所有谷歌调查结果。不幸的是,大多数人都只是复制和粘贴所引用的答案(包括“停止用头撞墙,去庆祝!”)句子,这对我不起作用……所以在工作了半天之后,我真的要开始敲我的头了...

我的简单错误:javascript windows.myExtension 对象是“未定义的”,因此在其上调用 Foo 会引发错误。请参阅下面的完整来源。似乎属性集在 javascript 端不可见。

更多信息:

  • 我使用 Debugger.Launch() 语句来方便地调试我的扩展,断点被击中,所有 BHO 扩展函数都被正确调用和运行。
  • 评论的替代方案(使用 property.SetProperty)也不起作用,出现同样的错误:

    console.log(window.myExtension);//写 'undefined',为什么?

  • 使用 VS 2010、Windows 7 x64、IE 9

请让我帮忙运行这个...提前致谢

简单测试页:

<!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>

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

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)"

最佳答案

我有一个 hack-y 解决方案。它现在对我有用,所以我把它贴在这里。如果我遇到任何问题,我会更新这篇文章。

@Eli Gassert 正确识别了问题。在 SetSite 函数中,我们向 DocumentComplete 事件添加了一个处理程序。所以当我们在 $.ready() 时它不会执行。

所以我所做的是将处理程序添加到 BeforeScriptExecute 事件。这是我的 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;
}

处理程序的签名不同,这里是处理程序的代码。这个还在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;
}

我刚刚粘贴了 DocumentComplete 方法中的代码,并在顶部注释掉了条件。

因此,我能够在 jquery $.ready() 中看到 myprop。这解决了我眼前的问题,我正在继续我的代码。

不用说,我的插件只提供将从 javascript 调用的方法,不需要对文档内容做任何事情。

我还不知道pDispWindow有什么用,不检查它是否为空有什么影响等等。

关于c# - 从 Javascript 调用 C# BHO 方法(仍然不工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15068872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com