Как получить COM-сервер для Excel, написанный на VB.NET, установленный и зарегистрированный в списке серверов автоматизации?

Версии

Excel 2007, Windows Vista, VB.NET, Visual Studio 2008 с пакетом .NET 3.5 sp2, MSI.

То, что я пытаюсь сделать

У меня есть Excel UDF, который написан на VB.NET. Он отображается как COM-сервер, потому что вы не можете напрямую создавать Excel UDF на языках .NET. Установка – настоящая боль, потому что ни один из настроек установки, похоже, не совсем прав; ни один из них не дает вам установочный пакет, который помещает COM-сервер на клиентскую машину с зарегистрированным сервером, зарегистрированной библиотекой типов и компонентом, видимым в списке серверов автоматизации Excel 2007.

Что я пробовал

Ниже приведены настройки установки для библиотек типов с их дефектами, очевидными во время компиляции и установки:

vsdrfComSelfReg

  • нет предупреждения во время компиляции проекта установки
  • Не удалось зарегистрировать модуль xxx.tlb. HRESULT -2147024703
  • Компонент ProgID и GUID устанавливаются в реестре, но компонент не отображается в списке серверов автоматизации

vsdrfDoNotregister

  • предупреждение при компиляции
  • монтажные работы, но, конечно, TLB не зарегистрирован

vsdrfCOM

  • Предупреждение о компиляции: ПРЕДУПРЕЖДЕНИЕ. Невозможно создать регистрационную информацию для файла с именем ‘xxx.tlb’
  • библиотека типов не регистрируется во время установки

Правильная настройка должна быть vsdrfCOM, как описано здесь :

В. Кто-нибудь может рассказать, что означает vsdrfCOM в проекте установки Visual Studio? Он доступен, когда я проверяю свойство «Регистрация» среди свойств добавленных файлов в проекте установки.

О. Это означает, что Visual Studio будет извлекать данные регистрации COM во время сборки и помещать их в файл MSI (в основном таблицу реестра файла MSI, а также таблицу classов). Поэтому, когда вы устанавливаете его, ваш код не нужно самостоятельно регистрировать, потому что файл копируется на диск и записи реестра создаются. Он также создаст регистрацию библиотеки типов, добавив запись в таблицу TypeLib MSI.

Многие из трудностей кажутся специфичными для Vista. В частности, использование утилиты REGCAP для создания файла .REG из файла .TLB не работает в Vista. Если бы не это, возможно, этот совет был бы полезен . Вместо этого он создает пустые .REG-файлы, когда он вообще работает.

Я пробовал все советы в этой статье StackOverflow . У этого сообщения есть довольно хорошее описание технической проблемы:

Записи в диалоговом окне «Ссылки» взяты из раздела реестра HKCR \ TypeLib, а не из HKCR \ CLSID. Если ваша assembly не отображается в диалоговом окне «Ссылки», но скомпилированные библиотеки DLL все еще могут использовать вашу сборку COM, это означает, что classы и интерфейсы были правильно зарегистрированы для вашей сборки, но сама библиотека типов не была.

Вопрос

У кого-нибудь есть идея, как сделать установку зарегистрировать компонент и библиотеку типов? У меня нет доступа к машине с Windows XP.


Основываясь на том, почему это отстойно

Для компиляции кода для этого не требуется .TLB. Я не пробовал развертывать надстройку Excel Automation, как вы это делаете, но я предполагаю, что UDF должны загружаться и работать нормально.

В Excel это не совсем так.

  • Пользователь открывает рабочий лист и пытается ссылаться на UDF. Он не найден, потому что DLL не загружается. ПОТЕРПЕТЬ НЕУДАЧУ
  • Пользователь переходит в «Главная | Параметры Excel»> «Надстройки» Excel надстройки + Go, а COM-сервер не указан в диалоговом окне «Надстройки». ПОТЕРПЕТЬ НЕУДАЧУ
  • Затем пользователь нажимает на Automation Servers для получения списка доступных серверов автоматизации. DLL не существует. ПОТЕРПЕТЬ НЕУДАЧУ
  • Пользователь возвращается к диалоговому окну надстройки и выбирает «Обзор», переходит в каталог установки и выбирает либо DLL («XXX не является допустимой надстройкой»), либо библиотеку типов («Выбранный файл не содержит новый Automation Server, или у вас недостаточно прав … »). ПОТЕРПЕТЬ НЕУДАЧУ

