Registration-Free aktivace komponent modelu COM: Návod
Steve White
Premier Support for Developers, Microsoft UK
Leslie Muller
Global IT Research & Development, Credit Suisse First Boston
Červenec 2005
Shrnutí: Sada Microsoft Platform SDK poskytuje vynikající úlohu dokumentování témat izolovaných aplikací a souběžných sestavení. Ne všichni se však s tímto tématem vyrovnává s aktivací komponent modelu COM bez registrace. Com bez registrace je funkce platformy, která je velmi zajímavá pro podniky s uzamčenými servery a aplikacemi izolovanými na sdílených infrastrukturách. Tento článek vás provede funkčním příkladem registrace bezplatné aktivace nativní komponenty MODELU COM nativními klienty a spravovaným klientem prostřednictvím zprostředkovatele com. (18 tištěných stránek)
Platí pro:
Microsoft Windows Server 2003
Microsoft Windows XP
Microsoft .NET Framework verze 1.1
Microsoft Visual Studio .NET 2003
Microsoft Visual Studio 6.0
Stáhněte si ukázku, která doprovází tento článek, MSDNRegFreeCOM.msi.
Obsah
Úvod
terminologie modelu COM Registration-Free
Spuštění ukázky
Sestavení serveru MODELU COM v jazyce Visual C++
Sestavení klienta C++/.NET
Aktivace Registration-Free
Server com a klient jazyka Visual Basic 6.0
Nekompatibilní apartmány
Použití rozhraní API kontextu aktivace
Řešení problémů
Závěr
Další čtení
Úvod
Com bez registrace je mechanismus, který je k dispozici v systému Microsoft Windows XP (SP2 pro . Komponenty založené na technologii NET) a platformy Microsoft Windows Server 2003. Jak název napovídá, mechanismus umožňuje snadné (například použití XCOPY) nasazení komponent MODELU COM do počítače bez nutnosti je zaregistrovat.
Na cílových platformách je jednou z fází inicializace procesu a jeho závislých modulů načtení všech přidružených souborů manifestu do struktury paměti označované jako kontext aktivace . V případě absence odpovídajících položek registru se jedná o kontext aktivace, který poskytuje vazbu a informace o aktivaci, které potřebuje doba běhu modelu COM. Na serveru COM nebo v klientovi není vyžadován žádný speciální kód, pokud se nerozhodnete zneužít soubory vytvořením kontextů aktivace sami pomocí kontextového rozhraní API pro aktivaci.
V tomto názorném postupu vytvořím jednoduchou nativní komponentu COM a použijem ji, jak zaregistrovanou, tak neregistrovanou, od nativních a spravovaných klientů. Komponenta a nativní klient se zobrazí v jazyce Visual C++ i v jazyce Visual Basic 6.0; spravovaný klient se zobrazí v jazyce C# i v .NET jazyka Visual Basic. Zdrojový kód a ukázky si můžete stáhnout a hned je zobrazit v akci, nebo si je můžete projít s návodem a vytvořit si je krok za krokem.
terminologie modelu COM Registration-Free
Každý, kdo je obeznámen s technologií rozhraní .NET Framework, bude zvyklý na termín sestavení, který označuje sadu jednoho nebo více modulů nasazených, pojmenovaných a verzí jako jednotku, s jedním modulem obsahujícím manifest, který definuje sadu. V modelu COM bez registrace jsou termíny sestavení a manifest půjčovány pro nápady, které jsou podobné konceptu, ale nejsou identické s jejich protějšky .NET.
Model COM bez registrace používá sestavení znamená sadu jednoho nebo více modulů PE (tj. nativních nebo spravovaných) nasazených, pojmenovaných a vydaných verzí jako jednotky. Com bez registrace používá manifest odkazovat na textové soubory s příponou .manifest obsahující XML, která buď definuje identitu sestavení (manifest sestavení), spolu s vazbou a aktivačními podrobnostmi jeho tříd, nebo definuje identitu aplikace (manifest aplikace) spolu s jedním nebo více odkazy na identitu sestavení. Soubor manifestu sestavení je pojmenován pro sestavení a soubor manifestu aplikace je pojmenován pro aplikaci.
Termín souběžná sestavení (SxS) odkazuje na konfiguraci různých verzí stejné komponenty COM prostřednictvím souborů manifestu, aby je bylo možné načíst současně různými vlákny bez nutnosti registrace. SxS umožňuje a je volně synonymem, registrace com.
Spuštění ukázky
Po stažení a extrahování ukázkového kódu najdete složku s názvem \deployed. V této části je verze klientské aplikace Visual C++ (client.exe), jeho manifest (client.exe.manifest), verze com serveru Visual C++ (SideBySide.dll) a jeho manifest (SideBySide.X.manifest). Pokračujte a spusťte client.exe. Očekávaným výsledkem je, že client.exe aktivuje instanci SideBySideClass (implementovanou v SideBySide.dll) a zobrazí výsledek volání metody version, která by měla vypadat jako 1.0.0-CPP.
Sestavení serveru MODELU COM v jazyce Visual C++
Krok 1
Prvním krokem je sestavení serveru COM. V sadě Visual Studio vytvořte nový projekt ATL jazyka Visual C++ a zavolejte ho SideBySide. V Průvodci projektem ATL na kartě Nastavení aplikace zrušte zaškrtnutí políčka Atributd a zaškrtněte políčko Povolit sloučení kódu proxy/stubu.
V Průzkumníku řešení klikněte pravým tlačítkem na uzel projektu a zvolte Přidat | Přidat třídu.... Vyberte ATL Simple Object a zvolte Otevřít. Dejte třídě krátký název SideBySideClass a klepněte na tlačítko Dokončit.
V zobrazení tříd klikněte pravým tlačítkem na uzel ISideBySideClass a zvolte Přidat | Add Method.... V Průvodci přidáním metody zadejte verze jako název metody, zvolte typ parametru BSTR*, zadejte pVer jako název parametru, zaškrtněte políčko retvalovat, potom klikněte na Přidat a potom klikněte na Dokončit.
V zobrazení třídy rozbalte uzel CSideBySideClass a poklikejte na metodu Version. Řádek toDO // nahraďte:
*pVer = SysAllocString(L"1.0.0-CPP");
Vytvoří sestavení vydané verze a zkopíruje \release\SideBySide.dll do \nasazeného.
Sestavení klienta C++/.NET
Dalším krokem je sestavení klienta. V této části názorného postupu máte možnost sestavit klienta Visual C++ nebo klienta .NET pro server modelu COM visual C++. Bez nutnosti říci, je možné kombinovat a shodovat klienty a servery napsané v jazyce Visual C++, Visual Basic 6.0 a .NET. Pokud to chcete udělat, najdete ukázky triviální, aby se změnily tak, aby spolupracovaly. Sady klientů a serverů jsou uspořádány tak, jak jsou v tomto návodu v zájmu prezentace kódu, který funguje as-is.
Krok 2 (možnost A: Visual C++)
Vytvořte nový projekt konzoly Visual C++ Win32 s názvem klient ve složce na stejné úrovni vzhledem ke složce projektu SideBySide projektu. V Průvodci aplikací Win32 na kartě Nastavení aplikace zaškrtněte políčko Přidat podporu pro atl.
Upravte stdafx.h a do horní části souboru přidejte následující řádek hned za #pragma once
:
#define _WIN32_DCOM
Do stdafx.h přidejte do dolní části souboru následující řádek:
#import "..\deployed\SideBySide.dll" no_namespace
Nahraďte obsah client.cpp tímto kódem:
#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;
}
Vytvoří sestavení vydané verze a zkopíruje \release\client.exe do \nasazeného.
Krok 2 (možnost B: .NET Framework)
V sadě Visual Studio .NET 2003 vytvořte novou konzolovou aplikaci jazyka C# nebo Visual Basic .NET s názvem klient ve složce na stejné úrovni vzhledem ke složce projektu SideBySide projektu. Přidejte odkaz na knihovnu typů
Do metody Main vložte následující kód:
Kód jazyka C#
SideBySideLib.ISideBySideClass obj =
new SideBySideLib.SideBySideClassClass();
Console.WriteLine(obj.Version());
Console.ReadLine();
Kód .NET jazyka Visual Basic
Dim obj As SideBySideLib.ISideBySideClass =
New SideBySideLib.SideBySideClassClass
Console.WriteLine(obj.Version())
Console.ReadLine()
Vytvoří sestavení vydané verze a zkopíruje client.exe do \nasazeného.
Krok 3
V současné době by složka \nasazená měla obsahovat kromě některých zprostředkujících souborů pouze client.exe a SideBySide.dlla druhá složka bude zaregistrována procesem sestavení. Pokud chcete zkontrolovat, jestli váš server a klient za těchto normálních okolností spolupracují, spusťte \deployed\client.exe a poznamenejte si očekávaný výstup 1.0.0-CPP.
Krok 4
Tento názorný postup se týká registrace modelu COM, takže teď potřebujeme zrušit registraci sestavení SideBySide. Na příkazovém řádku přejděte do složky \deployed a spusťte příkaz: regsvr32 /u SideBySide.dll
.
Krok 5
Pokud chcete zjistit, jaký účinek měl předchozí krok, spusťte \deployed\client.exe znovu a zobrazí se zpráva Třída není zaregistrovaná. V této fázi jsme frustrovali modul runtime modelu COM od vyhledání informací, které potřebuje v registru, ale zatím jsme tyto informace zpřístupnit alternativními způsoby. V následujících krocích to napravíme.
Aktivace Registration-Free
krok 6
Ve složce \nasazená vytvořte soubor manifestu aplikace (textový soubor) pro client.exe aplikaci a zavolejte ho client.exe.manifest. Do souboru vložte následující:
<?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.X"
version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
Krok 7
Ve složce \deployed vytvořte soubor manifestu privátního sestavení (textový soubor) pro komponentu SideBySide.dll a zavolejte ho SideBySide.X.manifest. Do souboru vložte následující:
<?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.X"
version="1.0.0.0" />
<file name = "SideBySide.dll">
<comClass
clsid="{[CLSID_SideBySideClass]}"
threadingModel = "Apartment" />
<typelib tlbid="{[LIBID_SideBySide]}"
version="1.0" helpdir=""/>
</file>
<comInterfaceExternalProxyStub
name="ISideBySideClass"
iid="{[IID_ISideBySideClass]}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{[LIBID_SideBySide]}" />
</assembly>
Napsal(a) jsem hodnoty GUID, které budou specifické pro váš projekt, ve formě zástupných symbolů. Odpovídající hodnoty těchto zástupných symbolů najdete následujícím způsobem, a to buď v souboru SideBySide projektu SideBySide.idl, nebo otevřením SideBySide.dll v nástroji OLE/COM ObjectViewer (Oleview.exe).
[
object,
uuid([IID_ISideBySideClass]),
dual,
nonextensible,
helpstring("ISideBySideClass Interface"),
pointer_default(unique)
]
interface ISideBySideClass : IDispatch{
[id(1), helpstring("method Version")] HRESULT
Version([out,retval] BSTR* pVer);
};
[
uuid([LIBID_SideBySide]),
version(1.0),
helpstring("SideBySide 1.0 Type Library")
]
library SideBySideLib
{
importlib("stdole2.tlb");
[
uuid([CLSID_SideBySideClass]),
helpstring("SideBySideClass Class")
]
coclass SideBySideClass
{
[default] interface ISideBySideClass;
};
};
Krok 8
V tomto okamžiku bych měl prohlédnout téma vkládání souborů manifestu sestavení jako prostředky Win32. Pokud jsou vývojáři schopni a ochotní znovu sestavit komponenty modelu COM, doporučuje se, aby manifest sestavení (podobně jako manifest vytvořený v předchozím kroku) byl vložen do knihovny DLL modelu COM jako prostředek win32 typu RT_MANIFEST (definovaný v windows.h). V případech, kdy to není možné, dávejte prosím pozor, abyste sestavení (a v důsledku toho manifest sestavení) pojmenováli, který se liší od názvu souboru knihovny COM DLL. V předchozím případě se knihovna COM DLL nazývá SideBySide, ale sestavení se nazývá SideBySide.X. Pokud vás zajímá důvod tohoto omezení, je vysvětleno v části Řešení potíží. V tomto názorném postupu není manifest sestavení vložen tak, aby odrážel mnoho reálných případů, ve kterých to bude možné provést.
Krok 9
Chcete-li ověřit, zda je váš klient opět schopen aktivovat třídu SideBySideClass třídy, spustit \deployed\client.exe a poznamenat očekávaný výstup "1.0.0-CPP".
Server com a klient jazyka Visual Basic 6.0
Krok 1
Prvním krokem je sestavení serveru COM. Vytvořte nový projekt knihovny ActiveX DLL jazyka Visual Basic 6.0. V Průzkumníku projektů vyberte uzel Project1 a v okně vlastností změňte jeho název na SideBySide. V Průzkumníku projektů vyberte uzel Class1 a v okně Vlastnosti změňte jeho název na SideBySideClass.
Do okna kódu vložte následující podprogram:
Public Function Version()
Version = "1.0.0-VB6"
End Function
Zvolte soubor | Nastavte SideBySide.dll... a přejděte do složky \deployed a klikněte na OK. Pokud chcete zabránit generování nových identifikátorů GUID při každém vytváření knihovny DLL, zvolte Project | SideBySide Properties..., pak klepněte na kartu Komponenta a ve skupině Kompatibilita verzí vyberte přepínač Binární kompatibilita.
Krok 2
Vytvořte nový projekt EXE jazyka Visual Basic 6.0 Standard. V Průzkumníku projektů vyberte uzel Project1 a v okně Vlastnosti změňte jeho název na klienta. Zvolte soubor | Uložte project jako a uložte soubor formuláře a soubor projektu ve složce na stejné stejné hodnotě vzhledem ke složce projektu SideBySide projektu. Zvolte Project | Odkazy, zaškrtněte políčko vedle SideBySidea klepněte na tlačítko OK.
Poklikejte na hlavní formulář v návrháři formulářů a vložte následující kód do Sub Form_Load():
Dim obj As New SideBySideClass
MsgBox obj.Version()
Zvolte soubor | Nastavte client.exe... a přejděte do složky \deployed a pak zvolte OK.
Krok 3
V současné době by složka \nasazená měla obsahovat kromě některých zprostředkujících souborů pouze client.exe a SideBySide.dll; a ta druhá bude zaregistrována procesem sestavení. Pokud chcete zkontrolovat, jestli váš server a klient za těchto normálních okolností spolupracují, spusťte \deployed\client.exe a poznamenejte si očekávaný výstup 1.0.0-VB6.
Krok 4
Tento názorný postup se týká registrace modelu COM, takže teď potřebujeme zrušit registraci sestavení SideBySide. Na příkazovém řádku přejděte do složky \deployed a spusťte příkaz: regsvr32 /u SideBySide.dll
.
Krok 5
Pokud chcete zjistit, jaký účinek měl předchozí krok, spusťte \deployed\client.exe znovu a zobrazí se zpráva "Chyba za běhu 429: Komponenta ActiveX nemůže vytvořit objekt". V této fázi jsme frustrovali modul runtime modelu COM z vyhledání informací, které potřebuje v registru, ale zatím jsme tyto informace zpřístupnit alternativními způsoby. V následujících krocích to napravíme.
Krok 6
Ve složce \nasazená vytvořte soubor manifestu aplikace (textový soubor) pro client.exe aplikaci a zavolejte ho client.exe.manifest. Do souboru vložte následující:
<?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.X"
version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
Krok 7
Ve složce \deployed vytvořte soubor manifestu privátního sestavení (textový soubor) pro komponentu SideBySide.dll a zavolejte ho SideBySide.X.manifest. Do souboru vložte následující:
<?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.X"
version="1.0.0.0" />
<file name = "SideBySide.dll">
<comClass
clsid="{[CLSID_SideBySideClass]}"
threadingModel = "Apartment" />
<typelib tlbid="{[LIBID_SideBySide]}"
version="1.0" helpdir=""/>
</file>
<comInterfaceExternalProxyStub
name="_SideBySideClass"
iid="{[IID__SideBySideClass]}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{[LIBID_SideBySide]}" />
</assembly>
Napsal(a) jsem hodnoty GUID, které budou specifické pro váš projekt, ve formě zástupných symbolů. Odpovídající hodnoty těchto zástupných symbolů najdete otevřením SideBySide.dll v nástroji OLE/COM ObjectViewer (Oleview.exe).
[
uuid([LIBID_SideBySide]),
version(1.0),
custom(50867B00-BB69-11D0-A8FF-00A0C9110059, 8169)
]
library SideBySide
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-
C000-000000000046}
importlib("stdole2.tlb");
// Forward declare all types defined in this typelib
interface _SideBySideClass;
[
odl,
uuid([IID__SideBySideClass]),
version(1.0),
hidden,
dual,
nonextensible,
oleautomation
]
interface _SideBySideClass : IDispatch {
[id(0x60030000)]
HRESULT Version([out, retval] VARIANT* );
};
[
uuid([CLSID_SideBySideClass]),
version(1.0)
]
coclass SideBySideClass {
[default] interface _SideBySideClass;
};
};
Krok 8
Chcete-li ověřit, že se svolením souborů manifestu je váš klient ještě jednou schopen aktivovat SideBySideClass třídy, spustit \deployed\client.exe a poznamenat očekávaný výstup "1.0.0-VB6".
Nekompatibilní apartmány
Všechny servery COM v tomto návodu jsou vytvořeny tak, aby běžely v Single-Threaded Apartment (tj. STA nebo Apartment-threaded, components). Všichni klienti jsou STA s výjimkou klienta C++, což je MTA (jeho vlákno běží v Multi-Threaded Apartment). Existuje tedy jeden případ, kdy klient a server žijí v nekompatibilních apartmánech a v tomto případě musí probíhat zařazování volání modelu COM mezi proxy serverem a zástupným kódem. V tomto případě se používá následující část souboru manifestu sestavení:
...
<typelib tlbid="{[LIBID_SideBySide]}"
version="1.0" helpdir=""/>
</file>
<comInterfaceExternalProxyStub
name="ISideBySideClass"
iid="{[IID_ISideBySideClass]}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{[LIBID_SideBySide]}" />
...
Tyto prvky poskytují informace, které by jinak byly v registru. Element comInterfaceExternalProxyStub poskytuje dostatek informací pro typ knihovny zařazování a je vhodné pro rozhraní COM odvozená z IDispatch (která zahrnují všechna rozhraní Automation). V těchto případech ole32.dll externí proxy zástupný procedura (tj. externí souborům v sestavení). Pokud komponenty modelu COM implementují pouze odesílání
Vlastní rozhraní jsou trochu vzácnější a pro ty musíte udělat trochu více práce. Zvažte rozhraní s názvem ISxSCustom, které je odvozeno přímo z IUnknown a není kompatibilní s automatizací. Pro SideBySideClass implementovat ISxSCustoma pro klienty, aby volali své metody ve scénáři bez registrace, musím přidat comInterfaceProxyStub element do manifestu sestavení. Jak navrhuje název elementu, tentokrát je zástupný kód proxy není externí: je poskytována buď SideBySide.dll (pokud jsem zaškrtnu políčko Povolit sloučení proxy/zástupný kód v Průvodci projektem ATL) nebo v SideBySidePS.dll. Pokud je zástupný kód proxy sloučený, nový prvek je podřízeným prvkem existujícího souboru elementu:
<file name = "SideBySide.dll">
...
<comInterfaceProxyStub
name="ISxSCustom"
iid="{[IID_ISxSCustom]}" />
</file>
Jinak potřebuji přidat další element souboru deklarující knihovnu DLL proxy-stub:
<file name = "SideBySide.dll"> ... </file>
<file name = "SideBySidePS.dll">
<comInterfaceProxyStub
name="ISxSCustom"
iid="{[IID_ISxSCustom]}" />
</file>
Kdybych nepotřeboval ilustrovat výše popsané prvky, vytvořil bych server MODELU COM visual C++, aby byl obou vláken tak, aby jeho třídy byly aktivovány v MTA klienta. V případě, že klient a server existují ve stejném bytě, jsou prvky, které jsou právě popsány, ignorovány. Nicméně, vyzývám vás, abyste nezávisel na této situaci, protože mohou existovat situace mimo vaši kontrolu, kde je komponenta aktivována v jiném bytě než jeho klient, i když jejich modely vláken jsou konzistentní. Vzhledem k relativně malému úsilí, myslím, že je vhodné vždy zahrnout konfiguraci proxy-zástupných procedur ve vašich manifestech.
Použití rozhraní API kontextu aktivace
V části Úvod jsem zmínil, že jednou z fází inicializace procesu aplikace, na platformách, na kterých se tento článek týká, je vyhledání souboru manifestu aplikace. Soubor manifestu aplikace obsahuje odkazy na sestavení, na kterých má aplikace závislosti. V případě registrace bez registrace nativních komponent modelu COM, co znamená sestavení je sada jedné nebo více knihoven DLL com shromážděných v rámci společné identity a verze.
Pokud vaše aplikace ví, priori potenciální sadu koclass, které se mají během své životnosti přímo nebo nepřímo aktivovat, jsou manifesty aplikace pohodlné. Existuje ale poměrně vzácná třída aplikací (např. gridových serverů), která návrhem nevědí, že moduly, které se načtou, ještě před modulem runtime. V tomto případě se volá způsob odkazování na soubory manifestu sestavení po inicializaci procesu. To je splněno kontextové rozhraní API pro aktivaci, použití, které obviuje soubor manifestu aplikace. V nejjednodušším případě je technika inicializace struktury ACTCTX s umístěním souboru manifestu sestavení a pak vytvořit a aktivovat kontext aktivace z něj. Následující pokyny předpokládají, že jste již vytvořili klienta Visual C++ aplikaci popsanou v kroku 2 (možnost A).
Upravte stdafx.h a bezprostředně za definici _WIN32_DCOM
přidejte následující řádek:
#define _WIN32_FUSION 0x0100 // this causes activation context
structs and APIs to be included.
Pokud se podíváte na funkci _tmain v client.cpp, mezi inicializací modelu COM a neinicializovat volání, uvidíte složený příkaz, který aktivuje a volá SideBySideClass. Tento složený příkaz (vše mezi složenými závorkami) musíme přesunout uvnitř nový oddíl kódu, který inicializuje kontext aktivace následujícím způsobem:
ACTCTX actCtx;
memset((void*)&actCtx, 0, sizeof(ACTCTX));
actCtx.cbSize = sizeof(ACTCTX);
actCtx.lpSource = "SideBySide.X.manifest";
HANDLE hCtx = ::CreateActCtx(&actCtx);
if (hCtx == INVALID_HANDLE_VALUE)
cout << "CreateActCtx returned: INVALID_HANDLE_VALUE"
<< endl;
else
{
ULONG_PTR cookie;
if (::ActivateActCtx(hCtx, &cookie))
{
// previous compound statement goes here...
::DeactivateActCtx(0, cookie);
}
}
Výše uvedený kód se spustí před aktivací jakýchkoli tříd. Kód jednoduše načte soubor manifestu sestavení (jehož název je v tomto příkladu pevně zakódovaný, ale měl by odpovídat sestavení, které chcete načíst dynamicky) do aktivačního kontextu, který pak aktivuje (tj. vytvoří aktuální). Od tohoto okamžiku se aktivace coclass provádí stejně jako předtím. Nyní můžete zahodit client.exe.manifest.
Alternativou k rozhraní API kontextu přímé aktivace, ale k dispozici pouze v systému Windows Server 2003, je objekt microsoft.Windows.ActCtx.
Není nutné říci, že existuje mnohem více pro kontext aktivace rozhraní API, než jsem zde ukázal a můžete najít odkaz na úplnou dokumentaci k rozhraní API v další čtení části.
Řešení problémů
Jak jsme viděli, registrace bez registrace komponent MODELU COM nevyžaduje žádný speciální kód na serveru nebo v klientovi. Vše, co je potřeba, je odpovídající dvojice souborů manifestu.
Navrhuji vám přístup k vlastnímu vývoji bez registrace způsobem, jak to tento návod dělá. Konkrétně: nejprve se dostanete ke známému stavu tím, že uvidíte, že váš klient pracuje s registrovaným serverem; pak zrušte registraci serveru a ověřte, že vaše chybová zpráva je to, co jste očekávali; a konečně, napravit situaci vytvářením a nasazením souborů manifestu. Tímto způsobem se úsilí o řešení potíží s aktivací bez registrace omezí na strukturu souborů manifestu (a správné vložení manifestu, pokud se tak rozhodnete).
Při řešení problémů modelu COM bez registrace je prohlížeč událostí v systému Windows Server 2003 váš přítel. Když systém Windows XP nebo Windows Server 2003 zjistí chybu konfigurace, obvykle se zobrazí okno s chybovou zprávou s názvem aplikace, kterou jste spustili, a obsahuje zprávu "Tato aplikace se nepodařilo spustit, protože konfigurace aplikace není správná. Přeinstalace aplikace může tento problém vyřešit." Doporučuji, že kdykoli uvidíte tuto zprávu, reprodukujete problém v systému Windows Server 2003, podívejte se do protokolu událostí systému a vyhledejte události z SideBySide zdroj. Důvod, proč nenavrhuji, že se podíváte na protokol událostí systému Windows XP v těchto případech je, že bude vždy obsahovat zprávu, jako je například "Vygenerovat kontext aktivace selhal pro [path]\[název_souboru aplikace]. Manifest. Referenční chybová zpráva: Operace se úspěšně dokončila, což nepomůže identifikovat problém.
Schémata různých souborů manifestu jsou zdokumentovaná v sadě SDK platformy pod nadpisem Soubory manifestu Referenčnía nástroj pro ověření schématu Manifestchk.vbs je k dispozici, takže zde budu popisovat pouze několik bodů relevantních pro návod. Nejprve se podíváme na soubor manifestu sestavení. Podívejte se například zpět na krok 7.
Vzpomeňte si, že v registrační smyslu je sestavení abstraktní myšlenkou, ke které přidružíte jeden nebo více fyzických souborů prostřednictvím obsahu manifestu sestavení souboru. Název sestavení se zobrazí na třech místech a musí být v každém z nich stejný: v názvu atribut souboru manifestu sestavení assemblyIdentity element; v název atribut souboru manifestu aplikace dependentAssembly/assemblyIdentity element; a název samotného souboru manifestu sestavení s výjimkou přípony .manifest. Pokud se název souboru manifestu neshoduje s názvem v manifestu aplikace, zobrazí se v protokolu událostí systému Windows Server 2003 následující zpráva: "Závislé sestavení [hodnota název atributu v manifestu aplikace] nebylo nalezeno a poslední chyba byla odkazovaná sestavení není nainstalována ve vašem systému." Pokud je název element v manifestu sestavení nesprávný, zobrazí se v protokolu událostí systému Windows Server 2003 následující zpráva: Identita komponenty nalezená v manifestu neodpovídá identitě požadované komponenty.
Pokud SideBySide.dll byla komponenta založená na rozhraní .NET Framework, museli bychom vložit soubor manifestu sestavení do SideBySide sestavení jako prostředek Win32 (a soubor manifestu bychom pojmenovali po sestavení .NET , tj. SideBySide.manifest). Vzhledem k sekvenci vyhledávání zavaděče sestavení je však pro nativní komponenty modelu COM volitelné pro vložení manifestu do modulu. Než zavaděč sestavení vyhledá [AssemblyName].manifest, vyhledá [AssemblyName].dll a vyhledá v něm prostředek Win32 typu RT_MANIFEST. Konfigurace uvnitř prostředku musí mít element AssemblyIdentity, který odpovídá [AssemblyName] a další atributy v AssemblyIdentity manifestu aplikace odkazu.
Pokud se však [AssemblyName].dll najde, ale neobsahuje odpovídající manifest, zastaví se mechanismus načítání sestavení a nebude nadále hledat [AssemblyName].manifest. V době psaní tohoto článku platí zavaděč sestavení v systému Windows XP (což v této situaci zobrazí svou obvyklou zprávu, že "konfigurace aplikace je nesprávná"), ale ne v systému Windows Server 2003. V systému Windows Server 2003 hledání pokračovat a soubor manifestu najít, i když odpovídá názvu modulu. Nicméně, vyzývám vás, abyste nezávisel na tomto chování. Místo toho, abyste zajistili konzistentně podporu obou platforem, doporučujeme vložit manifest sestavení do sestavení jako RT_MANIFEST prostředek, kdykoli je to možné. Pokud to není možné, musíte souboru manifestu sestavení dát jiný název než jakýkoli modul ve stejné složce. Případně umístěte komponentu COM do podřízené složky složky manifestu sestavení a odkazujte na tuto podřízenou cestu do souboru manifestu sestavení souboru elementu.
Element
Element souboru
Element comClass má pouze jeden povinný atribut: clsid. Pokud se aplikace pokusí aktivovat neregistrovanou třídu coclass, jejíž CLSID není uvedena v comClass element v manifestu sestavení, CoCreateInstance vrátí HRESULT s hodnotou REGDB_E_CLASSNOTREG (0x80040154), text zprávy, pro kterou není zaregistrovaná třída.
Jak jsem řekl, typelib a
comInterface[External]ProxyStub prvky jsou vyžadovány v případě, že klient a server existují v různých apartmánech, takže následující chyby lze zobrazit pouze při zpracování těchto prvků. Chyby konfigurace v těchto prvcích způsobují CoCreateInstance vrátit HODNOTU HRESULT, která odpovídá zprávám "Knihovna není zaregistrovaná", "Chyba při načítání knihovny/knihovny DLL" nebo "žádné takové rozhraní se nepodporuje". Pokud se zobrazí některé z těchto zpráv, pečlivě zkontrolujte identifikátory GUID a ujistěte se, že jsou k dispozici všechny povinné atributy. Schéma souboru manifestu najdete v sadě SDK platformy.
Teď se podíváme na soubor manifestu aplikace. Příklad: Vraťte se ke kroku 6. manifestu aplikace musí mít název ve formátu [název_souboru_aplikace].manifest. V návodu se tedy jmenovala client.exe.manifest, aby bylo jasné, že by se měla číst při každém načtení client.exe do procesu. Pokud se to neprovede správně, vrátí funkce CoCreateInstance hodnotu HRESULT s hodnotou REGDB_E_CLASSNOTREG (0x80040154), text zprávy, pro kterou není zaregistrovaná třída.
Nejdůležitějším prvkem v manifestu aplikace je dependentAssembly/assemblyIdentity element. Tento prvek je odkaz na ekvivalentní jeden v manifestu sestavení a oba musí odpovídat přesně. Dobrým způsobem, jak zajistit, aby to udělali, je zkopírovat prvek z manifestu sestavení a vložit ho sem. Pokud existuje jakýkoli rozdíl, zobrazí se v protokolu událostí systému Windows Server 2003 následující zpráva: "Identita komponenty nalezená v manifestu neodpovídá identitě požadované komponenty."
Závěr
Com bez registrace je technologie, která uvolní komponenty MODELU COM ze závislosti na registru Windows a v důsledku toho uvolní aplikace, které je používají, od vyžadování vyhrazených serverů. Umožňuje aplikacím se závislostmi na různých verzích stejné komponenty MODELU COM sdílet infrastrukturu a načíst tyto různé verze komponent MODELU COM vedle sebe v ozvěně mechanismu správy verzí a nasazení rozhraní .NET Framework.
Tento článek vás provede ukázkou registrace bezplatné aktivace nativních komponent modelu COM nativními klientskými aplikacemi napsanými v jazyce Visual C++ i Visual Basic 6.0 a spravovaným klientem. Vysvětluje, jak mechanismus funguje a podtrhl některé možné chyby konfigurace a jak je řešit.
Další čtení
- Registration-Free aktivace . komponentyNET-Based: Návod
- izolované aplikace a souběžná sestavení
- schématu souboru manifestu
- pomocí rozhraní API kontextu aktivace
o autorovi
Steve White je konzultant pro vývoj aplikací pracující v týmu Premier Support for Developers v Microsoft UK. Podporuje vývoj zákazníků pomocí Visual C#, Windows Forms a ASP.NET. Jeho blog má více informací o jeho zájmech o hudbu, vizualizace a programování.
Leslie Muller je technik s týmem Research & Development v Credit Suisse First Boston. Leslie má 12 let zkušeností jako vývojář a technický architekt, pracující v prostředích, jako jsou finanční služby, technologické startupy, průmyslová automatizace a obrana. Když neprogramuje ani neprovádí výzkum, baví se lyžování, hokej a když je to možné trochu šílené věci s motorizovanými vozidly v extrémních prostředích, jako je Island nebo Rockies.