4

我需要远程加载一个包含 ActiveX 对象(非可视)的 .NET DLL,然后使用新的 ActiveXObject() 方法通过 javascript 访问它。

当前 IE8 使用对象标记上代码库属性的路径正确加载此 DLL,但由于 ActiveX 引导程序未在注册表中找到 DLL,ActiveXObject 失败。

我正在使用 ProcMon 来跟踪正在发生的事件,并且可以验证是否正在下载 DLL,以及是否正在通过新的 ActiveXObject 方法探测注册表。第二部分失败了,因为 ActiveX 对象不在注册表中。

<body>
    <object
        name="Hello World"
        classid="clsid:E86A9038-368D-4e8f-B389-FDEF38935B2F"
        codebase="http://localhost/bin/Debug/Test.ActiveX.dll">
    </object>  

    <script type="text/javascript">    
        var hw = new ActiveXObject("Test.ActiveX.HelloWorld");
        alert(hw.greeting());
    </script>    
</body>

如果我使用regasm我可以提供必要的注册然后一切正常,但是我不想为此目的部署安装程序 - 我知道 IE 应该为我注册 DLL - 我只是不知道这是什么机制.

.NET 类具有使这一切在 regasm 中工作的必要属性,但似乎没有调用注册表代码。(注册码是从这里偷的)

namespace Test
{
    [Guid("E86A9038-368D-4e8f-B389-FDEF38935B2F")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [ComVisible(true)]
    public interface IHelloWorld
    {
        [DispId(0)]
        string Greeting();
    }

    [ComVisible(true)]
    [ProgId("Test.ActiveX.HelloWorld")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IHelloWorld))]
    public class HelloWorld : IHelloWorld    
    {
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\ ", ""); // <-- extra space to preserve prettify only.. not in the real code

            // Open the CLSID\{guid} key for write access
            using (RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true))
            {
                // And create the 'Control' key - this allows it to show up in 
                // the ActiveX control container 
                using (RegistryKey ctrl = k.CreateSubKey("Control"))
                {
                    ctrl.Close();
                }

                // Next create the CodeBase entry - needed if not string named and GACced.
                using (RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true))
                {
                    inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
                    inprocServer32.Close();
                }

                // Finally close the main key
                k.Close();
            }
        }

        ...

        public string Greeting()
        {
            return "Hello World from ActiveX";
        }
    }
}
4

1 回答 1

2

这个问题的简单答案是你不能;IE 不会加载它不知道的 activex 控件。

您可以做的是找到一种方法来安装 DLL(从而注册 ActiveX 控件),然后在安装后加载它。在本机上,如果没有用户的任何提示,这是不可能“自动”完成的,可能是因为这将是一个噩梦般的安全漏洞。

现在,如果您只是在寻找 ActiveX 控件的“本机”安装方法,那将是您指定的 CAB 文件。它不会“自动”为您完成所有工作,但它可用于让 IE 提示用户安装 ActiveX 控件,这将导致您的安装程序运行。

您可以在http://msdn.microsoft.com/en-us/library/aa751974(v=vs.85).aspx找到有关如何使用此方法的信息

在 C# 中做你想做的事情可能不是一个非常灵活的方法。它只有在用户安装了 .net 时才有效,而且我从未尝试使用 CAB 文件安装 .net ActiveX 控件。我建议您考虑使用常规浏览器插件或 C++ ActiveX 控件。您可以查看FireBreath以在 C++ 中创建可以用作 ActiveX 控件但也可以在所有其他浏览器上使用的东西。

于 2011-05-23T04:41:06.107 回答