Насколько я могу судить, пользователь должен запустить regasm.exe из командной строки, чтобы получить доступ к серверу Excel UDF / COM. Как вы относитесь к тому, чтобы рассказывать людям, чтобы запустить regasm из командной строки, чтобы установить надстройку в Excel?


Изменить 2009-10-04

Замечания и указания Майка выглядят потрясающе. Ключевая вещь, которую я не знал, это то, что программа установки имеет встроенный редактор реестра для добавления разделов реестра . О, и что установка с атрибутом ComRegisterFunctionAttribute не вызывается установщиком Microsoft . У меня уже были указания о написании функций установщика из источников, которые он привел.

One Solution collect form web for “Как получить COM-сервер для Excel, написанный на VB.NET, установленный и зарегистрированный в списке серверов автоматизации?”

Я сделал попытку развернуть надстройку автоматизации в выходные дни. Оказывается, это чрезвычайно сложно (не удивительно!), И я не мог найти абсолютно никаких источников в Интернете о том, как это сделать должным образом. Никто.

Есть источники, которые описывают, как использовать RegAsm , но никто не может правильно использовать Project Setup для регистрации надстройки автоматизации, которая немного отличается от стандартной надстройки COM.

К счастью, я смог его решить. Вот что я узнал:

Если вы прочитали некоторые статьи о том, как создать и зарегистрировать надстройку автоматизации C #, вы увидите, что вам нужно добавить раздел реестра « Programmable в HKEY\_CLASSES\_ROOT\CLSID\\{GUID} , где {GUID} – это GUID вашего COM-видимого classа.

Обычно это делается путем добавления пары методов, отмеченных атрибутом ComRegisterFunctionAttribute и атрибутом ComUnregisterFunctionAttribute . Хорошим примером этого является статья « Написание пользовательских функций рабочего листа Excel в C # » Габхана Берри:

 // C#: [ComRegisterFunctionAttribute] public static void RegisterFunction(Type type) { Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type)); } [ComUnregisterFunctionAttribute] public static void UnregisterFunction(Type type) { Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type), false); } private static string GetSubKeyName(Type type) { string s = @"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\Programmable"; return s; } 

Переведенный на VB.NET, это позволяет:

 'VB.NET:  _ Public Shared Sub RegisterFunction(ByVal type As Type) Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type)) End Sub  _ Public Shared Sub UnregisterFunction(ByVal type As Type) Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type), false) End Sub Private Shared Function GetSubKeyName(ByVal type As Type) As String Dim s As String = ("CLSID\{" _ + (type.GUID.ToString.ToUpper + "}\Programmable")) Return s End Function 

Метод, отмеченный ComRegisterFunctionAttribute , автоматически RegAsm при регистрации сборки для этого classа. Метод, отмеченный ComUnregisterFunctionAttribute , автоматически RegAsm когда assembly для этого classа незарегистрирована с помощью переключателя /u .

Проблема заключается в том, что ComRegisterFunctionAttribute и ComUnregisterFunctionAttribute полностью игнорируются при установке через проект установки Visual Studio.

Сначала это кажется неожиданным, потому что Visual Studio Setup Project запускает RegAsm с /regfile переключателя /regfile , чтобы сгенерировать файл .REG, содержащий все необходимые ключи реестра. Именно этот файл .REG затем используется, тогда пакет .MSI запускается на клиентском сайте.

От сборки и развертывания сборки .NET COM Фил Уилсон:

Как Visual Studio обрабатывает записи регистрации classа COM? Ну, если вы настроили Fusion Log Viewer (Fuslogvw.exe в .NET 2.0 SDK) для записи сборки, запустите его после сборки вашей установки, и вы заметите, что Regasm.exe на самом деле работает во время сборки вашего . Однако регистрация не выполняется. Что происходит, так это то, что Visual Studio запускает Regasm с параметром /regfile для создания REG-файла, содержащего записи реестра, необходимые для получения информации для шага 1, и этот .reg-файл внутренне импортируется в проект установки. Поэтому, если вы хотите увидеть, какие записи регистрации classов Visual Studio создадут в настройке MSI, вы можете запустить Regasm самостоятельно с параметром /regfile

