Registration-Free'attivazione dei componenti COM: procedura dettagliata
Steve White
Supporto Premier per sviluppatori, Microsoft UK
Leslie Muller
Global IT Research & Development, Credit Suisse First Boston
Luglio 2005
riepilogo : Microsoft Platform SDK offre un ottimo lavoro per documentare gli argomenti di applicazioni isolate e assembly side-by-side. Tuttavia, non tutti equivalgono a questo argomento con quello dell'attivazione senza registrazione dei componenti COM. COM senza registrazione è una funzionalità di piattaforma di grande interesse per le aziende con server e applicazioni bloccati isolati in infrastrutture condivise. Questo articolo illustra un esempio funzionante dell'attivazione senza registrazione di un componente COM nativo da parte di client nativi e, tramite interoperabilità COM, da un client gestito. (18 pagine stampate)
Si applica a:
Microsoft Windows Server 2003
Microsoft Windows XP
Microsoft .NET Framework versione 1.1
Microsoft Visual Studio .NET 2003
Microsoft Visual Studio 6.0
Scaricare l'esempio che accompagna questo articolo MSDNRegFreeCOM.msi.
Contenuto
Introduzione
terminologia com Registration-Free
Esecuzione dell'esempio
Compilazione del server COM di Visual C++
Compilazione del client C++/.NET
attivazione Registration-Free
Server e client COM di Visual Basic 6.0
Appartamenti incompatibili
Uso dell'API del contesto di attivazione
Risoluzione dei problemi
Conclusione
Altre informazioni
Introduzione
COM senza registrazione è un meccanismo disponibile in Microsoft Windows XP (SP2 per . Componenti basati su NET) e piattaforme Microsoft Windows Server 2003. Come suggerisce il nome, il meccanismo consente una distribuzione semplice (ad esempio, con XCOPY) di componenti COM in un computer senza la necessità di registrarli.
Nelle piattaforme di destinazione, una delle fasi di inizializzazione di un processo e dei relativi moduli dipendenti consiste nel caricare tutti i file manifesto associati in una struttura di memoria denominata contesto di attivazione . In assenza di voci del Registro di sistema corrispondenti, si tratta di un contesto di attivazione che fornisce le informazioni di associazione e attivazione necessarie per il tempo di esecuzione COM. Non è necessario alcun codice speciale nel server COM o nel client, a meno che non si scelga di ignorare l'uso dei file creando personalmente contesti di attivazione usando l'API del contesto di attivazione .
In questa procedura dettagliata si creerà un semplice componente COM nativo e lo si utilizzerà, sia registrato che non registrato, dai client nativi e gestiti. Il componente e il client nativo verranno presentati sia in Visual C++ che in Visual Basic 6.0; Il client gestito verrà presentato sia in C# che in Visual Basic .NET. È possibile scaricare il codice sorgente e gli esempi e visualizzarli immediatamente in azione oppure seguire la procedura dettagliata e compilarli manualmente.
terminologia com Registration-Free
Chiunque abbia familiarità con la tecnologia .NET Framework sarà abituato al termine assembly, che indica un set di uno o più moduli distribuiti, denominati e con controllo delle versioni come unità, con un modulo contenente un manifesto che definisce il set. In COM senza registrazione, i termini assembly e manifesto vengono presi in prestito per idee simili in concetto ma non identiche alle loro controparti .NET.
COM senza registrazione usa assembly per indicare un set di uno o più moduli PE (ad esempio, nativi o gestiti) distribuiti, denominati e con controllo delle versioni come unità. COM senza registrazione usa
Il termine assembly side-by-side (SxS) fa riferimento alla configurazione di versioni diverse dello stesso componente COM, tramite file manifesto, in modo che possano essere caricati simultaneamente da thread diversi senza dover essere registrati. SxS abilita ed è sinonimo di COM senza registrazione.
Esecuzione dell'esempio
Dopo aver scaricato ed estratto il codice di esempio, si troverà una cartella denominata \deployed. In questa è la versione visual C++ dell'applicazione client (client.exe), il relativo manifesto (client.exe.manifest), la versione visual C++ del server COM (SideBySide.dll) e il relativo manifesto (SideBySide.X.manifest). Procedere ed eseguire client.exe. Il risultato previsto è che
Compilazione del server COM di Visual C++
Passaggio 1
Il primo passaggio consiste nel creare un server COM. In Visual Studio creare un nuovo progetto ATL di Visual C++ e chiamarlo SideBySide. Nella scheda Impostazioni applicazione della Creazione guidata progetto ATL deselezionare la casella di controllo con attributi e selezionare la casella di controllo Consenti unione del codice proxy/stub.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto e scegliere Aggiungi | Aggiungi classe.... Selezionare oggetto semplice ATL e scegliere Apri. Assegnare alla classe un breve nome di SideBySideClass e fare clic su Fine.
In Visualizzazione classi fare clic con il pulsante destro del mouse sul nodo ISideBySideClass
In Visualizzazione classi espandere il nodo
*pVer = SysAllocString(L"1.0.0-CPP");
Creare una build di versione e copiare \release\SideBySide.dll in \deployed.
Compilazione del client C++/.NET
Il passaggio successivo consiste nel compilare il client. In questa parte della procedura dettagliata è possibile compilare un client Visual C++ o .NET per il server COM Visual C++. Inutile dire, è possibile combinare e abbinare client e server scritti in Visual C++, Visual Basic 6.0 e .NET. Se vuoi farlo, troverai i campioni semplici da modificare in modo che lavorino insieme. I set di client e server sono organizzati come sono in questa procedura dettagliata nell'interesse della presentazione del codice che funziona as-is.
Passaggio 2 (opzione A: Visual C++)
Creare un nuovo progetto console Win32 di Visual C++ denominato client in una cartella di pari livello rispetto alla cartella del progetto SideBySide. Nella scheda Impostazioni applicazione win32 selezionare la casella di controllo Aggiungi supporto per ATL.
Modificare stdafx.h e aggiungere la riga seguente all'inizio del file, subito dopo il #pragma once
:
#define _WIN32_DCOM
Anche in stdafx.h aggiungere la riga seguente nella parte inferiore del file:
#import "..\deployed\SideBySide.dll" no_namespace
Sostituire il contenuto di client.cpp con questo codice:
#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;
}
Creare una build di versione e copiare \release\client.exe in \deployed.
Passaggio 2 (opzione B: .NET Framework)
In Visual Studio .NET 2003 creare una nuova applicazione console C# o Visual Basic .NET denominata client in una cartella di pari livello rispetto alla cartella del progetto SideBySide. Aggiungere un riferimento alla libreria dei tipi
Incollare il codice seguente all'interno del metodo Main
Codice C#
SideBySideLib.ISideBySideClass obj =
new SideBySideLib.SideBySideClassClass();
Console.WriteLine(obj.Version());
Console.ReadLine();
Codice .NET di Visual Basic
Dim obj As SideBySideLib.ISideBySideClass =
New SideBySideLib.SideBySideClassClass
Console.WriteLine(obj.Version())
Console.ReadLine()
Creare una build di versione e copiare client.exe in \deployed.
Passaggio 3
Attualmente la cartella
Passaggio 4
Questa procedura dettagliata riguarda regsvr32 /u SideBySide.dll
.
Passaggio 5
Per vedere quale effetto ha avuto il passaggio precedente, eseguire di nuovo \deployed\client.exe e verrà visualizzato il messaggio "Classe non registrata". In questa fase il runtime COM è stato frustrato dalla ricerca delle informazioni necessarie nel Registro di sistema, ma le informazioni sono ancora disponibili in modo alternativo. Rimedieremo a questo nei passaggi seguenti.
attivazione Registration-Free
passaggio 6
Nella cartella \deployed creare un file manifesto dell'applicazione (un file di testo) per l'applicazione client.exe e chiamarlo client.exe.manifest. Incollare quanto segue nel file:
<?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>
Passaggio 7
Nella cartella
<?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>
Ho scritto i valori GUID, che saranno specifici per il tuo progetto, sotto forma di segnaposto. I rispettivi valori di questi segnaposto sono disponibili nel file SideBySideSideBySide.idl file oppure aprendo SideBySide.dll nello strumento 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;
};
};
Passaggio 8
A questo punto dovrei esaminare l'oggetto dell'incorporamento dei file manifesto dell'assembly come risorse Win32. Dove gli sviluppatori sono in grado e disposti a ricompilare i componenti COM, è consigliabile che un manifesto dell'assembly (come quello creato nel passaggio precedente) sia incorporato nella DLL COM come risorsa Win32 di tipo RT_MANIFEST (definito in windows.h). Nei casi in cui ciò non è possibile, prestare attenzione a assegnare all'assembly (e di conseguenza al manifesto dell'assembly) un nome diverso da quello del nome file della DLL COM. Pertanto, nel caso precedente, la DLL COM viene chiamata SideBySide ma l'assembly viene chiamato SideBySide.X. Se si è interessati al motivo di questo vincolo, viene illustrato nella sezione Risoluzione dei problemi. In questa procedura dettagliata il manifesto dell'assembly non è incorporato per riflettere i molti casi reali in cui questa operazione non sarà fattibile.
Passaggio 9
Per verificare che, per gentile concessione dei file manifesto, il client è ancora una volta in grado di attivare la classe SideBySideClass
Server e client COM di Visual Basic 6.0
Passaggio 1
Il primo passaggio consiste nel creare un server COM. Creare un nuovo progetto DLL ActiveX di Visual Basic 6.0. In Esplora progetti selezionare il nodo
Incollare la subroutine seguente nella finestra codice:
Public Function Version()
Version = "1.0.0-VB6"
End Function
Scegliere
Passaggio 2
Creare un nuovo progetto EXE Standard di Visual Basic 6.0. In Esplora progetti selezionare il nodo
Fare doppio clic sul modulo principale in Progettazione moduli e incollare il codice seguente all'interno di Sub Form_Load():
Dim obj As New SideBySideClass
MsgBox obj.Version()
Scegliere
Passaggio 3
Attualmente la cartella
Passaggio 4
Questa procedura dettagliata riguarda regsvr32 /u SideBySide.dll
.
Passaggio 5
Per vedere quale effetto ha avuto il passaggio precedente, eseguire di nuovo \deployed\client.exe e verrà visualizzato il messaggio "Errore di run-time '429': componente ActiveX non è in grado di creare l'oggetto". In questa fase il runtime COM è stato frustrato dalla ricerca delle informazioni necessarie nel Registro di sistema, ma le informazioni sono ancora disponibili in modo alternativo. Rimedieremo a questo nei passaggi seguenti.
Passaggio 6
Nella cartella \deployed creare un file manifesto dell'applicazione (un file di testo) per l'applicazione client.exe e chiamarlo client.exe.manifest. Incollare quanto segue nel file:
<?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>
Passaggio 7
Nella cartella
<?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>
Ho scritto i valori GUID, che saranno specifici per il tuo progetto, sotto forma di segnaposto. I rispettivi valori di questi segnaposto sono disponibili aprendo SideBySide.dll nello strumento 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;
};
};
Passaggio 8
Per verificare che, per gentile concessione dei file manifesto, il client è ancora una volta in grado di attivare la classe SideBySideClass, eseguire \deployed\client.exe e notare l'output previsto "1.0.0-VB6".
Appartamenti incompatibili
Tutti i server COM in questa procedura dettagliata vengono compilati per l'esecuzione in un apartment di Single-Threaded (ad esempio, sono componenti sta o threaded apartment). Tutti i client sono STA ad eccezione del client C++, ovvero MTA (il relativo thread viene eseguito in un apartment a thread multipli). Quindi c'è un caso in cui il client e il server vivono in appartamenti incompatibili e in questo caso il marshalling tra apartment delle chiamate COM deve avvenire tra un proxy e uno stub. In questo caso viene usato la sezione seguente del file manifesto dell'assembly:
...
<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]}" />
...
Questi elementi forniscono informazioni che altrimenti sarebbero presenti nel Registro di sistema. L'elemento comInterfaceExternalProxyStub
Le interfacce personalizzate sono un po ' più rare e per questi è necessario fare un po 'di più. Si consideri un'interfaccia denominata ISxSCustom che deriva direttamente da IUnknown e non è compatibile con l'automazione. Per SideBySideClass implementare ISxSCustome per consentire ai client di chiamare i relativi metodi in uno scenario senza registrazione, è necessario aggiungere un comInterfaceProxyStub elemento al manifesto dell'assembly. Come suggerito dal nome dell'elemento, questa volta il proxy-stub è non esterno: viene fornito da SideBySide.dll (se è stata selezionata la casella di controllo Consenti unione del codice proxy/stub nella Creazione guidata progetto ATL) o in SideBySidePS.dll. Se il proxy-stub viene unito, il nuovo elemento è figlio dell'elemento file esistente:
<file name = "SideBySide.dll">
...
<comInterfaceProxyStub
name="ISxSCustom"
iid="{[IID_ISxSCustom]}" />
</file>
In caso contrario, è necessario aggiungere un ulteriore elemento di file dichiarando la dll proxy-stub:
<file name = "SideBySide.dll"> ... </file>
<file name = "SideBySidePS.dll">
<comInterfaceProxyStub
name="ISxSCustom"
iid="{[IID_ISxSCustom]}" />
</file>
Se non avessi bisogno di illustrare gli elementi descritti in precedenza, avrei compilato il server COM di Visual C++ per essere a threading in modo che le relative coclassi sarebbero state attivate nell'MTA del client. Nel caso in cui il client e il server esistano nello stesso apartment, gli elementi appena descritti vengono ignorati. Tuttavia, ti invito a non dipendere da questa circostanza perché potrebbero esserci situazioni al di fuori del controllo in cui un componente viene attivato in un apartment diverso dal suo client, anche se i loro modelli di threading sono coerenti. Considerando il minimo sforzo richiesto, penso sia consigliabile sempre includere la configurazione proxy-stub nei manifesti.
Uso dell'API del contesto di attivazione
Nella sezione introduzione ho menzionato che una delle fasi di inizializzazione del processo di un'applicazione, sulle piattaforme a cui si applica questo articolo, consiste nell'individuare un file manifesto dell'applicazione. Il file manifesto dell'applicazione contiene riferimenti agli assembly in cui l'applicazione presenta dipendenze. Nel caso dell'attivazione senza registrazione di componenti COM nativi, il significato di un assembly è un set di una o più DLL COM raccolte con un'identità e una versione comuni.
Se l'applicazione conosce un potenziale set di coclassi da attivare direttamente o indirettamente durante la sua durata, i manifesti dell'applicazione sono utili. Tuttavia, esiste una classe relativamente rara di applicazioni (ad esempio, server griglia) che per impostazione predefinita non, prima del runtime, conoscere i moduli che caricheranno. In questo caso, viene chiamato un modo per fare riferimento ai file manifesto dell'assembly dopo l'inizializzazione del processo. Questa operazione viene soddisfatta dall'API del contesto di attivazione , l'uso del quale obvia un file manifesto dell'applicazione. Al suo modo più semplice, la tecnica consiste nell'inizializzare una struttura ACTCTX con il percorso del file manifesto dell'assembly e quindi creare e attivare un contesto di attivazione da esso. Le istruzioni seguenti presuppongono che sia già stata compilata l'applicazione client visual C++ descritta nel passaggio 2 (opzione A).
Modificare stdafx.h e aggiungere la riga seguente immediatamente dopo la definizione di _WIN32_DCOM
:
#define _WIN32_FUSION 0x0100 // this causes activation context
structs and APIs to be included.
Se si esamina la funzione _tmain in client.cpp, tra le chiamate COM inizializzate e non inizializzate, verrà visualizzata un'istruzione composta che attiva e chiama il SideBySideClass. È necessario spostare questa istruzione composta (tutti gli elementi tra parentesi graffe) all'interno di una nuova sezione di codice che inizializza il contesto di attivazione come indicato di seguito:
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);
}
}
Il codice precedente viene eseguito prima dell'attivazione di qualsiasi coclasse. Il codice legge semplicemente il file manifesto dell'assembly (il cui nome è hardcoded in questo esempio, ma deve corrispondere a qualsiasi assembly che si desidera caricare in modo dinamico) in un contesto di attivazione che viene quindi attivato (ad esempio, rende corrente). Da questo punto in poi l'attivazione delle coclassi avviene come prima. È ora possibile rimuovere client.exe.manifest.
Un'alternativa all'API del contesto di attivazione diretta, ma disponibile solo in Windows Server 2003, è l'oggetto Microsoft.Windows.ActCtx.
Inutile dire, c'è molto di più per l'API del contesto di attivazione di quanto ho mostrato qui e puoi trovare un collegamento alla documentazione completa dell'API nella sezione Ulteriori di lettura.
Risoluzione dei problemi
Come si è visto, l'attivazione senza registrazione dei componenti COM non richiede codice speciale nel server o nel client. Tutto ciò che è necessario è una coppia corrispondente di file manifesto.
Ti suggerisco di affrontare il tuo sviluppo senza registrazione nel modo in cui viene eseguita questa procedura dettagliata. In particolare: prima di tutto arrivare a uno stato noto visualizzando il client che lavora con un server registrato; quindi annullare la registrazione del server e verificare che il messaggio di errore sia quello previsto; e infine, risolvere la situazione creando e distribuendo i file manifesto. In questo modo, i tentativi di risoluzione dei problemi relativi all'attivazione senza registrazione saranno limitati alla struttura dei file manifesto e all'incorporamento corretto del manifesto dell'assembly se si sceglie di farlo.
Durante la risoluzione dei problemi COM senza registrazione, il Visualizzatore eventi in Windows Server 2003 è un amico. Quando Windows XP o Windows Server 2003 rileva un errore di configurazione, viene in genere visualizzata una finestra di messaggio di errore intitolata per l'applicazione avviata e contenente il messaggio "L'applicazione non è riuscita ad avviare perché la configurazione dell'applicazione non è corretta. La reinstallazione dell'applicazione potrebbe risolvere il problema." Consiglio che ogni volta che viene visualizzato questo messaggio si riproduce il problema in Windows Server 2003, consultare il registro eventi di sistema e cercare gli eventi dall'origine SideBySide. Il motivo per cui non suggerisco di esaminare il registro eventi di Windows XP in questi casi è che conterrà invariabilmente un messaggio come "Genera contesto di attivazione non riuscito per [percorso]\[nome file applicazione]. Manifesto. Messaggio di errore di riferimento: l'operazione è stata completata correttamente", che non consente di identificare il problema.
Gli schemi dei vari file manifesto sono documentati in Platform SDK sotto l'intestazione Riferimento ai file manifestoe lo strumento di convalida dello schema Manifestchk.vbs è disponibile, quindi qui chiamerò solo alcuni punti rilevanti per la procedura dettagliata. Esaminiamo prima di tutto il file manifesto dell'assembly. Per un esempio, tornare al passaggio 7.
Si ricorderà che, nel com senza registrazione senso, un assembly è un'idea astratta con cui si associano uno o più file fisici tramite il contenuto del manifesto dell'assembly . Il nome dell'assembly viene visualizzato in tre posizioni e deve essere identico in ognuno: nel nome
Se SideBySide.dll fosse stato un componente basato su .NET Framework, sarebbe stato necessario incorporare il file manifesto dell'assembly nell'assembly SideBySide come risorsa Win32 (e il file manifesto sarebbe stato denominato dopo l'assembly .NET, ovvero SideBySide.manifest). Tuttavia, a causa della sequenza di ricerca del caricatore di assembly, per i componenti COM nativi è facoltativo per incorporare il manifesto nel modulo. Prima che il caricatore di assembly cerchi [AssemblyName].manifest, cerca [AssemblyName].dll e cerca una risorsa Win32 di tipo RT_MANIFEST. La configurazione all'interno della risorsa deve avere un
Tuttavia, se viene trovato [AssemblyName].dll ma non non contenere un manifesto corrispondente, il meccanismo di caricamento dell'assembly si arresta e non continua a cercare [AssemblyName].manifest. Al momento della stesura di questo articolo, questo è vero del caricatore di assembly in Windows XP (che in questa circostanza visualizzerà il suo consueto messaggio che indica che la configurazione dell'applicazione non è corretta), ma non in Windows Server 2003. In Windows Server 2003, la ricerca continua e trovare il file manifesto anche se corrisponde al nome di un modulo. Tuttavia, vi invito a non dipendere da questo comportamento. Invece, per garantire il supporto coerente di entrambe le piattaforme, è consigliabile incorporare il manifesto dell'assembly nell'assembly come risorsa RT_MANIFEST ogni volta che possibile. Se non è fattibile, è necessario assegnare al file manifesto dell'assembly un nome diverso da quello di qualsiasi modulo nella stessa cartella. In alternativa, posizionare il componente COM in una cartella figlio della cartella del manifesto dell'assembly e fare riferimento a questo percorso figlio nell'elemento
L'elemento assemblyIdentity
L'elemento file
L'elemento comClass ha un solo attributo obbligatorio: clsid. Se l'applicazione tenta di attivare una coclasse non registrata il cui CLSID non è elencato in un elemento comClass nel manifesto dell'assembly, CoCreateInstance restituirà un valore HRESULT con il valore REGDB_E_CLASSNOTREG (0x80040154), il testo del messaggio per il quale è "Classe non registrata".
Come ho detto, i typelib e
comInterface[External]ProxyStub elementi sono necessari nel caso in cui il client e il server esistano in appartamenti diversi, in modo che gli errori seguenti possano essere visualizzati solo quando questi elementi vengono elaborati. Gli errori di configurazione in questi elementi causano CoCreateInstance per restituire un valore HRESULT corrispondente ai messaggi "Libreria non registrata", "Errore durante il caricamento della libreria dei tipi/DLL" o "nessuna interfaccia supportata". Se viene visualizzato uno di questi messaggi, controllare i GUID e assicurarsi che siano presenti tutti gli attributi obbligatori. Lo schema del file manifesto è disponibile in Platform SDK.
Si esaminerà ora il file manifesto dell'applicazione. Per un esempio, tornare al passaggio 6. Il manifesto dell'applicazione deve essere denominato nel formato [nomefile applicazione].manifesto. Quindi, nella procedura dettagliata è stato denominato client.exe.manifest per renderlo chiaro che deve essere letto ogni volta che client.exe viene caricato in un processo. Se questa operazione non viene eseguita correttamente, CoCreateInstance restituirà un valore HRESULT con il valore REGDB_E_CLASSNOTREG (0x80040154), il testo del messaggio per il quale è "Classe non registrata".
L'elemento più importante nel manifesto dell'applicazione è l'elemento dependentAssembly/assemblyIdentity. Questo elemento è un riferimento a quello equivalente nel manifesto dell'assembly e i due devono corrispondere esattamente. Un buon modo per assicurarsi che lo facciano è copiare l'elemento dal manifesto dell'assembly e incollarlo qui. Se esiste alcuna differenza, verrà visualizzato il messaggio seguente nel registro eventi di sistema di Windows Server 2003: "L'identità del componente trovata nel manifesto non corrisponde all'identità del componente richiesto".
Conclusione
COM senza registrazione è una tecnologia che libera i componenti COM da una dipendenza dal Registro di sistema di Windows e di conseguenza libera le applicazioni che le utilizzano dalla necessità di server dedicati. Consente alle applicazioni con dipendenze da versioni diverse dello stesso componente COM di condividere un'infrastruttura e di caricare le varie versioni dei componenti COM affiancate in un'eco del meccanismo di distribuzione e controllo delle versioni di .NET Framework.
Questo articolo illustra una dimostrazione dell'attivazione senza registrazione di componenti COM nativi da parte di applicazioni client native scritte sia in Visual C++ che in Visual Basic 6.0 e da un client gestito. Illustra alcune delle modalità di funzionamento del meccanismo e sottolineato alcuni possibili errori di configurazione e come risolverli.
Altre informazioni
- Registration-Free l'attivazione di . componentiNET-Based: procedura dettagliata
- applicazioni isolate e assembly side-by-side
- schema del file manifesto
- uso dell'API contesto di attivazione
Informazioni sull'autore
Steve White è un consulente per lo sviluppo di applicazioni che lavora nel team Premier Support for Developers di Microsoft UK. Supporta lo sviluppo di clienti con Visual C#, Windows Form e ASP.NET. Il suo blog ha maggiori informazioni sui suoi interessi in musica, visualizzazioni e programmazione.
Leslie Muller è un technologo con il team Research & Development di Credit Suisse First Boston. Leslie ha 12 anni di esperienza come sviluppatore e architetto tecnico, lavorando in ambienti come servizi finanziari, startup tecnologiche, automazione industriale e difesa. Quando non programma o fa ricerche ama sciare, hockey su ghiaccio e quando possibile fare cose leggermente folli con veicoli motorizzati in ambienti estremi come Islanda o le Rockies.