Registration-Free Activation of .NET-Based Components: A Walkthrough (Procedura dettagliata per l'attivazione senza registrazione di componenti basati su .NET)
Steve White
Supporto premier per sviluppatori, Microsoft UK
Leslie Muller
Sviluppo globale della ricerca & IT, Credit Suisse First Boston
Luglio 2005
Riepilogo: Microsoft Platform SDK esegue un ottimo lavoro per documentare gli argomenti delle applicazioni isolate e degli assembly side-by-side. Tuttavia, non tutti equivalgono a questo argomento con quello dell'attivazione gratuita della registrazione dei componenti COM. Com gratuito per la registrazione è una funzionalità di piattaforma di grande interesse per le aziende con server e applicazioni bloccate isolate sulle infrastrutture condivise. Questo articolo illustra un esempio di lavoro dell'attivazione gratuita della registrazione di un componente basato su .NET Framework dai client nativi tramite interoperabilità COM. (11 pagine stampate)
Si applica a:
Microsoft Windows Server 2003
Microsoft Windows XP Service Pack 2
Microsoft .NET Framework versione 1.1
Microsoft Visual Studio .NET 2003
Microsoft Visual Basic 6.0
Scaricare l'esempio che accompagna questo articolo, MSDNRegFreeNet.msi.
Contents
Introduzione
terminologia COM Registration-Free
Esecuzione dell'esempio
Creazione di un assembly .NET come server COM
Compilazione del client
attivazione Registration-Free
Risoluzione dei problemi
Conclusione
Altre informazioni
Introduzione
Com gratuito per la registrazione è un meccanismo disponibile nelle piattaforme Microsoft Windows XP (SP2 per i componenti basati su .NET Framework) e Microsoft Windows Server 2003. Come suggerisce il nome, il meccanismo consente una facile distribuzione (ad esempio XCOPY) dei 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, è un contesto di attivazione che fornisce le informazioni di associazione e attivazione necessarie per il runtime COM. Non è necessario alcun codice speciale nel server COM o nel client, a meno che non si scelga di evitare l'uso dei file creando contesti di attivazione autonomamente usando l'API di contesto di attivazione.
In questa procedura dettagliata si creerà un semplice assembly .NET e lo utilizzerà, sia registrato che non registrato, dai client COM nativi scritti in Visual C++ e Visual Basic 6.0. È possibile scaricare il codice sorgente e gli esempi e vederli immediatamente in azione oppure seguire la procedura dettagliata e compilarli manualmente.
terminologia COM Registration-Free
Chiunque abbia familiarità con la tecnologia .NET verrà abituati al termine assembly , ovvero un set di uno o più moduli distribuiti, denominati e con versione come unità, con un modulo contenente un manifesto che definisce il set. In COM gratuito per la registrazione, l'assembly dei termini e il manifesto vengono presi in prestito per idee simili nel concetto, ma non identiche alle loro controparti .NET.
La registrazione COM usa l'assembly per indicare un set di moduli PE (ovvero nativi o gestiti) distribuiti, denominati e con versione come unità. La registrazione COM usa il manifesto per fare riferimento ai file di testo con l'estensione manifesto contenente XML, che definisce l'identità di un assembly (manifesto dell'assembly) insieme ai dettagli dell'associazione e dell'attivazione delle relative classi o definisce l'identità di un'applicazione (manifesto dell'applicazione) insieme a uno o più riferimenti all'identità dell'assembly. Un file manifesto dell'assembly è denominato per l'assembly e un file manifesto dell'applicazione è denominato per l'applicazione.
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, troverai una cartella denominata \distribuita. In questa è la versione visual C++ dell'applicazione client (client.exe), il relativo manifesto (client.exe.manifesto) e la versione C# del server COM (SideBySide.dll). Andare avanti ed eseguire client.exe. Il risultato previsto è che client.exe attiverà un'istanza di SideBySideClass (implementata in SideBySide.dll) e visualizzerà il risultato della chiamata al metodo Version che dovrebbe essere simile a "1.0.0-C#".
Creazione di un assembly .NET come server COM
Passaggio 1
In Visual Studio .NET 2003 creare un nuovo progetto dilibreria di classi C# o Visual Basic .NET e chiamarlo SideBySide. Rimuovere AssemblyInfo.[ file cs/vb] dal progetto e implementare una classe come indicato di seguito:
codice 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#";
}
}
}
Codice .NET di Visual Basic
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
Ho scritto i valori GUID, che saranno specifici per il progetto, sotto forma di segnaposto. È necessario usare lo strumento guidgen per generare GUIDD univoci che saranno i rispettivi valori che intendo quando si usano successivamente i segnaposto.
Passaggio 2
In modo che una libreria di tipi venga generata e registrata in fase di compilazione, impostare l'impostazione Register for COM Interop su true.
Passaggio 3
Produrre una compilazione di versione e copiare SideBySide.dll in \distribuito.
Compilazione del client
Il passaggio successivo consiste nel creare il client e per questa procedura dettagliata è possibile compilare un client Visual C++ o un client Visual Basic 6.0 .
Passaggio 4 (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 applicazioneWin32 selezionare la casella di controllo Aggiungi supporto per ATL.
Modificare stdafx.h e aggiungere la riga seguente nella parte superiore del file, immediatamente dopo :#pragma once
#define _WIN32_DCOM
Anche in stdafx.h aggiungere la riga seguente nella parte inferiore del file:
import "[path]\SideBySide.tlb" no_namespace
In questo caso[path] deve essere il percorso relativo alla libreria dei tipi generata quando è stato creato l'assembly SideBySide . Questo percorso varia in genere a seconda che si sia scelto un progetto C# o un progetto .NET di Visual Basic nel passaggio 1.
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;
}
Produrre una compilazione di versione e copiare \release\client.exe in \distribuito.
Passaggio 4 (opzione B: Visual Basic 6.0)
Creare un nuovo progetto EXE Standard di Visual Basic 6.0 . In Esplora progetti selezionare il nodo Project1 e, nella finestra Proprietà, modificare il nome nel client. Scegliere file | Salvare Project Con nome e salvare il file di modulo e il file di progetto in una cartella di pari livello rispetto alla cartella del progetto SideBySide . Scegliere progetto | Riferimenti, selezionare la casella di controllo accanto a SideBySide e scegliere OK.
Fare doppio clic sul modulo principale nella finestra di progettazione moduli e incollare il codice seguente all'interno di Sub Form_Load():
Dim obj As New SideBySideClass
Dim isxs As SideBySide.ISideBySideClass
Set isxs = obj
MsgBox isxs.Version()
Scegliere file | Fai client.exe... e passare alla cartella \distribuita e quindi scegliere OK.
Passaggio 5
Attualmente la cartella \distribuita deve contenere, a parte alcuni file intermedi, solo client.exe e SideBySide.dll; e quest'ultimo sarà stato registrato dal suo processo di compilazione. Per verificare che il server e il client funzionino insieme in queste circostanze normali, eseguire \deployed\client.exe e prendere nota dell'output previsto "1.0.0-C#" o "1.0.0-VB.NET".
Passaggio 6
Questa procedura dettagliata riguarda la registrazione COM gratuita , quindi è ora necessario annullare la registrazione dell'assembly SideBySide . In un prompt dei comandi di Visual Studio 2003 passare alla cartella \distribuita ed eseguire il comando : regasm /u SideBySide.dll
.
Passaggio 7
Per visualizzare l'effetto del passaggio precedente, eseguire di nuovo\deployed\client.exe e verrà visualizzato il messaggio "Classe non registrata" o "Errore di runtime '429': componente ActiveX non può creare l'oggetto". In questa fase è stato frustrato il runtime COM dalla ricerca delle informazioni necessarie nel Registro di sistema, ma è ancora necessario rendere disponibili le informazioni tramite mezzi alternativi. Verrà rimediato nei passaggi seguenti.
attivazione Registration-Free
Passaggio 8
Nella cartella \distribuita 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"
version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
Passaggio 9:
Nella cartella del progetto SideBySide creare un file manifesto dell'assembly privato (un file di testo) e chiamarlo SideBySide.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=" SideBySide"
version="1.0.0.0" />
<clrClass
clsid="{[CLSID_SideBySideClass]}"
progid="SideBySide.SideBySide"
threadingModel="Both"
name="SideBySide.SideBySideClass" >
</clrClass>
</assembly>
L'attività successiva consiste nell'incorporare il file manifesto dell'assembly precedente nell'assembly SideBySide come risorsa Win32. Al momento della scrittura, questo è obbligatorio per Windows XP, ma non per Windows Server 2003. In Windows Server 2003 è possibile uscire semplicemente distribuendo il file manifesto dell'assembly insieme all'assembly. Tuttavia, ti invito a non dipendere da questo comportamento perché potrebbe anche cambiare in un prossimo Service Pack di Windows Server 2003. Per assicurarsi di continuare a supportare entrambe le piattaforme in futuro, seguire i passaggi successivi e incorporare il file manifesto dell'assembly nell'assembly .NET come risorsa Win32. Questa operazione è necessaria solo per l'attivazione gratuita della registrazione di . Componenti basati su NET e non è un requisito per l'attivazione gratuita della registrazione dei componenti COM nativi .
Passaggio 10
Nella cartella del progetto SideBySide creare un file di script di definizione delle risorse (un file di testo) e chiamarlo SideBySide.rc. Incollare quanto segue nel file:
#include <windows.h>
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST SideBySide.manifest
Il file windows.h e le relative dipendenze sono disponibili quando si installa la sezione Platform SDK (Core SDK) o Visual C++. La parte di windows.h necessaria è la definizione:
#define RT_MANIFEST 24
Di conseguenza, il contenuto di SideBySide.rc si risolve in:
1 24 SideBySide.manifest
Tuttavia, è più chiaro e più generale usare le definizioni di macro come indicato.
Passaggio 11
Nella cartella del progetto SideBySide creare un file di comando di compilazione (un file di testo) e chiamarlo build.cmd. Incollare quanto segue nel file:
Per compilare C#:
rc SideBySide.rc
csc /t:library /out:..\deployed\SideBySide.dll
/win32res:SideBySide.res Class1.cs
Per compilare Visual Basic .NET:
rc SideBySide.rc
vbc /t:library /out:..\deployed\SideBySide.dll
/win32resource:SideBySide.res /rootnamespace:SideBySide Class1.vb
Questi comandi fanno prima di tutto per richiamare lo strumento del compilatore di risorse Microsoft Windows da Platform SDK (rc.exe) per compilare lo script di definizione delle risorse dal passaggio 10 in un file di risorse compilato denominato SideBySide.res. Richiama quindi il compilatore C# o Visual Basic .NET per compilare il file di codice sorgente in un assembly e incorporare il file di risorse compilato come risorsa Win32. L'assembly compilato viene scritto nella cartella \distribuita , ma non è registrato per l'interoperabilità COM.
Passaggio 12
In un prompt dei comandi di Visual Studio 2003 passare alla cartella del progetto SideBySide ed eseguire il comando : build
.
Passaggio 13
Per verificare che, grazie ai file manifesto, il client è ancora una volta in grado di attivare la classe SideBySideClass tramite interoperabilità COM, eseguire \deployed\client.exe e notare l'output previsto "1.0.0-C#" o "1.0.0-VB.NET".
Risoluzione dei problemi
Come si è visto, l'attivazione gratuita della registrazione dei componenti basati su .NET Framework non richiede codice speciale nel server o nel client. Tutto ciò che è necessario è una coppia corrispondente di file manifesto, uno dei quali è incorporato nell'assembly .NET come risorsa Win32 di tipo RT_MANIFEST.
Ti suggerisco di approcciarti allo sviluppo gratuito della registrazione in modo che questa procedura dettagliata faccia. In particolare: prima di tutto ottenere 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 file manifesto. In questo modo, i problemi di risoluzione dei problemi relativi all'attivazione gratuita della registrazione saranno limitati alla struttura dei file manifesto e all'incorporamento corretto del manifesto dell'assembly.
Quando si verificano problemi COM gratuiti per la registrazione, l'Visualizzatore eventi in Windows Server 2003 è un amico. Quando Windows XP o Windows Server 2003 rileva un errore di configurazione, in genere verrà visualizzata una finestra di messaggio di errore intitolata per l'applicazione avviata e contenente il messaggio "Questa applicazione non è riuscita ad avviare perché la configurazione dell'applicazione non è corretta. La reinstallazione dell'applicazione può risolvere questo problema." Ti consiglio che ogni volta che visualizzi questo messaggio riproduci il problema in Windows Server 2003, consulta il registro eventi di sistema e cerca gli eventi dall'origine SideBySide . Il motivo per cui non è consigliabile esaminare il registro eventi di XP in questi casi è che invariabilmente conterrà un messaggio come "Genera contesto di attivazione non riuscito per [path]\[nome file applicazione]. Manifesto. Messaggio di errore di riferimento: l'operazione è stata completata correttamente, che non consente di identificare il problema.
Prima di passare alla struttura dei file manifesto, parliamo delle risorse Win32. Come accennato in precedenza, windows.h definisce il simbolo RT_MANIFEST come valore 24, ovvero il valore che il sistema operativo riconoscerà come file manifesto incorporato. Se si dimentica di includere windows.h nello script di definizione delle risorse (file con estensione rc), la compilazione avrà esito positivo e il file manifesto verrà comunque incorporato come risorsa, ma non del tipo corretto. Per verificare che il manifesto sia stato incorporato correttamente, aprire il SideBySide.dll in Visual Studio (File | Apri | File...). Verrà visualizzata una visualizzazione albero che mostra le risorse all'interno del modulo. Nel nodo radice deve essere un nodo denominato RT_MANIFEST sotto il quale deve essere un altro nodo che mostra il numero di risorsa del manifesto (1 nella procedura dettagliata). Fare doppio clic su questo ultimo nodo per visualizzare i dati in una visualizzazione binaria e assegnargli una rapida sanità verificare che sia simile al file manifesto XML. Anche se è binario, i caratteri dell'intervallo ASCII saranno evidenti. Se i dati binari sono mancanti o non sono corretti, verificare che lo script di definizione della risorsa (file rc) faccia riferimento al file manifesto. Se il testo del nodo RT_MANIFEST è tra virgolette, probabilmente si è dimenticato di includere windows.h nello script di definizione della risorsa (file rc).
Ognuno degli errori appena menzionati verrà segnalato nel registro eventi di sistema di Windows Server 2003 con il messaggio: "Impossibile trovare l'assembly dipendente [nome] e l'ultimo errore è stato l'assembly a cui si fa riferimento non è installato nel sistema".
Gli schemi dei vari file manifesto sono documentati in Platform SDK sotto il titolo Riferimento file manifesto e lo strumento di convalida dello schema Manifestchk.vbs è disponibile, quindi qui chiamerò solo alcuni punti pertinenti alla procedura dettagliata. Prima di tutto esaminiamo il file manifesto dell'assembly. Per un esempio, tornare al passaggio 9.
Si ricorderà che, nel senso COM di registrazione, un assembly è un'idea astratta con cui si associano uno o più file fisici tramite il contenuto del file manifesto dell'assembly .
L'elemento assemblyIdentity definisce l'identità dell'assembly. Per. I componenti basati su NET devono corrispondere al nome dell'assembly .NET e quindi al nome del relativo nome, altrimenti verrà visualizzato il messaggio seguente nel registro eventi di sistema di Windows Server 2003: "Impossibile trovare l'assembly dipendente [valoredell'attributo nome] e l'ultimo errore è stato l'assembly a cui si fa riferimento non è installato nel sistema". Tuttavia, l'attributo di versione non deve corrispondere all'assembly .NET AssemblyVersion, né al relativo AssemblyFileVersion, anche se è consigliabile applicare un certo tipo di coerenza.
L'elemento clrClass include solo due attributi obbligatori: nome e clsid. L'attributo namedeve corrispondere allo spazio dei nomi combinato e al nome della classe CLR attivata. In caso contrario, CoCreateInstance restituirà un valore HRESULT con il valore COR_E_TYPELOAD (0x80131522). Questo risultato da un oggetto System.TypeLoadException generato quando il caricatore di tipi non riesce a trovare il tipo CLR richiesto nell'assembly .NET. Una cosa da watch per se l'assembly .NET è scritto in Visual Basic .NET è che si fornisce l'opzione /rootnamespace nella riga di comando al compilatore .NET di Visual Basic (vbc.exe). L'attributo clsid deve corrispondere al CLSID assegnato alla classe CLR attivata tramite guidAttribute. In caso contrario, CoCreateInstance restituirà un HRESULT con il valore REGDB_E_CLASSNOTREG (0x80040154), il testo del messaggio per il quale è "Classe non registrata".
Ora si esaminerà l'attenzione sul file manifesto dell'applicazione. Per un esempio, tornare al passaggio 8. Il manifesto dell'applicazione deve essere denominato nel formato [nome file applicazione].manifesto. Quindi, nella procedura dettagliata è stato denominato client.exe.manifest per renderlo chiaro 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'elementoassemblyIdentitydipendenteAssembly/. Questo elemento è un riferimento a quello equivalente nel manifesto dell'assembly e i due devono corrispondere esattamente. Un buon modo per assicurarsi che sia necessario copiare l'elemento dal manifesto dell'assembly e incollarlo qui. Se si verifica alcuna differenza, verrà visualizzato il messaggio seguente nel registro eventi di sistema di Windows Server 2003: "Identità componente trovata nel manifesto non corrisponde all'identità del componente richiesto".
Conclusione
Com gratuito per la registrazione è una tecnologia che libera i componenti COM da una dipendenza dal Registro di sistema di Windows e di conseguenza libera le applicazioni che li usano richiedendo server dedicati. Consente alle applicazioni con dipendenze di 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 di versione .NET.
Questo articolo illustra come illustrare l'attivazione gratuita della registrazione dei componenti basati su .NET Framework da applicazioni client native scritte in Visual C++ e Visual Basic 6.0. Ha spiegato alcune delle modalità di funzionamento del meccanismo e sottolineato alcuni possibili errori di configurazione e come risolverli.
Altre informazioni
- Attivazione gratuita della registrazione dei componenti COM: procedura dettagliata
- Applicazioni isolate e assembly affiancati
- Schema 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 in Microsoft UK. Supporta i clienti che sviluppano con Visual C#, Windows Forms e ASP.NET. Il suo blog ha altre informazioni sui suoi interessi in musica, visualizzazioni e programmazione.
Leslie Muller è un technlogo con il team di sviluppo di ricerca & presso 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 sta programmando o facendo ricerche si gode di sci, hockey su ghiaccio e quando possibile fare cose leggermente pazze con veicoli motorizzati in ambienti estremi come Islanda o rockies.