Однако при запуске RegAsm, используя переключатель /regfile , я заметил, что переключатель Programmable не был включен. Затем я помещаю в мои методы, отмеченные ComRegisterFunctionAttribute и ComUnregisterFunctionAttribute и обнаружил, что оба они вызываются при запуске RegAsm без переключателя /regfile , но не /regfile при запуске с /regfile переключателя /regfile и не вызывают при запуске через. MSI, созданный проектом установки Visual Studio.

Файлы справки для Regasm.exe подтверждают это (выделено мной):

Вы можете использовать параметр /regfile для создания REG-файла, который содержит записи реестра, вместо внесения изменений непосредственно в реестр. Вы можете обновить реестр на компьютере, импортировав файл .reg с помощью редактора реестра (Regedit.exe). Обратите внимание, что файл .reg не содержит обновлений реестра, которые могут быть сделаны пользовательскими функциями регистра.

Таким образом, решение состоит в том, чтобы добавить сам Programmable ключ. Это можно сделать следующим образом:

  1. В рамках проекта установки откройте редактор реестра. Создайте новый ключ с именем CLSID под HKEY_CLASSES_ROOT , щелкнув правой кнопкой мыши по папке HKEY_CLASSES_ROOT , затем выбрав «Создать», а затем «Ключ».
  2. Под ключ CLSID добавьте новый ключ с именем для вашего GUID, включая фигурные скобки.
  3. Под новым ключом GUID, который вы добавили, добавьте ключ с именем Programmable . Вам не нужно вносить какие-либо значения в этот ключ; однако нам необходимо заставить его создать. Поэтому щелкните правой кнопкой мыши по Programmable ключу и выберите «Окно свойств». Затем измените свойство AlwaysCreate на True .

Как только вы это сделаете, вам больше не нужны методы, отмеченные ComRegisterFunctionAttribute и ComUnregisterFunctionAttribute, но я все равно оставил бы их в тех случаях, когда вы начнете через RegAsm, а не через Setup Project.

На этом этапе вы готовы к развертыванию. Создайте свое решение, а затем щелкните правой кнопкой мыши на проекте установки и выберите «Построить». Затем вы можете использовать созданные файлы Setup.exe и .MSI для развертывания на клиентской машине.

Однако следует учитывать, что при добавлении надстройки автоматизации через диалоговое окно надстроек Excel появляется сообщение об ошибке, указывающее, что «Mscoree.dll не может быть найден, вы хотите удалить надстройку? ” или что-то очень похожее. Это сообщение об ошибке может быть проигнорировано, и ваша надстройка будет работать независимо от того, на что вы отвечаете, но это может вызвать тревогу для клиента, устанавливающего надстройку.

Эта ситуация и объяснение того, как ее решить, хорошо описаны в статье « Написание пользовательских функций для Excel в .NET » Эриком Картером.

Проблема в том, что значением по умолчанию для ключа InprocServer32 является просто mscorree.dll , которого достаточно для того, чтобы .NET мог его найти, но заставляет Excel жаловаться. Решение состоит в том, чтобы убедиться, что значение по умолчанию для ключа InprocServer32 включает полный путь к вашему системному каталогу. Например, в 32-битных windowsх он должен читать C:\Windows\system32\mscoree.dll . Однако этот путь должен меняться, в зависимости от системы, на которой он установлен. Поэтому этот путь не должен быть жестко закодирован.

Эрик Картер обрабатывает это, изменяя методы, отмеченные ComRegisterFunctionAttribute и ComUnregisterFunctionAttribute , следующим образом:

 // C#: [ComRegisterFunctionAttribute] public static void RegisterFunction(Type type) { Registry.ClassesRoot.CreateSubKey( GetSubKeyName(type, "Programmable")); RegistryKey key = Registry.ClassesRoot.OpenSubKey( GetSubKeyName(type, "InprocServer32"), true); key.SetValue("", System.Environment.SystemDirectory + @"\mscoree.dll", RegistryValueKind.String); } [ComUnregisterFunctionAttribute] public static void UnregisterFunction(Type type) { Registry.ClassesRoot.DeleteSubKey( GetSubKeyName(type, "Programmable"), false); } private static string GetSubKeyName(Type type, string subKeyName) { System.Text.StringBuilder s = new System.Text.StringBuilder(); s.Append(@"CLSID\{"); s.Append(type.GUID.ToString().ToUpper()); s.Append(@"}\"); s.Append(subKeyName); return s.ToString(); } 

