Как создать элемент управления ActiveX в C #? - PullRequest
5 голосов
/ 10 октября 2011

Я не могу создать работающий элемент управления ActiveX в C #;Я попробовал следующие уроки, чтобы сделать это безуспешно.

Я создаю пример проекта библиотеки классов, который включает этот код:

namespace AACWCSurvey
{
    [ProgId("Prisoner.PrisonerControl")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class Class1
    {
        public Class1()
        {
            MessageBox.Show("FIRETRUCK!!!");
        }
    }
}

Затем я сделал следующие шаги:

Свойства => Приложение => Информация о сборке => Сделать сборку видимой для COM Build => Регистрация для COM-взаимодействия TRUE (проверено) Создать строгое имя для сборки (подпись) Построить проект

regasm MyDll.dll /tlb /codebase

Не вижу Prisoner.PrisonerControl в tstcon32 = (

Моя ОС - WinXP x86.


UPD: работает из VBScript:

Dim objJava
Set objJava = WScript.CreateObject("Prisoner.PrisonerControl")

, но не видна в tstcon32.

Ответы [ 3 ]

2 голосов
/ 10 октября 2011

Вы создали сервер COM, но не элемент управления ActiveX, который является гораздо более сложным объектом COM, который вы можете использовать с tstcon32.exe

Он должен реализовывать несколько интерфейсов, ключевыми из которых являются IOleObject и IOleWindow. Тип интерфейсов, который позволяет ему выполнять необходимые переговоры с хостом ActiveX и создавать видимое окно. Класс Winforms Control - ваш лучший выбор для его создания.

2 голосов
/ 10 октября 2011

Если вы прочитали фактическую статью с помощью элемента управления Prisoner.PrisonerControl, внутри ключа с вашим GUID элемента управления создается субключ с именем Control.

На моей машине с указателем{9DEA5F06-E324-31A7-837B-D0F3BDE91423} создание ключа

HKEY_CLASSES_ROOT\CLSID\{9DEA5F06-E324-31A7-837B-D0F3BDE91423}\Control

Создание элемента управления появляется в tstcon32.И с или без ActiveX можно использовать для javascript

var x = new ActiveXControl("Prisoner.PrisonerControl");

На самом деле мне пришлось бороться с окнами как на выполнение JavaScript, так и путь реестра, чтобы проверить его в моей системе, потому что это x64машина но это другая история.

0 голосов
/ 21 января 2019

Вот соответствующие шаги , которые документированы внешне . Это суммировано, оставляя некоторые изложения, но не необходимые шаги.

Этот пример также очень похож на статью Использование управляемых элементов управления в качестве элементов управления ActiveX , автор Garry Trinder, 25 ноября 2008 г., и я также включил некоторые заметки из этой статьи.

Предоставление элементов управления Windows Forms в качестве элементов управления ActiveX

В этой статье описывается, как использовать элементы управления Windows Forms. за пределами .NET.

Написание элемента управления

  1. Создайте новый проект элемента управления из Visual Studio - все мои примеры написаны на C #, но VB.NET также можно использовать.

[Здесь статья Гарри предлагает: " Во-первых, создайте управляемый проект usercontrol - либо библиотеку классов Windows Forms, либо проект библиотеки управления. Используйте конструктор usercontrol, чтобы создать свой пользовательский контроль пользователя так, как вы этого хотите (используя любой стандарт вам нравится)."]

  1. Добавить элементы управления и т. Д. В форму, ввести код и т. Д.

  2. Добавьте следующие пункты, используя пункты ...

using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
  1. Атрибут вашего класса, чтобы он получил ProgID. Это не обязательно, так как он будет сгенерирован, но почти всегда лучше Явный.

[ProgId("Prisoner.PrisonerControl")]
[ClassInterface(ClassInterfaceType.AutoDual)]

Это назначает ProgID, а также определяет, что интерфейс должен быть «AutoDual» - это портит интерфейс по умолчанию для Вы из всех публичных, нестатичных членов класса. Если это не так что вы хотите, используйте один из других вариантов.

  1. Обновите свойства проекта, чтобы ваша сборка была зарегистрирована для взаимодействия COM.

Если вы используете VB.NET, вам также нужна сборка со строгим именем. Любопытно, что в C # вы этого не сделаете - и это, кажется, особенность среда, а не особенность компилятора или CLR.

  1. Добавьте следующие два метода в ваш класс.

[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\","") ;

  // Open the CLSID\{guid} key for write access
  RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

  // And create the 'Control' key - this allows it to show up in 
  // the ActiveX control container 
  RegistryKey ctrl = k.CreateSubKey ( "Control" ) ; 
  ctrl.Close ( ) ;

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

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

Функция RegisterClass приписывается ComRegisterFunction - этот статический метод будет вызываться при регистрации сборки на COM Interop. Все, что я здесь делаю, это добавляю ключевое слово «Control» к реестра, а также добавить в запись CodeBase.

CodeBase интересен - не только для элементов управления .NET. Он определяет URL путь к тому, где можно найти код, который может быть сборкой на диск как в этом случае, или удаленная сборка на веб-сервере где-то. Когда среда выполнения пытается создать элемент управления, он будет проверьте этот URL и загрузите элемент управления по мере необходимости. Это очень полезно при тестировании компонентов .NET, как обычное предостережение о проживании в том же каталоге (и т. д.), что и .EXE, не применяется.

[ComUnregisterFunction()]
public static void UnregisterClass ( string key )
{
  StringBuilder sb = new StringBuilder ( key ) ;
  sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

  // Open HKCR\CLSID\{guid} for write access
  RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

  // Delete the 'Control' key, but don't throw an exception if it does not exist
  k.DeleteSubKey ( "Control" , false ) ;

  // Next open up InprocServer32
  RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;

  // And delete the CodeBase key, again not throwing if missing 
  k.DeleteSubKey ( "CodeBase" , false ) ;

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

Вторая функция удалит записи реестра, добавленные, когда (если) класс не зарегистрирован - это всегда хорошее предложение привести в порядок по ходу дела.

Теперь вы готовы скомпилировать и протестировать свой элемент управления.

Дополнительные заметки из блога Гарри:

[The] дополнительные записи реестра: Control, MiscStatus, TypeLib и Version [можно создать] с помощью .REG скрипта, но обычно лучше написать функции, которые будут вызываться при регистрации / отмене регистрации

Он описывает ключи реестра в некоторых деталях:

Control - пустой подраздел. TypeLib сопоставляется с GUID TypeLib (это GUID уровня сборки в assemblyinfo.cs). Version старшие и младшие номера версий из сборки версия. Единственный слегка интересный подраздел - MiscStatus. Это необходимо быть установленным на значение, состоящее из (побитовых) значений в OLEMISC ан задокументировано здесь . Чтобы сделать это перечисление доступным, добавьте ссылка на Microsoft.VisualStudio.OLE.Interop (и подходящий Оператор «using» для пространства имен).

Его последняя нота является предупреждением:

Примечание: кажется, что это работает нормально для Excel (с очень ограниченным тестированием Я сделал), частично работает с PowerPoint, но терпит неудачу с Слово. Возможно, некоторые дополнительные значения OLEMISC могут улучшить это; возможно, есть некоторые сообщения, которые нам нужно перехватить; возможно есть еще несколько интерфейсов, которые мы должны реализовать ... Тот факт, что я только едва заставить его работать очень ограниченным образом должен сказать вам, что это вероятно, это не та техника, которую вы хотите использовать каким-либо серьезным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...