Domanda

Stiamo adattando il nostro cliente lato applicazione relativamente complicata (ActiveX / .NET / Delphi / C ++ / COM) da utilizzare per raggiungere SxS distribuzione non admin e l'isolamento da versioni precedenti del nostro prodotto.

Siamo stati in grado di raggiungere questo obiettivo per quasi tutti i nostri componenti in proc come il nostro ui .net, Delphi ui, ei server COM che usiamo in proc componendo un file manifesto che descriveva tutte le librerie utilizzate dal nostro processo, senza registrazione sul client di uno qualsiasi dei componenti (quasi).

E qui viene la parte quasi: Al momento, i nostri invoca dell'applicazione (da esso è c ++ porzione) un fuori di server di proc ActiveX (Delphi ActiveX EXE), che a sua volta si invoca un altro insieme di fuori di server ActiveX proc (plugin di terze parti, qualsiasi cosa va qui, Delphi, C ++, qualsiasi cosa finché è fuori proc EXE ActiveX e implementa le nostre interfacce).

Come sappiamo SxS non supporta ActiveX di server proc. E non possiamo usare questi oggetti come nel server proc com nel nostro processo principale, perché ciò richiederebbe una riscrittura della nostra applicazione e anche peggio, una rottura della nostra API fronte pubblico che viene utilizzato da strumenti di terze parti e fornitori, un'API spezziamo che non possiamo permettere.

Abbiamo inciampato su questo articolo che descrive come IHTMLDocument2 può essere estratto da un Internet Explorer finestra in esecuzione in un processo separato. Il che ci ha fatto pensare di questo approccio:

Vorremmo creare un secondario applicazione satellitare / processo che verrà eseguito l'ActiveX come nel server di processo. Poi useremo LresultFromObject e ObjectFromLresult per trasferire un riferimento dell'oggetto ActiveX dal satellite applicazione per il processo di applicazione principale. L'applicazione satellitare avrà proprio file manifesto è di che permetterà l'esecuzione in modalità SxS.

Lo stesso approccio sarà presa per comunicare tra questo Delphi EXE ActiveX e il terzo AciveX EXE Plugin

C'è una soluzione alternativa, che per il momento non preferiamo rispetto alla soluzione sopra proposta, che è quello di utilizzare .NET Remoting e .net com classi proxy per aprire il canale di comunicazione tra i due processi, traducendo la richiesta com a servizi remoti .net, e di nuovo al COM sul secondo processo.

Così qui viene la domanda:

  1. Che ne pensate di questo approccio?
  2. Non si vede una soluzione migliore al problema?
È stato utile?

Soluzione

E 'possibile fare. Cosa è necessario:

  • Una domanda ha bisogno di avviare un server stesso, piuttosto che fare affidamento su COM per farlo. Non è necessario l'indirezione extra fornito dal Registro di sistema, basta usare CreateProcess ().
  • Un server dovrebbe registrare le sue fabbriche di classe nel suo metodo main () con CoRegisterClassObject ().
  • Importante: il CLSID che utilizza per ogni stabilimento deve essere modificato per essere unico per ogni istanza di servizio. Questo assicura che il client si connette al server corretto. Ho semplicemente XOR l'ID di processo con un CLSID classe factory. Il cliente conosce l'ID del processo pure in modo da può fare la stessa alterazione.
  • L'applicazione dovrebbe chiamare CoCreateInstance () in un ciclo con una chiamata di sonno () per attendere che la fabbrica oggetto di apparire. Non dichiarare il fallimento fino a quando almeno 60 secondi sono passati (che mi bit).
  • Sia l'applicazione e il server hanno bisogno di un manifesto che contiene un elemento <file> per ogni proxy / stub DLL e <comInterfaceExternProxyStub> elementi per ogni interfaccia che è remoto.

Altri suggerimenti

Alex,

nobugz è giusto, è possibile accedere alla tabella Running Object per creare un'istanza di un oggetto COM da un processo attualmente in esecuzione del vostro Delphi automazione exe.

Comunque ho trovato un grosso problema che non posso spiegare. Posso accedere solo l'oggetto tramite il metodo variante spedizione quando si lavora in questo modo.

In sostanza se il mio X exe attivo non è registrato, ottengo un errore "Interfaccia non supportata" se provo ad esempio l'oggetto tramite interfacce ad esempio:

WebUpdate: IAutomation;

WebUpdate: = CoAutomation.Create; <- Errore non funzionerà


WebUpdate: Variante;

WebUpdate: = CreateOleObject ( 'WebUpdate.Automation'); <- funziona bene

Se mi iscrivo alla x exe attivo utilizzando regserver il problema va via !!

Go Figure!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top