Переведенный на VB.NET, это эквивалентно:

 'VB.NET:  _ Public Shared Sub RegisterFunction(ByVal type As Type) Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable")) Dim key As RegistryKey = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true) key.SetValue("", (System.Environment.SystemDirectory + "\mscoree.dll"), RegistryValueKind.String) End Sub  _ Public Shared Sub UnregisterFunction(ByVal type As Type) Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false) End Sub Private Shared Function GetSubKeyName(ByVal type As Type, ByVal subKeyName As String) As String Dim s As System.Text.StringBuilder = New System.Text.StringBuilder s.Append ("CLSID\{") s.Append(type.GUID.ToString.ToUpper) s.Append ("}\") s.Append (subKeyName) Return s.ToString End Function 

Это работает, но имеет ту же самую точную проблему, когда assembly правильно зарегистрирована при запуске RegAsm на локальном компьютере, но не удается при попытке использовать ее в проекте установки Visual Studio.

Решение, опять же, состоит в том, чтобы добавить наши собственные ключи реестра. Однако на этот раз нам нужно создать значение по умолчанию, которое использует свойство [SystemFolder] , что эквивалентно вызову System.Environment.SystemDirectory используемому в коде Эрика Картера выше.

Для этого добавьте ключ с именем InprocServer32 под ключ CLSID\\{GUID} который мы создали ранее. Затем щелкните правой кнопкой мыши новый ключ InprocServer32 и выберите «Создать», затем «Строковое значение». Результатом будет новое значение с именем New Value #1 , но вы будете в режиме редактирования, что позволит вам переименовать его. Здесь вы хотите удалить все символы, а затем нажать enter . Удалив все символы из имени, вы создаете значение по умолчанию, и значок для значения реестра будет автоматически переименован «(по умолчанию)». Затем щелкните этот значок по умолчанию правой кнопкой мыши и выберите «Окно свойств». В окне свойств установите для свойства Value значение "[SystemFolder]mscoree.dll" (без кавычек).

Затем вы можете щелкнуть правой кнопкой мыши по проекту установки и выбрать «Создать», а затем вы готовы к развертыванию.

Есть только одна последняя вещь, о которой нужно беспокоиться. Если вы устанавливаете Excel 2007 или выше, вышесказанное будет работать на 100%. Однако, если вы устанавливаете Excel 2003 или ниже, вам необходимо включить следующее:

ИСПРАВЛЕНИЕ: надстройки, интеллектуальные документы или смарт-tags, созданные с помощью Microsoft Visual Studio 2005, не запускаются в Office

Подробное объяснение того, как его развернуть, дано здесь .

Если вы не примените это исправление, все будет правильно зарегистрировано, и вы даже можете добавить надстройку автоматизации успешно – все будет хорошо, но ваши функции рабочего листа не сработают, и вы все равно получите #NAME? ошибок в результате. (Но, опять же, вам это не нужно для Excel 2007 и выше.)

Итак, в конце концов, TLB не имеет значения. Во всем моем тестировании я использовал RegAsm без переключателя / TLB и не включал TLB при регистрации через Project Setup. Поэтому у меня не было проблем с этим, но у Vista возникли проблемы при попытке добавить файл TLB в проект установки .

Надеюсь, это поможет, Хью, и, надеюсь, кто-нибудь еще, кто может наткнуться на эту тему в будущем …

Майк

  • Установка старой версии пакета R
  • Что такое ошибка INSTALL_PARSE_FAILED_NO_CERTIFICATES?
  • Visual Studio 2013 - Нет установленных веб-шаблонов Visual Basic / Visual C #
  • Как найти UpgradeCode и ProductCode установленного приложения в Windows 7
  • Как изменить местоположение библиотеки в R?
  • Как установить конкретный JDK в Mac OS X?
  • Какова польза и реальная цель установки программы?
  • Добавление пользовательских prerequsites в проект настройки визуальной студии
  • Различия между utf8 и latin1
  • Ошибка , когда я пытался обновить приложение
  • невозможно загрузить, $ GOPATH не установлен
  • Давайте будем гением компьютера.