Поделиться через


активация Registration-Free . компонентыNET-Based: пошаговое руководство

 

Стив Уайт
Поддержка Premier для разработчиков, Microsoft UK

Лесли Мюллер
Глобальные ИТ-исследования & разработки, Кредит Suisse First Boston

Июль 2005 г.

сводка. Пакет SDK для платформы Майкрософт позволяет документировать темы изолированных приложений и параллельных сборок. Тем не менее, не все соответствуют этому разделу с активацией com-компонентов без регистрации. Com без регистрации — это функция платформы, которая очень интересна предприятиям с заблокированными серверами и приложениями, изолированными на общих инфраструктурах. В этой статье рассматривается рабочий пример активации компонента на основе .NET Framework собственными клиентами через COM-взаимодействие. (11 печатных страниц)

Применимо к:
   Microsoft Windows Server 2003
   Microsoft Windows XP с пакетом обновления 2
   Microsoft .NET Framework версии 1.1
   Microsoft Visual Studio .NET 2003
   Microsoft Visual Basic 6.0

Скачайте пример, который сопровождает эту статью, MSDNRegFreeNet.msi.

Содержимое

Знакомство
терминология COM Registration-Free
Запуск примера
Создание сборки .NET в качестве COM-сервера
Создание клиента
активация Registration-Free
Устранение неполадок
Заключение
Дальнейшее чтение

Знакомство

Com без регистрации — это механизм, доступный на платформах Microsoft Windows XP (SP2 для компонентов .NET Framework) и Microsoft Windows Server 2003. Как показано в названии, механизм обеспечивает простое (например, XCOPY) развертывание com-компонентов на компьютере без необходимости регистрировать их.

На целевых платформах один из этапов инициализации процесса и его зависимых модулей заключается в загрузке всех связанных файлов манифеста манифестов, в структуру памяти, называемую контекстом активации . В отсутствие соответствующих записей реестра это контекст активации, предоставляющий сведения о привязке и активации, необходимые среде выполнения COM. Специальный код не требуется на COM-сервере или в клиенте, если вы не решите скрыть использование файлов путем создания контекстов активации самостоятельно с помощью API контекста активации активации.

В этом пошаговом руководстве я создаю простую сборку .NET и использовать ее как зарегистрированную, так и незарегистрированную из собственных клиентов COM, написанных в Visual C++ и Visual Basic 6.0. Вы можете скачать исходный код и примеры и увидеть их в действии сразу или выполнить пошаговые инструкции и создать их самостоятельно.

терминология COM Registration-Free

Любой пользователь, знакомый с технологией .NET, привыкнет к термину сборки означает набор одного или нескольких модулей, развернутых, именованных и версий, с одним модулем, содержащим манифест , определяющий набор. В com без регистрации термины сборки и манифест манифеста используются для идей, которые похожи в концепции, но не идентичны их аналогам .NET.

COM без регистрации использует сборку для обозначения набора одного или нескольких модулей PE (т. е. собственных или управляемых) развернутых, именованных и версий в виде единицы. COM без регистрации использует манифест для ссылки на текстовые файлы с расширением .manifest, содержащим XML, который определяет удостоверение сборки (манифест сборки) вместе с сведениями о привязке и активации его классов или определяет удостоверение приложения (манифест приложения) вместе с одним или несколькими ссылками на удостоверения сборки. Файл манифеста сборки называется для сборки, а файл манифеста приложения называется для приложения.

Термин параллельных сборок (SxS) относится к конфигурации разных версий одного и того же com-компонента с помощью файлов манифеста, чтобы их можно было загружать одновременно различными потоками без необходимости регистрации. SxS включает и слабо синонимен com.

Запуск примера

После скачивания и извлечения примера кода вы найдете папку с именем \deployed. Ниже приведена версия клиентского приложения Visual C++ (client.exe), его манифест (client.exe.manifest), а также версия COM-сервера C# (SideBySide.dll). Используйте client.exe. Ожидаемый результат заключается в том, что client.exe активирует экземпляр SideBySideClass (реализован в SideBySide.dll) и отобразит результат вызова метода version, который должен выглядеть как "1.0.0-C#".

Создание сборки .NET в качестве COM-сервера

