Как я могу развернуть объект ActiveX C # через удаленно загруженную DLL (без предварительной регистрации), используя IE8 / IE9, а затем получить к нему доступ с помощью JavaScript? - PullRequest
4 голосов
/ 25 января 2011

Мне нужно удаленно загрузить .NET DLL, содержащую объект ActiveX (не визуальный), а затем получить к нему доступ через javascript, используя новый метод ActiveXObject ().

В настоящее время IE8 правильно загружает эту DLL с путем из атрибута codebase на теге объекта, но ActiveXObject завершается ошибкой из-за того, что загрузчик ActiveX не находит DLL в реестре.

Я использую 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";
        }
    }
}

1 Ответ

2 голосов
/ 23 мая 2011

Простой ответ на этот вопрос заключается в том, что вы не можете; 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, но также и во всех других браузерах.

...