【问题标题】:Error when calling a .net dll from Com Visible dll using javascript使用 javascript 从 Com Visible dll 调用 .net dll 时出错
【发布时间】:2010-01-04 16:45:43
【问题描述】:

我正在开发一个 Windows 7 小工具。我正在创建一个 activex 对象并加载程序集。我正在遵循codeproject (GadgetInterop) 中提到的方法。该小工具的任务之一是与 Facebook 交互。

这就是我引用的方式: Javascript 创建一个 GadgetBuilder 对象。 从这里我加载我的图书馆。说“MyLibrary.dll”。

  • 当我调用 MyLibrary.GetCount() 方法时,(只返回一些整数)它可以工作。
  • 但是当我在方法中调用一些 facebook 函数说 MyLibrary.GetFaceBookFeeds() 时会引发错误。我从 CodePlex 引用“facebook.dll”

如果我从 ASP.NET 表单测试我的代码,它会完美运行。但是,当我通过尝试使用 javascript 加载它从我的 html 页面运行它时,我收到以下错误:

无法加载文件或程序集 'facebook, Version=2.1.3654.38113, Culture=neutral, PublicKeyToken=null' 或其依赖项之一。系统找不到指定的文件。

我确认 dll 与“MyLibrary.dll”位于同一文件夹中。

  1. 为什么会出现这个错误?
  2. 我该如何完成我的任务? (我需要使用从 javascript 调用 dll,因为我们在 dll 中做很多其他事情)。

【问题讨论】:

  • 不寒而栗。我们还在做浏览器activex吗?
  • 是的,我在小工具中使用了 bowser activex(我猜他们在小工具中使用的是 ie6 环境)
  • @Marc Gravell:这是一个由 IE 引擎托管的 Windows 桌面小工具。这里不存在跨浏览器兼容性问题,因为该小工具不会由任何其他浏览器运行。

标签: c# .net javascript activex windows-desktop-gadgets


【解决方案1】:

您不必在桌面小工具中为 .net 代码使用基于反射的程序集加载器,您可以使用类 ID 等将程序集编写为 com 可见的。This article 提供了使用 .net 的示例在没有“适配器”的情况下实现您想要做的事情。

话虽如此,您应该注意基于 Activex 的桌面小工具的各种问题:

  • 在小工具中创建 ActiveX 实例时,程序集 dll 将被 sidebar.exe “锁定打开”,并且即使在小工具已关闭后也无法删除该文件。不幸的是,小工具卸载过程没有考虑到这一点,卸载小工具将导致 sidebar.exe 在删除程序集失败时退出文件删除,留下程序集和任何其他未删除的剩余文件删除到那时。也没有显示错误消息。覆盖小工具(例如使用新版本)也是如此 - sidebar.exe 会在安装新的小工具包之前尝试完全删除文件夹,这在大多数情况下会导致安装失败。
  • 注册这种activex 控件可能非常棘手。例如,您提供的 CodeProject 文章中给出的注册表脚本不适用于我的 Windows 7 x64。解决此问题的唯一方法是使用 WMI 写入注册表。
  • 以类似的方式,注销 ActiveX 控件也是一个问题。当用户卸载小工具时,会留下注册表项。我想对很多人来说这不是问题,但想象一下,一个小工具爱好者尝试了他发现的每一个小工具,突然发现许多未使用的注册表项。您可以通过在实例化对象后直接删除注册表项来解决此问题(因为它无论如何都被侧边栏进程缓存)并在下次启动时再次重新注册它。

确实,虽然您可以在不使用反射的情况下执行此操作,但使用反射可能是更好的选择,因为您可以将适配器程序集复制到备用文件夹,使用它来加载当前程序集,然后在小工具关闭或完成时将其卸载使用它。这消除了无法卸载小工具的第一个问题,因为托管程序集位于不同的文件夹中,并且无论如何关闭小工具时都会卸载反映的程序集。

facebook.dll 没有加载的原因是因为您使用的加载程序没有正确解析依赖项(它找不到文件,因为它不知道去哪里查找)。欢迎您试用我们名为 PluginLoader 的基于反射的程序集加载器,看看它是否有效。我们还没有正式发布它,但我们打算让它广泛可用并推荐给所有开发人员使用,以尝试消除 ActiveX 和 Windows 桌面小工具的问题。因为我们还没有正式发布它,所以您必须安装我们的小工具Auction Sidebar Tool,它将安装插件加载器以供使用,代码如下:

var plLoader = new ActiveXObject("Sidebar.PluginLoader");
var myLibrary = plLoader.LoadAssembly(classToLoad, 
                                System.Gadget.path+"\\path\\to\\MyLibrary.dll");
myLibrary.GetFaceBookFeeds();

要加载的类是您需要以 Namespace.Class 格式加载的类(即 MyLibrary.MyClass)。我们专门对其进行了编码以正确解决任何依赖关系,因此它应该适合您。如果它对您有用,欢迎您将它包含在您的小工具中。您只需要 AuctionSidebarTool 文件夹中的 PluginLoader.js 和 PluginLoader.dll 文件,但您需要编辑 PluginLoader.js 文件以删除引用我们程序集的部分(从第 110 行开始)。如果您将其包含在您的项目中,它将检查现有的 PluginLoader.dll,如果失败,它将把它复制到本地 AppData 中的 Windows Sidebar 文件夹,注册它并使用方法 LoadAssembly 提供 AddInLoader 对象和UnloadAssembly。如果您需要任何额外帮助,请在 cmets 中告诉我。

希望对您有所帮助。这可能是迄今为止我在 SO 上写的最长的答案 :)

【讨论】:

  • 嗨,安迪,非常感谢您的详细解释。同意你提出的观点。我还没有检查/使用您的解决方案。会这样做并更新你。感谢您的最佳回复之一。
  • 不用担心,我很高兴它有所帮助。将来当我可以让我的 .net 开发人员在我们的插件加载器上写一篇文章时,我会更新这个答案。
猜你喜欢
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 2012-04-11
  • 2013-09-08
相关资源
最近更新 更多