Шаг 1

В Visual Studio .NET 2003 создайте новый C# или проект библиотеки классов Visual Basic для .NET и вызовите его SideBySide. Удалите AssemblyInfo. [cs/vb] файл из проекта и реализовать класс следующим образом:

Код C#

using System;
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: Guid("[LIBID_SideBySide]")]

namespace SideBySide
{
   [Guid("[IID_ISideBySideClass]")]
   public interface ISideBySideClass
   {
      string Version();
   }

   [Guid("[CLSID_SideBySideClass]")]
   public class SideBySideClass : ISideBySideClass
   {
      public string Version()
      {
         return "1.0.0-C#";
      }
   }
}

Код Visual Basic .NET

Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices

<Assembly: AssemblyVersion("1.0.0.0")> 
<Assembly: Guid("[LIBID_SideBySide]")>

<Guid("[IID_ISideBySideClass]")> _
Public Interface ISideBySideClass
    Function Version() As String
End Interface

<Guid("[CLSID_SideBySideClass]")> _
Public Class SideBySideClass
    Implements ISideBySideClass
    Function Version() As String Implements ISideBySideClass.Version
        Version = "1.0.0-VB.NET"
    End Function
End Class

Я написал значения GUID, которые будут конкретными для проекта, в виде заполнителей. Вам потребуется использовать средство guidgen guidgen для создания уникальных идентификаторов GUID, которые будут соответствующими значениями, которые будут использоваться при последующем использовании заполнителей.

Шаг 2

Чтобы библиотека типов была создана и зарегистрирована во время сборки, задайте для параметра register for COM Interop параметра true.

Шаг 3

Создайте сборку выпуска и скопируйте SideBySide.dll в \deployed.

Создание клиента

Следующим шагом является создание клиента и для этого пошагового руководства вы можете создать клиент Visual C++ или клиент Visual Basic 6.0.

Шаг 4 (вариант A: Visual C++)

Создайте новый консольного проекта Visual C++ Win32 с именем клиента в папке с братом SideBySide проекта. В мастер еприложений Win32 на вкладке параметров приложения установите флажок Добавить поддержку ATL.

Измените stdafx.h и добавьте следующую строку в верхней части файла сразу после #pragma once:

#define _WIN32_DCOM

Кроме того, в stdafx.h добавьте следующую строку в нижней части файла:

import "[path]\SideBySide.tlb" no_namespace

Здесь [путь] должен быть относительным путем к библиотеке типов, созданной при создании сборки SideBySide. Этот путь обычно зависит от того, выбрали ли вы проект C# или Visual Basic .NET на шаге 1.

Замените содержимое client.cpp следующим кодом:

#include "stdafx.h"
#include <iostream>
using namespace std;

void ErrorDescription(HRESULT hr)
{
    TCHAR* szErrMsg;
    if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
      FORMAT_MESSAGE_FROM_SYSTEM, 
      NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
      (LPTSTR)&szErrMsg, 0, NULL) != 0)
   {
        cout << szErrMsg << endl;
        LocalFree(szErrMsg);
    }
   else
        cout << "Could not find a description for error 0x" 
           << hex << hr << dec << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
   CoInitializeEx(0, COINIT_MULTITHREADED);

   {
      ISideBySideClassPtr ptr;
      HRESULT hr = 
              ptr.CreateInstance(__uuidof(SideBySideClass));
      if (SUCCEEDED(hr))
      {
         cout << ptr->Version() << endl;
      }
      ErrorDescription(hr);

      char c;
      cin >> c;
   }

   CoUninitialize();

   return 0;
}

Создайте сборку выпуска и скопируйте \release\client.exe в \deployed.

Шаг 4 (вариант B: Visual Basic 6.0)

Создайте новый проект Visual Basic 6.0 Standard EXE. В обозревателе проектов выберите узел Project1 и в окнесвойств измените его имя на клиента. Выберите файл | Сохраните проект как и сохраните файл формы и файл проекта в папке с общим значением относительно папки SideBySide проекта. Выбор проекта | Ссылки, установите флажок рядом с SideBySide и нажмите кнопку ОК.

