4

ActiveX オブジェクト (非ビジュアル) を含む .NET DLL をリモートでロードし、新しい ActiveXObject() メソッドを使用して JavaScript 経由でアクセスする必要があります。

現在、IE8 は object タグの codebase 属性からのパスを使用してこの DLL を正しくロードしていますが、ActiveX ブートストラップがレジストリで DLL を見つけられないため、ActiveXObject は失敗しています。

私は ProcMon を使用して発生中のイベントを追跡しており、DLL がダウンロードされていること、およびレジストリが新しい ActiveXObject メソッドによってプローブされていることを確認できます。ただし、ActiveX オブジェクトがレジストリにないため、この 2 番目の部分は失敗します。

<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 コントロールの使用を検討することをお勧めします。ActiveX コントロールとしてだけでなく、他のすべてのブラウザーでも機能するものを C++ で作成するために、 FireBreathを見ることができます。

于 2011-05-23T04:41:06.107 に答える