简体   繁体   English

使用JavaScript从Com Visible dll调用.net dll时出错

[英]Error when calling a .net dll from Com Visible dll using javascript

I am developing a windows 7 gadget.I am creating an activex object and loading the assembly.I am following the methodlogy mentioned here at codeproject (GadgetInterop). 我正在开发Windows 7小工具,正在创建Activex对象并加载程序集。我正在遵循代码项目 (GadgetInterop)此处提到的方法。 One of the tasks of the gadget is to interface with Facebook. 该小工具的任务之一是与Facebook交互。

This is how I am referencing: Javascript creates a GadgetBuilder object. 这就是我的引用方式:Javascript创建了一个GadgetBuilder对象。 From here I load the my library. 从这里加载我的库。 say "MyLibrary.dll". 说“ MyLibrary.dll”。

  • When I call method say MyLibrary.GetCount(), (just return some integer) it works. 当我说MyLibrary.GetCount()方法时(仅返回一些整数),它可以工作。
  • But when I call some facebook function inside the method say MyLibrary.GetFaceBookFeeds() it throws an error.I reference "facebook.dll" from CodePlex 但是,当我在方法内部调用MyLibrary.GetFaceBookFeeds()调用某些Facebook函数时,它将引发错误。我从CodePlex引用了“ facebook.dll”

If I test my code from a ASP.NET form it works perfectly. 如果我从ASP.NET表单测试我的代码,则可以完美运行。 However, When I run it from my html page by trying to load it using javascript, I get the following error: 但是,当我尝试通过使用javascript从html页面运行它时,出现以下错误:

Could not load file or assembly 'facebook, Version=2.1.3654.38113, Culture=neutral, PublicKeyToken=null' or one of its dependencies. 无法加载文件或程序集'facebook,Version = 2.1.3654.38113,Culture = neutral,PublicKeyToken = null'或其依赖项之一。 The system cannot find the file specified. 该系统找不到指定的文件。

I verified that the dll's are in the same folder as "MyLibrary.dll". 我确认dll与“ MyLibrary.dll”位于同一文件夹中。

  1. Why is this error coming? 为什么会出现此错误?
  2. How do I go about achieving my task? 我该如何完成任务? (I need to use calling a dll from javascript as we are doing a lot of other things in the dll). (我需要使用从javascript调用dll的方法,因为我们在dll中做了很多其他事情)。

You're not forced to use a reflection-based assembly loader for .net code in desktop gadgets, you can write the assembly to be com visible, using class ids, etc. This article provides an example of using .net to achieve what you're trying to do without the "adapter". 您无需在桌面小工具中为.net代码使用基于反射的程序集加载器,您可以使用类ID等将程序集编写为com可见。 本文提供了一个使用.net来实现目标的示例正在尝试没有“适配器”的情况。

