2010-10-19 5 views
10

Sto provando a impostare la registrazione senza COM, ma ho un piccolo problema in quanto un altro oggetto COM potrebbe essere il client.Registrazione gratuita Com e dll manifesta

App.exe -----> COM server/client dll (registrati e non) --------> server COM DLL (non registrato)

Le mie domande è, è possibile creare un manifest per la seconda dll (DLL server/client COM)? Non ho il controllo dell'eseguibile, ma se l'ho fatto, funziona se creo un manifest client per l'eseguibile e un manifest server per la DLL del server COM.

questo è il file manifest per la dll centrale. Ho provato ad incorporarlo e l'ho provato esterno. Ancora non funziona.

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

Su ulteriori indagini, posso ottenere tutto questo per funzionare fino a quando la dll mezzo è anche registrazione gratuita e l'exe ha un manifesto dell'applicazione. Non appena registro la DLL centrale e rilasciamo il manifest dell'applicazione (non ho il controllo di quale exe userà la mia DLL), l'intera operazione smetterà di funzionare.

Se l'exe non ha manifest, il manifest di dll non viene preso in considerazione. Posso provarlo impostando tutto per funzionare. Quindi si commette un errore nel manifesto dell'assembly. Apparirà il solito messaggio:

Impossibile creare il processo: questa applicazione non è stata avviata poiché la configurazione dell'applicazione non è corretta. Reinstallare l'applicazone potrebbe risolvere questo problema.

Se poi cadere il manifesto dell'applicazione, l'applicazione viene caricata (anche se il CoCreateInstance fallisce perché le dipendenze non vengono presi in considerazione)

+0

Perché stai chiamando il gruppo 'comser.dll'? Le informazioni sul manifesto di assemblaggio vengono unite? È molto più facile distribuire un assieme con un nome descrittivo, ad es. "Microsoft.VC90.CRT", che contiene dll con nomi diversi: "msvcr90.dll". Quando si ha a che fare con gli assembly dll diventa più difficile eseguire il debug in quanto un manifest singolo ora ha due scopi: descrivere i contenuti dell'assembly ai consumatori e AND descrivere le dipendenze della dll nell'assembly. –

+0

I nomi sono stati modificati per proteggere gli innocenti! Quelli non sono i veri nomi. Queste sono DLL native e non assembly .NET. – Steve

+0

Inoltre, come funziona "non funziona"? Exe e 2nd dll si caricano e non riescono semplicemente a istanziare il 3o o l'exe o la seconda DLL non si carica completamente? Fare in modo che le cose non vengano effettivamente caricate è un buon passo poiché significa che il sistema sta visualizzando il manifest e registra un errore nel sistema o nell'applicazione, almeno nel registro eventi. Se semplicemente fallisce nella chiamata a CoCreateInstance, probabilmente non riesce a vedere il manifest. –

risposta

5

Basta aggiungere una dipendenza di montaggio alla/manifest cliente di dll server che punta al com server dll.

Ricordare che manifesti di assemblaggio sono diversi da manifesti 'applicazione': Un manifest di assembly descrive un assembly: gli assegna un nome e ne elenca le DLL. Un manifest dell'applicazione è la risorsa incorporata RT_MANIFEST, che descrive le dipendenze dei moduli correnti.

Quindi, in ultima analisi, si avrebbe:

  • app.exe, con un monitor esterno (app.exe.manifest) o RT_MANIFEST incorporato descrivere una dipendenza da un assembly chiamato 'acme.clientserver'
  • acme.clientserver.manifest che descrive un assembly e che elenca "clisrv.dll" come una registrazione gratuita.
  • clisrv.dll, con un esterno (clisrv.dll.2.manifest) o incorporato RT_MANIFEST, descrivendo una dipendenza su un assieme denominato 'acme.server'
  • acme.server.manifest, descrivendo un assieme, elencando serv .dll come registrazione gratuita dll.
  • serv.dll - che a sua volta potrebbe non avere un elenco manifest ancora più assembly dipendenti.

E 'tecnicamente possibile chiamare il gruppo dal nome del dll, e unire sia il montaggio e dll manifestare insieme - il caricatore Win32 supporta questa, ma alcune impostazioni che sono valide in manifesti dell'applicazione non sono validi in manifesta assemblaggio , che può causare il caricamento dell'assembly risultante. Inoltre rende molto difficile firmare digitalmente.

WRT l'exe deve avere un manifest: in genere il manifest di exe imposta il contesto di attivazione predefinito dei processi. Non sono sicuro al 100% di come si comporta Windows quando l'exe non ha manifest, ma sono abbastanza sicuro che i manifesti in DLL saranno ancora elaborati.

Ciò significa che il problema si riduce alla mancanza del supporto per l'isolamento in CoCreateInstance: per qualche motivo, per impostazione predefinita, CoCreateInstance ricerca solo nel contesto di attivazione predefinito per le voci reg free.

Il modo per ignorare che è quello di costruire manualmente il proprio contesto di attivazione, utilizzando il Activation Context API

Il metodo di base sarebbe quella di chiamare:

  • CreateActCtx - per creare un contesto di attivazione dal le DLL manifesto .
  • ActivateActCtx - per attivare il contesto
  • CoCreateInstance - cercherà ora il contesto di attivazione corrente per le voci reg free.
  • DisattivaActCtx - per ripristinare il contesto di attivazione predefinito.

È possibile aggiungere/D ISOLATION_AWARE_ENABLED per avvolgere la maggior parte delle chiamate finestre che vengono effettuate dai contesti di attivazione, per qualche motivo CoCreateInstance non è avvolto:/

+0

non ho l'app.exe.manifest (non ne ho bisogno visto che la versione centrale è registrata). Ho provato ad aggiungere un manifest alla middle dll, ma senza risultato. – Steve

+0

Hai aperto la DLL centrale in un editor di risorse (ad esempio, per esempio Visual Studio) e hai visto se ha una risorsa RT_MANIFEST e cosa contiene? VS visualizza sempre RT_MANIFESTS come esadecimale, quindi è necessario esportarlo per visualizzarlo come testo. –

+0

Ok, fatto. La DLL ha due RT_Manifests, uno che suppongo sia stato inserito dal compilatore (Delphi) che nomina i controlli comuni di Windows come dipendenza, e l'altro 1, quello che ho aggiunto che viene visualizzato sopra. – Steve