Дважды щелкните основную форму в конструкторе форм и вставьте следующий код в Sub Form_Load():

    Dim obj As New SideBySideClass
    Dim isxs As SideBySide.ISideBySideClass
    Set isxs = obj
    MsgBox isxs.Version()

Выберите файл | Сделайте client.exe... и перейдите в папку \deployed, а затем нажмите кнопку ОК.

Шаг 5

В настоящее время папка \deployed должна содержать только client.exe и SideBySide.dll; и последний будет зарегистрирован в процессе сборки. Чтобы проверить, работает ли сервер и клиент вместе с этими обычными обстоятельствами, запустите \deployed\client.exe и запишите ожидаемые выходные данные "1.0.0-C#" или "1.0.0-VB.NET".

Шаг 6

В этом пошаговом руководстве описывается COM, поэтому теперь необходимо отменить регистрацию сборки SideBySide. В командной строке Visual Studio 2003 перейдите в папку \deployed и выполните команду: regasm /u SideBySide.dll.

Шаг 7

Чтобы узнать, какой эффект имел предыдущий шаг, выполните \deployed\client.exe еще раз, и вы увидите сообщение "Класс не зарегистрирован" или "Ошибка времени выполнения "429": компонент ActiveX не может создать объект". На этом этапе мы разочарованы com-средой выполнения от поиска информации, необходимой в реестре, но мы еще не сделали информацию доступной с помощью альтернативных средств. Мы исправим это в следующих шагах.

активация Registration-Free

Шаг 8

В папке \deployed создайте файл манифеста приложения (текстовый файл) для приложения client.exe и вызовите его client.exe.manifest. Вставьте следующий код в файл:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
   manifestVersion="1.0">
<assemblyIdentity
            type = "win32"
            name = "client"
            version = "1.0.0.0" />
<dependency>
            <dependentAssembly>
                        <assemblyIdentity
                                    type="win32"
                                    name="SideBySide"
                                    version="1.0.0.0" />
            </dependentAssembly>
</dependency>
</assembly>

Шаг 9

В папке проекта SideBySide создайте файл манифеста частной сборки (текстовый файл) и вызовите его SideBySide.manifest. Вставьте следующий код в файл:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
<assemblyIdentity
            type="win32"
            name=" SideBySide"
            version="1.0.0.0" />
<clrClass
            clsid="{[CLSID_SideBySideClass]}"
            progid="SideBySide.SideBySide"
            threadingModel="Both"
            name="SideBySide.SideBySideClass" >
</clrClass>
</assembly>

Следующая задача — внедрить приведенный выше файл манифеста сборки в сборку SideBySide в качестве ресурса Win32. На момент написания этой статьи это обязательно для Windows XP, но не для Windows Server 2003. В Windows Server 2003 можно просто развернуть файл манифеста сборки вместе с сборкой. Однако я призываю вас не зависеть от этого поведения, так как это может измениться в предстоящем пакете обновления Windows Server 2003. Чтобы обеспечить поддержку обеих платформ в будущем, выполните следующие действия и вставьте файл манифеста сборки в сборку .NET в качестве ресурса Win32. Это необходимо только для активации бесплатной регистрации . Компоненты на основе NET и не являются обязательным требованием для активации собственных компонентов COM.

Шаг 10

В папке проекта SideBySide создайте файл скрипта определения ресурса (текстовый файл) и вызовите его SideBySide.rc. Вставьте следующий код в файл:

#include <windows.h>
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST SideBySide.manifest

Файл windows.h и его зависимости доступны при установке пакета SDK для платформы (основной пакет SDK) или Visual C++. Часть windows.h, которая требуется ниже, — это определение:

#define RT_MANIFEST 24

Следовательно, содержимое SideBySide.rc разрешить:

1 24 SideBySide.manifest

Тем не менее, более четко и более широко использовать определения макросов, как показано в этом направлении.

Шаг 11

В папке проекта SideBySide создайте файл команды сборки (текстовый файл) и вызовите его build.cmd. Вставьте следующий код в файл:

Сборка C#:

rc SideBySide.rc
csc /t:library /out:..\deployed\SideBySide.dll 
/win32res:SideBySide.res Class1.cs

Сборка Visual Basic .NET:

rc SideBySide.rc
vbc /t:library /out:..\deployed\SideBySide.dll 
/win32resource:SideBySide.res /rootnamespace:SideBySide Class1.vb

Эти команды сначала необходимо вызвать средство компилятора ресурсов Microsoft Windows из пакета SDK платформы (rc.exe) для компиляции скрипта определения ресурсов из шага 10 в скомпилированный файл ресурсов с именем SideBySide.res. Затем он вызывает компилятор C# или Visual Basic .NET для сборки файла исходного кода в сборку и внедрения скомпилированного файла ресурсов в него в качестве ресурса Win32. Скомпилированная сборка записывается в папку \deployed, но она не зарегистрирована для взаимодействия COM.

Шаг 12

В командной строке Visual Studio 2003 перейдите в папку SideBySide проекта и выполните команду: build.

Шаг 13

Чтобы убедиться, что, любезно файлов манифеста, клиент сможет активировать класс SideBySideClass через COM-взаимодействие, запустить \deployed\client.exe и заметить ожидаемые выходные данные 1.0.0-C#или "1.0.0-VB.NET".

Устранение неполадок

Как мы видели, активация компонентов на основе .NET Framework без регистрации не требует специального кода на сервере или в клиенте. Все, что необходимо, — это соответствующая пара файлов манифеста, одна из которых внедрена в сборку .NET как ресурс Win32 типа RT_MANIFEST.

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

При устранении неполадок с COM без регистрации средство просмотра событий в Windows Server 2003 является вашим другом. Когда Windows XP или Windows Server 2003 обнаруживает ошибку конфигурации, обычно отображается окно сообщения об ошибке, которое называется запущенным приложением и содержит сообщение "Не удалось запустить это приложение, так как конфигурация приложения неправильная. Переустановка приложения может устранить эту проблему". Я советую каждый раз, когда вы видите это сообщение, вы воспроизводите проблему в Windows Server 2003, обратитесь к журналу системных событий и найдите события из источника SideBySide. Причина, по которой я не предполагаю, что вы просматриваете журнал событий XP в этих случаях, заключается в том, что оно неизменно будет содержать сообщение, например "Сбой контекста активации для [path]\[имя файла приложения]. Очевидный. Сообщение об ошибке ссылки: операция успешно завершена", которая не помогает определить проблему.

Прежде чем перейти к структуре файлов манифеста, давайте поговорим о ресурсах Win32. Как уже упоминалось выше, windows.h определяет символ RT_MANIFEST как значение 24, которое является значением, которое операционная система распознает как внедренный файл манифеста. Если вы забыли включить windows.h в скрипт определения ресурсов (RC-файл), то сборка по-прежнему будет выполнена успешно, и файл манифеста по-прежнему будет внедрен в качестве ресурса, но не правильного типа. Чтобы проверить правильность внедрения манифеста, откройте SideBySide.dll в Visual Studio (файл| Открыть | Файл...). Вы увидите представление дерева с ресурсами в модуле. Под корневым узлом должен быть узел с именем RT_MANIFEST под ним, который должен быть другим узлом, показывающим номер ресурса манифеста (1 в пошаговом руководстве). Дважды щелкните этот последний узел, чтобы просмотреть данные в двоичном представлении и присвойте ему быструю проверку работоспособности, похожей на XML-файл манифеста. Хотя это двоичный код, символы из диапазона ASCII будут очевидны. Если двоичные данные отсутствуют или выглядят неверными, убедитесь, что скрипт определения ресурса (RC-файл) ссылается на файл манифеста. Если текст узла RT_MANIFEST находится в кавычках, скорее всего, вы забыли включить windows.h в скрипт определения ресурсов (RC-файл).

В журнале системных событий Windows Server 2003 с сообщением "Не удалось найти зависимые сборки [имя], и последняя ошибка не установлена в вашей системе".

Схемы различных файлов манифестов документируются в пакете SDK для платформы в разделе "Справочник по файлам манифестов ", а средство проверки схемы manifestchk.vbs доступно, поэтому здесь я буду вызывать только несколько пунктов, относящихся к пошаговому руководству. Сначала рассмотрим файл манифеста сборки. Например, вернитесь к шагу 9.