That being said, there are various problems with activex based desktop gadgets that you should be aware of: 话虽这么说,基于Activex的桌面小工具存在各种问题,您应该注意:

  • When an ActiveX instance is created in the gadget, the assembly dll will be "locked open" by sidebar.exe and the file cannot be deleted, even after the gadget has been closed. 在小工具中创建ActiveX实例时,sidebar.exe将“锁定打开”程序集dll,即使关闭了小工具,也无法删除该文件。 Unfortunately the gadget uninstallation process doesn't account for this and an uninstallation of the gadget will result in sidebar.exe copping out of the file deletion when it fails to delete the assembly, leaving the assembly and any other remaining files that hadn't been deleted up to that point. 不幸的是,小工具的卸载过程无法解决这个问题,小工具的卸载将导致sidebar.exe在无法删除程序集时无法删除文件,从而使程序集和所有其他尚未删除的文件丢失删除到那时。 There's also no error message displayed. 也没有显示错误消息。 The same is true of overwriting a gadget (with a new version, for instance) - sidebar.exe attempts to delete the folder completely before installing the new gadget package, resulting in a failed installation in most cases. 覆盖小工具(例如,使用新版本)的情况也是如此-sidebar.exe尝试在安装新小工具包之前完全删除该文件夹,导致大多数情况下安装失败。
  • The registration of such an activex control can be very tricky. 这种Activex控件的注册可能非常棘手。 The registry script given in the CodeProject article you provided does not work on my Windows 7 x64, for instance. 例如,您提供的CodeProject文章中提供的注册表脚本不适用于Windows 7 x64。 The only way to work around this is to use WMI to write to the registry. 解决此问题的唯一方法是使用WMI写入注册表。
  • In a similar fashion, unregistration of the ActiveX control is also an issue. 同样,取消ActiveX控件的注册也是一个问题。 When the user uninstalls the gadget, the registry entries are left behind. 当用户卸载小工具时,注册表项将被保留。 Not a problem for a lot of people I suppose, but imagine a gadget enthusiast who tries every gadget he finds suddenly discovering the many unused registry entries. 我想对于很多人来说这不是问题,但是想象一下一个小工具爱好者,他会尝试发现的每个小工具突然发现许多未使用的注册表项。 You can get around this by removing the registry entries directly after instantiating the object (since it's cached by the sidebar process anyway) and re-registering it again next startup. 您可以通过在实例化对象后立即删除注册表项来解决此问题(因为它始终由边栏进程缓存),并在下次启动时再次对其进行重新注册。

So really although you can do it without reflection, using reflection can be a better option because you can copy the adapter assembly to an alternative folder, use it to load the current assembly and then unload it when the gadget is closed or finished using it. 因此,实际上,尽管您可以在不进行反射的情况下进行操作,但是使用反射可能是更好的选择,因为您可以将适配器程序集复制到备用文件夹,使用它加载当前程序集,然后在小工具关闭或使用完该组件时将其卸载。 This eliminates the first issue of not being able to uninstall the gadget because the hosting assembly is located in a different folder and the reflected assembly is unloaded when the gadget is closed anyway. 这消除了第一个无法卸载小工具的问题,因为托管程序集位于另一个文件夹中,并且无论如何关闭小工具时,都会卸载反射的程序集。

The reason facebook.dll isn't loading is because the loader you're using doesn't correctly resolve dependencies (it can't find the file because it doesn't know where to look). facebook.dll之所以无法加载,是因为您使用的加载器无法正确解析依赖项(由于找不到位置,因此无法找到文件)。 You're welcome to try our reflection-based assembly loader called PluginLoader and see if that works. 欢迎您尝试我们称为PluginLoader的基于反射的程序集加载器,看看是否可行。 We haven't had an official release for it yet but we were intending to make it widely available and recommended for use by all developers to try and eliminate the problems with ActiveX and Windows Desktop Gadgets. 我们尚未发布它的正式版本,但我们打算使其广泛可用,并建议所有开发人员使用它来尝试消除ActiveX和Windows桌面小工具的问题。 Because we haven't officially released it you'll have to install our gadget, Auction Sidebar Tool which will install the plugin loader ready for use with the following code: 由于我们尚未正式发布它,因此您必须安装我们的小工具“ 拍卖侧边栏工具” ,该工具将安装插件加载程序,以供以下代码使用:

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

Where class to load is the class you need to load in the format Namespace.Class (ie MyLibrary.MyClass ). 要加载的类是需要以Namespace.Class格式(即MyLibrary.MyClass )加载的类。 We specifically coded it to correctly resolve any dependencies so it should work for you just fine. 我们专门对其进行了编码,以正确解决任何依赖关系,因此它应该可以为您正常工作。 If it does work for you, you're welcome to include it with your gadget. 如果它对您有用,则欢迎将其包含在小工具中。 All you need is the PluginLoader.js and PluginLoader.dll files from the AuctionSidebarTool folder, but you'll need to edit the PluginLoader.js file to remove the parts that reference our assembly (line 110 onwards). 您需要做的只是AuctionSidebarTool文件夹中的PluginLoader.js和PluginLoader.dll文件,但是您需要编辑PluginLoader.js文件以删除引用我们装配体的零件(从第110行开始)。 If you include this in your project, it will check for an existing PluginLoader.dll and if it fails, it will copy it to the Windows Sidebar folder in local AppData, register it and provide the AddInLoader object with the methods LoadAssembly and UnloadAssembly . 如果将其包含在项目中,它将检查是否存在现有的PluginLoader.dll,如果失败,则将其复制到本地AppData中的Windows Sidebar文件夹中,进行注册并为AddInLoader对象提供LoadAssemblyUnloadAssembly方法。 If you need any extra help just let me know in the comments. 如果您需要其他帮助,请在评论中告诉我。

Hope that helps. 希望能有所帮助。 That's probably the longest answer I've written so far on SO :) 到目前为止,这可能是我写的最长的答案:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM