Question

Nous adaptons notre côté client application relativement complexe (ActiveX / .net / Delphi / C ++ / COM) à utiliser SxS pour réaliser le déploiement non admin et l'isolement des versions plus anciennes de notre produit.

Nous avons pu atteindre cet objectif pour presque tous nos composants proc comme notre ui .net, Delphi ui, et les serveurs COM que nous utilisons dans proc en composant un fichier manifeste qui décrit toutes les bibliothèques utilisées par notre processus, sans inscription sur le client de l'un des composants (presque).

Et voici la presque partie: À l'heure actuelle, nos invoque l'application (à partir de son c ++ partie) un sur serveur proc ActiveX (Delphi ActiveX EXE), qui à son tour lui-même invoque une autre série de de serveurs proc ActiveX (plugins tiers, quelque chose va ici, Delphi, C ++, quelque chose aussi longtemps qu'il est hors de proc ActiveX EXE et implémente nos interfaces).

Comme nous le savons SxS ne prend pas en charge sur les serveurs proc ActiveX. Et nous ne pouvons pas utiliser ces objets comme dans les serveurs proc com dans notre processus principal car cela nécessiterait une refonte majeure de notre application et même pire, une rupture de notre API public face qui est utilisé par des outils tiers et les fournisseurs, un api rompons que nous ne pouvons pas permettre.

Nous avons trébuché sur cet article qui décrit comment IHTMLDocument2 peut être extrait d'un Internet Explorer fenêtre en cours d'exécution dans un processus séparé. Ce qui nous a fait penser à cette approche:

Nous créerions une application satellite secondaire / processus qui se déroulera l'ActiveX comme dans le serveur de processus. Ensuite, nous allons utiliser LresultFromObject et ObjectFromLresult pour transférer une référence de l'objet ActiveX du satellite l'application du processus d'application principale. L'application par satellite aura son propre fichier manifeste qui lui permettra de fonctionner en mode SxS.

Une même approche sera prise pour communiquer entre ce Delphi ActiveX EXE et le tiers AciveX EXE Plugins

Il existe une solution alternative, qui pour le moment, nous ne préférons pas sur la solution proposée ci-dessus, qui consiste à utiliser .net Remoting et .net com classes proxy pour ouvrir le canal de communication entre les deux processus, en traduisant la demande de com à Remoting .net, et retour à com au deuxième processus.

Alors, voici la question:

  1. Que pensez-vous de cette approche?
  2. Voyez-vous une meilleure solution au problème?
Était-ce utile?

La solution

Il est possible de le faire. Ce qui est nécessaire:

  • Une application doit démarrer un serveur lui-même plutôt que de compter sur COM pour le faire. Vous n'avez pas besoin indirection supplémentaire fourni par le registre, il suffit d'utiliser CreateProcess ().
  • Un serveur doit enregistrer ses usines de classe dans la méthode main () avec CoRegisterClassObject ().
  • Important: le CLSID utilise pour chaque usine doit être modifié pour être unique pour chaque instance de service. Cela garantit que le client se connecte au serveur approprié. Je XOR simplement l'ID de processus avec un CLSID usine de classe. Le client connaît l'ID de processus et peut donc faire la même modification.
  • L'application doit appeler CoCreateInstance () dans une boucle avec un sommeil () pour attendre l'usine d'objets à apparaître. Ne pas déclarer l'échec jusqu'à au moins 60 secondes se sont écoulées (qui me bit).
  • L'application et le serveur ont besoin d'un manifeste qui contient un élément de <file> pour chaque élément de DLL proxy / stub et <comInterfaceExternProxyStub> pour chaque interface déportée.

Autres conseils

Alex,

nobugz est à droite, vous pouvez accéder à la table d'objets en cours pour créer une instance d'un objet COM à partir d'un processus en cours d'exécution de votre automatisation Delphi exe.

Cependant, j'ai trouvé un gros problème que je ne peux pas expliquer. Je ne peux accéder à l'objet via la méthode de répartition variante lorsque vous travaillez de cette façon.

En gros, si mon exe Active X n'est pas enregistré, je reçois une erreur « Interface non pris en charge » si je tente d'exemple l'objet à travers des interfaces par exemple:

WebUpdate: IAutomation;

WebUpdate: = CoAutomation.Create; <- Wont Erreur travail


WebUpdate: Variant;

WebUpdate: = CreateOleObject ( 'WebUpdate.Automation'); <- Travaux fin

Si j'enregistre l'actif x exe en utilisant regserver le problème disparaît !!

Go Figure!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top