Вы помните, что в смысле com сборка является абстрактной идеей, с которой вы связываете один или несколько физических файлов с помощью содержимого манифеста сборки файла.

Элемент assemblyIdentity определяет удостоверение сборки . Для. Компоненты на основе NET, атрибуты должны совпадать с именем сборки .NET и, следовательно, его именем файла, в противном случае в журнале системных событий Windows Server 2003 отображается следующее сообщение: "Зависимые сборки [значение имени атрибута] не удалось найти, и в случае последней ошибки в системе не установлено следующее сообщение. Однако версии атрибут не должен соответствовать сборке .NET AssemblyVersion, а также AssemblyFileVersion, хотя рекомендуется применить некоторую согласованность.

Элемент clrClass имеет только два обязательных атрибута: имя и clsid. Имя атрибутадолжно соответствовать объединенному пространству имен и имени класса, активируемому классу CLR. Если это не так, то CoCreateInstance вернет HRESULT со значением COR_E_TYPELOAD (0x80131522). Это приводит к возникновению ошибки System.TypeLoadException, когда загрузчик типов не сможет найти запрошенный тип CLR в сборке .NET. Одна вещь, чтобы отслеживать, если сборка .NET написана в Visual Basic .NET, заключается в том, что вы предоставляете переключатель /rootnamespace в командной строке компилятору .NET Visual Basic (vbc.exe). Атрибут clsid clsidдолжен совпадать с clSID, назначенным классу CLR, активируемым через guidAttribute. Если это не так, То CoCreateInstance вернет HRESULT со значением REGDB_E_CLASSNOTREG (0x80040154), текст сообщения, для которого "Класс не зарегистрирован".

Теперь давайте повернем внимание к файлу манифеста приложения. Например, вернитесь к шагу 8. Манифест приложения должен называться в формате [имя файла приложения].manifest. Таким образом, в пошаговом руководстве он был назван client.exe.manifest, чтобы сделать его понятным, когда client.exe загружается в процесс. Если это не сделано правильно, CoCreateInstance вернет HRESULT со значением REGDB_E_CLASSNOTREG (0x80040154), текст сообщения, для которого "Класс не зарегистрирован".

Наиболее важным элементом манифеста приложения является элемент зависимыйAssembly/assemblyIdentity. Этот элемент является ссылкой на эквивалентный элемент в манифесте сборки, а два должны соответствовать точно. Хороший способ убедиться, что они делают это, — скопировать элемент из манифеста сборки и вставить его здесь. Если в журнале событий системы Windows Server 2003 имеется какое-либо различие, вы увидите следующее сообщение: "Идентификатор компонента, найденный в манифесте, не соответствует идентификатору запрошенного компонента".

Заключение

Com без регистрации — это технология, которая освобождает COM-компоненты от зависимости от реестра Windows и, следовательно, освобождает приложения, которые используют их от необходимости выделенных серверов. Это позволяет приложениям с зависимостями в разных версиях одного и того же COM-компонента совместно использовать инфраструктуру и загружать эти различные версии com-компонентов параллельно в эхо механизма управления версиями и развертывания .NET.

В этой статье описана демонстрация активации компонентов на основе .NET Framework с помощью собственных клиентских приложений, написанных как в Visual C++, так и в Visual Basic 6.0. В ней объясняется, как работает механизм и подчеркнул некоторые возможные ошибки конфигурации и способы их устранения.

Дальнейшее чтение

 

о авторе

Стив Уайт является консультантом по разработке приложений, работающим в команде разработчиков Premier в Microsoft UK. Он поддерживает разработку клиентов с помощью Visual C#, Windows Forms и ASP.NET. Его блог имеет больше информации о его интересах к музыке, визуализациям и программированию.

Лесли Мюллер является технологическим специалистом по исследованиям & разработки в Credit Suisse First Boston. Лесли имеет 12 лет опыта в качестве разработчика и технического архитектора, работая в таких средах, как финансовые услуги, технологические стартапы, промышленная автоматизация и оборона. Когда он не программирует или делает исследования он любит лыжи, хоккей и когда возможно делать немного сумасшедшие вещи с моторизованными автомобилями в экстремальных средах, таких как Исландия или Скалистые скалы.