Comment traiter ActiveX / OCX aujourd'hui - Tableau de décision conserver / envelopper / remplacer

· Mis à jour le: · · COM, ActiveX, OCX, .NET, Développement Windows, Modernisation

Les projets où il est question d’ActiveX / OCX ont généralement une ambiance un peu pesante.

  • Une application VB6 ou un vieux C++ / MFC est encore en service actif
  • Le SDK d’un équipement industriel ou d’un instrument de mesure n’est fourni qu’en OCX
  • Le Web interne suppose ActiveX et ne parvient pas à sortir du mode IE
  • On veut passer du 32 bits au 64 bits, mais un seul OCX fait de la résistance

Cela dit, ici, « c’est vieux, donc on jette tout » comme « ça fonctionne, donc on le conserve éternellement » sont deux réponses tout aussi négligentes. Ce qui compte, c’est de distinguer si cet ActiveX / OCX est un simple composant d’interface, ou une surface frontière porteuse de spécifications métier ou d’équipement.

Dans cet article, nous organisons, dans un ordre qui facilite la décision, lequel de conserver, envelopper ou remplacer choisir lorsqu’on rencontre de l’ActiveX / OCX.

Les cas visés sont par exemple les suivants.

  • Des applications de bureau existantes de la famille VB6 / MFC / WinForms
  • Une migration progressive vers C# / .NET
  • Des écrans hérités impliquant WebBrowser / le mode IE
  • Des applications Windows contenant des contrôles ActiveX fournis par un éditeur

Sommaire

  1. La conclusion d’abord (en une ligne)
  2. Ce que cet article entend par ActiveX / OCX
  3. Le tableau de décision à consulter en premier
    • 3.1. Vue d’ensemble
    • 3.2. Le choix de conserver
    • 3.3. Le choix d’envelopper
    • 3.4. Le choix de remplacer
    • 3.5. La dépendance au navigateur est une catégorie à part
  4. Les points qui faussent facilement la décision
    • 4.1. S’agit-il d’un composant d’interface, ou d’un composant porteur de spécifications ?
    • 4.2. 32 bits / 64 bits et les frontières de processus
    • 4.3. Enregistrement, distribution, droits, licences
    • 4.4. STA / boucle de messages / callbacks
    • 4.5. Avez-vous des tests ? Pouvez-vous observer le comportement ?
  5. Recommandations selon les cas typiques
    • 5.1. Une application de bureau interne encore stable aujourd’hui
    • 5.2. Vous voulez faire passer un OCX 32 bits côté 64 bits
    • 5.3. Des écrans reposant sur IE / WebBrowser
    • 5.4. Un ActiveX porteur de contrôle d’équipement ou de spécifications propriétaires
  6. Anti-patterns courants
  7. Liste de contrôle pour démarrer une migration
  8. Guide de choix rapide
  9. Ce type de sujet se prête bien à ces consultations
  10. Résumé
  11. Références

1. La conclusion d’abord (en une ligne)

  • Quand vous voyez de l’ActiveX / OCX, le premier critère à juger n’est pas « est-ce ancien ? » mais ce que ce composant a pris en charge
  • S’il s’agit d’un simple composant d’interface, le remplacement est relativement facile
  • S’il porte du contrôle d’équipement, des rapports, des formats de fichiers propriétaires ou des années d’habitudes d’exploitation, il est plus sûr de commencer par l’envelopper plutôt que de le réimplémenter d’un coup
  • S’il tourne de façon stable sur le bureau et que le périmètre de changement est restreint, conserver est aussi une décision tout à fait valable
  • La dépendance à ActiveX dans le navigateur peut être maintenue en vie, mais son avenir est mince, donc mieux vaut la considérer avec le remplacement comme priorité
  • On ne peut pas charger un OCX 32 bits tel quel dans un processus 64 bits. Ce n’est pas quelque chose que la bonne volonté peut franchir
  • L’enregistrement, les DLL dépendantes, les droits administrateur, les licences, STA / MTA - les frictions en dehors de l’implémentation ont tendance à être les points difficiles
  • « On réécrit tout, pour voir » et « on gèle tout par peur » ont tous deux un taux d’incidents élevé

En résumé, l’ordre de la décision est le suivant.

  1. Que porte cet OCX ?
  2. A-t-il besoin de tourner dans le même processus ?
  3. Le 32 bits / 64 bits, l’enregistrement ou la dépendance au navigateur vont-ils poser problème ?
  4. Faut-il construire une frontière testable avant de remplacer ?

Vu dans cet ordre, les choses deviennent nettement plus faciles à organiser.

2. Ce que cet article entend par ActiveX / OCX

Fixons d’abord la façon dont les mots sont utilisés dans cet article.

Terme Sens dans cet article
COM Le modèle de composants binairement compatible de Windows. Le socle des interfaces publiques, de l’enregistrement, de l’Apartment Model, etc.
ActiveX / OCX En pratique, souvent utilisé pour désigner globalement les contrôles basés sur COM et leurs actifs environnants. Cela inclut en particulier, le plus souvent, les contrôles d’interface .ocx et les composants intégrés dans IE / un conteneur
Dépendance WebBrowser / de la famille IE Même sans être ActiveX à proprement parler, cela inclut les navigateurs intégrés et les intégrations qui supposent « la vision du monde d’IE ». Du point de vue de la décision, c’est un problème très proche

À strictement parler, ActiveX et COM ne sont pas la même chose. Mais les points qui posent problème en pratique sont assez similaires.

  • Le 32 bits / 64 bits s’accorde-t-il ?
  • Comment distribuer l’enregistrement et les DLL dépendantes ?
  • Dans quel hôte / conteneur cela tourne-t-il ?
  • STA, boucle de messages, callbacks vont-ils poser problème ?
  • Une dépendance au navigateur subsiste-t-elle ?

Cet article traite ensemble ces points de décision pratiques.

3. Le tableau de décision à consulter en premier

3.1. Vue d’ensemble

Commencez par ce tableau, et l’orientation générale se décide déjà à peu près.

Situation Premier choix Raison
Dépend d’ActiveX dans le navigateur Plutôt remplacer Edge lui-même ne prend pas en charge ActiveX, et le mode IE est positionné comme un maintien en vie
L’OCX tourne de façon stable dans une application de bureau et le périmètre de changement est restreint Plutôt conserver Le coût de le démonter maintenant est souvent plus élevé
On veut moderniser seulement les alentours en .NET, mais le comportement du contrôle reste illisible Plutôt envelopper Il est plus sûr de clarifier d’abord la frontière
On veut mettre tel quel un OCX 32 bits dans un processus 64 bits Envelopper / changer la configuration C’est une frontière que l’in-proc ne peut pas franchir
Utilisé seulement comme composant d’interface, et une alternative existe Plutôt remplacer Un remplacement de surface suffit souvent
Éditeur disparu ; la signature, l’enregistrement ou les DLL dépendantes causent un incident à chaque fois Plutôt remplacer Le coût d’exploitation a émergé comme dette technique
Intègre du contrôle d’équipement, des rapports ou des protocoles propriétaires Plutôt envelopper Tant que le comportement n’est pas figé, le coût du remplacement reste illisible
OuiNonOuiOuiNonNonOuiNonOuiNonVous avez de l'ActiveX / OCXDépendance au navigateur ?Prioriser le remplacementLe mode IE est un maintien en viePrincipalement un composant d'interface ?Une alternative équivalente existe-t-elle ?Envisager le remplacementEnvelopper d'abord et clarifier la frontièrePorte du contrôle d'équipement / des spécifications propriétaires / de la logique de rapports ?Envelopper d'abordrassembler des tests, puis remplacer par étapesEnregistrement / bitness / distribution douloureux ?Revoir la configurationenvisager out-of-proc / pont vers un processus séparé / Reg-Free COMConserver est aussi réaliste

Ci-dessous, examinons chaque cas dans l’ordre.

3.2. Le choix de conserver

Le simple fait qu’il s’agisse d’ActiveX / OCX ne fait pas automatiquement de lui une cible de remplacement. Quand ces conditions sont réunies, conserver est souvent, tout simplement, la solution la moins coûteuse.

  • Le périmètre d’utilisation est fermé, et l’environnement d’exploitation est fixe - distribution interne, livré avec un équipement, etc.
  • Ce contrôle tourne encore de façon stable, et les demandes de changement ne sont pas importantes
  • L’éditeur est encore actif, ou votre équipe peut assurer une maintenance minimale
  • Il ne dépend pas du navigateur et vit entièrement dans un hôte de bureau existant
  • La prémisse 32 bits / 64 bits n’a pas besoin de changer dans un avenir proche

Ce qui compte ici, c’est que conserver ne veut pas dire négliger. Si vous conservez, voici a minima ce qu’il faut mettre en place.

  • Documenter l’OS pris en charge, la bitness, les DLL dépendantes nécessaires et la procédure d’enregistrement
  • Déplacer l’installation, l’enregistrement et la désinstallation vers des scripts ou un installateur, plutôt que vers des notes humaines
  • Préparer un test de fumée sur un environnement propre
  • Concentrer autant que possible les appels au contrôle en un seul endroit, plutôt que de les disperser dans toute l’application

Le pire résultat, c’est de continuer pendant 10 ans avec « ça fonctionne, donc on n’y touche pas », jusqu’à ce que plus personne ne puisse expliquer les prémisses. Plus vous choisissez de conserver, plus rendre les prémisses visibles devient important.

3.3. Le choix d’envelopper

En pratique, ce choix est celui qui représente le plus de travail.

Ici, « envelopper » signifie confiner l’ActiveX / OCX à l’intérieur d’une frontière étroite, et le présenter aux alentours comme une nouvelle API ou un nouveau composant d’écran.

C’est assez efficace. La raison en est que se lancer dans une réimplémentation complète alors que le comportement de l’ancien composant n’est pas encore totalement lisible tend à devenir une double peine : archéologie des spécifications et reproduction des anomalies en même temps. Il est plus sûr de d’abord isoler l’ancien composant et de ne clarifier que la frontière.

Il existe plusieurs formes d’enveloppement.

Façon d’envelopper Cas où c’est adapté Points à surveiller
Hôte WinForms + AxHost / Aximp On veut l’intégrer dans des écrans de bureau existants, ne conserver que quelques écrans STA, événements, dépendances au moment de la conception, licences
Helper EXE 32 bits / COM LocalServer / pont vers un processus séparé On veut se rapprocher du côté 64 bits, isoler les plantages Communication inter-processus, ordre de démarrage, supervision, déploiement
Façade compatible COM du côté .NET On veut conserver les appelants COM existants tout en mettant à jour le contenu IID / CLSID / TLB / méthode d’enregistrement / bitness

Ce qui compte particulièrement, c’est de ne pas copier telles quelles 200 anciennes API lorsqu’on enveloppe. Faire cela revient simplement à importer les contraintes de l’ancien monde directement dans le nouveau code.

Lorsqu’on enveloppe, garder ces points en tête améliore nettement les choses.

  • Utiliser des méthodes à granularité grossière
  • Ne pas laisser le code d’écran toucher directement l’OCX
  • Capturer à la frontière les journaux nécessaires en cas d’échec
  • Décider à la frontière des responsabilités de timeout, de nouvelle tentative et de traduction des exceptions
  • Faire en sorte que le futur remplacement soit lui aussi interchangeable derrière la même interface

Il arrive aussi qu’on veuille ne conserver que le point d’entrée COM du côté .NET, plus récent. Dans ce cas, une configuration réaliste consiste à « mettre à jour le contenu tout en maintenant seulement le contrat COM ». Cependant, le réflexe de l’époque .NET Framework, « un simple RegAsm suffira », ne suffit pas forcément. Le traitement actuel du COM host .NET, du TLB, de la bitness et du Registration-Free COM est plus facile à gérer plus tard si on le conçoit d’abord.

3.4. Le choix de remplacer

Le remplacement convient surtout aux cas où le problème est principalement l’ancienneté de surface.

Dans ces situations, mieux vaut considérer le remplacement comme la priorité.

  • Cet ActiveX n’est utilisé que comme composant d’interface
  • L’éditeur propose un successeur pour .NET / WPF / WebView2
  • La dépendance au navigateur ou la prémisse IE vous freine
  • L’enregistrement, la signature, les droits administrateur ou les réglages de sécurité vous font trébucher à chaque fois
  • Des tests ou des scénarios métier existent pour valider une implémentation alternative

À l’inverse, jeter d’un coup, pour la seule raison qu’il a l’air ancien, un composant portant du contrôle d’équipement ou de la logique de rapports finit généralement en bourbier.

Si vous remplacez, commencez par l’interface.

  • Les grilles
  • Les calendriers
  • Les arbres
  • Les zones d’affichage du navigateur
  • Les simples assistants de saisie

Ceux-là sont comparativement faciles à remplacer. En revanche, certains éléments qui ressemblent à de l’interface ont un contenu dense.

  • Les ActiveX de contrôle d’équipement fournis par un éditeur
  • Les contrôles fusionnés avec l’impression ou la génération de rapports
  • Les contrôles intégrant la lecture/écriture de formats de fichiers propriétaires
  • Les contrôles portant des callbacks COM ou des hypothèses de threading

Se tromper sur cette différence fait s’effondrer d’un coup l’estimation de charge.

3.5. La dépendance au navigateur est une catégorie à part

Ici, c’est vraiment une catégorie à part.

L’ActiveX dans le navigateur, contrairement à l’OCX de bureau, a une raison assez faible d’être prolongé tel quel à l’avenir.

La raison est simple : les plateformes de navigateur modernes n’en font plus leur terrain de jeu principal. Microsoft Edge lui-même ne prend pas en charge ActiveX. Le mode IE, de son côté, utilise le moteur de la famille IE pour les sites configurés, et peut servir de couche de compatibilité pour faire fonctionner certaines fonctionnalités d’IE, y compris ActiveX.

Autrement dit :

  • Un maintien en vie pour le faire tourner maintenant est possible
  • Mais en tant que conception à long terme, l’avenir n’est pas large

C’est cela.

La même chose s’applique au contrôle WebBrowser intégré dans les applications Windows. WebBrowser traîne avec lui la vision du monde d’IE, donc si vous voulez simplement afficher du HTML, il est plus naturel de faire de WebView2 le premier candidat pour tout nouveau travail à partir de maintenant.

Cependant, ce à quoi il faut faire attention ici, c’est que WebView2 n’est pas un composant de remplacement complet pour WebBrowser.

  • Les scripts reposant sur le DOM d’IE
  • Les dépendances à ActiveX
  • Les hypothèses autour de window.external
  • Le comportement reposant sur les zones de sécurité ou l’intranet

Cela ne se transpose pas tel quel. Si vous remplacez, il faut reconcevoir non seulement le moteur de rendu, mais aussi la surface de connexion entre le navigateur et le natif.

4. Les points qui faussent facilement la décision

4.1. S’agit-il d’un composant d’interface, ou d’un composant porteur de spécifications ?

C’est le point le plus important.

Pour une vieille grille ou un vieux calendrier, vérifier la compatibilité visuelle et des événements fait déjà bien avancer les choses. En revanche, un ActiveX portant du contrôle d’équipement, des rapports ou un format propriétaire cache une masse de spécifications derrière son apparence.

Même en ressemblant au même « contrôle à l’écran », il existe en réalité tout cet éventail.

  • Un simple composant d’affichage de liste
  • Un composant qui envoie des commandes à un appareil via un protocole propriétaire
  • Un composant qui gère en interne le timeout, la reconnexion, la retransmission, voire l’absorption d’exceptions
  • Un composant qui porte la compatibilité de formats d’impression ou d’export

Réimplémenter d’un coup ce dernier type finit généralement en projet d’archéologie des spécifications. Ici, mieux vaut envelopper d’abord.

4.2. 32 bits / 64 bits et les frontières de processus

C’est souvent négligé, mais c’est un point assez fondamental.

Un OCX in-proc doit avoir la même bitness que le processus qui le charge. Autrement dit, on ne peut pas charger tel quel un OCX 32 bits dans une application 64 bits.

Les options réalistes à ce moment-là se résument généralement à ce triptyque.

  • Maintenir pour l’instant l’application hôte elle-même en 32 bits
  • La confiner dans un processus 32 bits séparé, et la relier au côté 64 bits via IPC ou COM out-of-proc
  • Remplacer d’abord la dépendance là où elle peut être retirée

Ici, « c’est du Any CPU, donc ça devrait s’arranger » ne fonctionne généralement pas. Même en construisant une façade compatible COM du côté du nouveau .NET, l’apparence du code managé et la bitness réelle du COM host sont deux problèmes distincts. Commencer cela de façon négligée fait apparaître ce cas désagréable où la build passe, mais où rien ne fonctionne chez le client.

4.3. Enregistrement, distribution, droits, licences

Techniquement appelable, mais mort à la distribution. C’est assez fréquent avec ActiveX / OCX.

Voici les points qui deviennent facilement des difficultés.

  • Les prérequis de regsvr32 reposent sur la mémoire d’une personne
  • Le placement des DLL dépendantes est implicite
  • Des droits administrateur sont nécessaires, mais cela n’a pas été formalisé dans la procédure d’exploitation
  • Les licences design-time et runtime d’un contrôle fourni par un éditeur sont distinctes
  • Cela fonctionne sur le poste de développement, mais pas dans un environnement propre

Ces points peuvent arrêter un projet sans qu’une seule ligne de code n’ait été touchée.

Les configurations sans enregistrement ou le déploiement side-by-side peuvent faciliter les choses dans certains cas, mais ce n’est pas une formule magique. Il faut vérifier la compatibilité avec le conteneur et la méthode de distribution.

En résumé, la migration d’ActiveX / OCX relève non seulement de l’implémentation, mais aussi de la conception de la distribution. Reporter ce point vous fait chuter spectaculairement à la fin.

4.4. STA / boucle de messages / callbacks

ActiveX / OCX n’est pas un simple appel de DLL. Il peut porter des hypothèses sur le modèle de threading COM ou la boucle de messages.

Voici en particulier les cas auxquels faire attention.

  • Stable seulement en supposant le thread UI
  • Suppose STA, mais est appelé sans précaution depuis le côté MTA
  • Un callback revient au milieu d’un appel synchrone
  • L’hypothèse sur le thread qui reçoit les événements reste floue

Au début, tout cela se présente sous les traits d’une histoire de fantômes : « ça se fige de temps en temps », « les événements n’arrivent pas parfois ». Mais le fond du problème est généralement une violation de prémisse.

C’est pourquoi, aussi bien pour envelopper que pour remplacer, il vaut mieux fixer d’avance sur quel thread on crée le composant, sur quel thread on l’appelle, et où l’on reçoit les événements.

4.5. Avez-vous des tests ? Pouvez-vous observer le comportement ?

Le remplacement n’est pas difficile seulement parce que le code est ancien. Il est difficile parce qu’il n’existe pas de critère permettant de dire « cela s’est comporté de la même façon ».

Le simple fait d’avoir ces éléments change déjà beaucoup les choses.

  • Des tests de fumée par scénario d’opération
  • Des exemples d’entrées/sorties
  • Des captures d’écran ou des exemples de rapports
  • Des schémas d’erreur et le comportement attendu
  • Des journaux en cas de timeout ou d’équipement non connecté

En particulier lorsque des équipements ou des rapports sont impliqués, il se produit ce phénomène étrange où le comportement réel est plus vrai que le cahier des charges. Sans moyen d’observation ici, le remplacement se transforme en fouille archéologique.

5. Recommandations selon les cas typiques

5.1. Une application de bureau interne encore stable aujourd’hui

La recommandation : plutôt conserver.

Avec des conditions comme celles-ci, il vaut souvent mieux ne pas l’arracher de force.

  • Utilisé uniquement en interne
  • Les postes cibles et l’OS sont raisonnablement fixés
  • Cet OCX n’est utilisé que sur quelques écrans
  • Les demandes de refonte sont faibles, et la durée de vie est prévisible

Cependant, plutôt que de le laisser tel quel, à nu, il vaut mieux, pour plus tard, au moins regrouper les points d’appel.

Autrement dit, la politique est la suivante.

  • Le conserver pour l’instant
  • Mais clarifier uniquement la frontière
  • Faire en sorte que, lorsque le remplacement deviendra nécessaire, on puisse démarrer à partir de là

Cette structure en trois étapes est la plus naturelle.

5.2. Vous voulez faire passer un OCX 32 bits côté 64 bits

La recommandation : envelopper / changer la configuration.

Y aller de front ici mène droit dans le mur. Parce qu’on ne peut pas mettre un OCX 32 bits en in-proc dans un processus 64 bits.

En pratique, une configuration facile à manier consiste à le confiner dans un processus helper 32 bits ou côté LocalServer, et à communiquer avec l’application 64 bits via une API grossière.

OCX 32 bitsHelper 32 bits / LocalServerApplication .NET 64 bitsOCX 32 bitsHelper 32 bits / LocalServerApplication .NET 64 bitsRequête via une API grossièreAppel in-procRésultats / événementsRésultats traduits

Le point ici est de ne pas relayer tel quel chaque méthode fine. Une frontière entre processus devient vite pénible dès qu’on y fait passer un grand nombre d’appels fins.

  • Viser une granularité de l’ordre de 1 opération = 1 requête
  • Mettre en forme les valeurs de retour et les erreurs en unités porteuses de sens
  • Capturer les journaux à la frontière

Avec cette forme en place, remplacer vraiment le contenu plus tard devient aussi plus facile.

5.3. Des écrans reposant sur IE / WebBrowser

La recommandation : prioriser le remplacement.

C’est un domaine où « ça marche maintenant » et « ça reste facile à maintenir plus tard » coïncident difficilement. Le mode IE aide beaucoup pour la compatibilité, mais la prémisse reste malgré tout celle de la famille IE.

C’est pourquoi il est plus clair de séparer la réflexion ainsi.

  • Maintenir en vie via le mode IE pour ne pas arrêter l’activité interne
  • Mais ne pas confondre le maintien en vie avec une conception permanente
  • Choisir la cible de remplacement parmi WebView2, du Web pur, un hybride UI native + Web, etc.

En particulier, si le contrôle WebBrowser n’est utilisé que comme simple visionneuse HTML, la priorité de remplacement est élevée.

En revanche, si l’ActiveX dans le navigateur porte aussi des rôles comme les fichiers locaux, les équipements, la signature ou des add-ons propriétaires, alors ce n’est pas un échange de moteur de rendu, mais une reconception de l’intégration native. Ici, le sujet devient un peu plus lourd.

5.4. Un ActiveX porteur de contrôle d’équipement ou de spécifications propriétaires

La recommandation : envelopper d’abord.

Ce type de composant est plus dense à l’intérieur qu’il n’y paraît. Même si la documentation du SDK est mince, à force de tourner sur le terrain pendant des années, des comportements comme ceux-ci ont pu s’accumuler implicitement.

  • La façon d’attendre en cas d’échec de connexion
  • Les nouvelles tentatives après un timeout
  • L’ordre des événements
  • Des contournements absorbant les particularités du matériel réel
  • L’interprétation des exceptions et des codes d’erreur

Refaire ce type de composant sous prétexte que « c’est vieux de toute façon » fait, avec une forte probabilité, s’enflammer les tests sur le terrain.

C’est pourquoi il est plus sûr de commencer par ceci.

  1. Confiner le composant existant à l’intérieur d’une frontière
  2. Ajouter des journaux pour rendre visible ce qui se passe
  3. Rassembler des scénarios de test et des schémas observés sur le matériel réel
  4. Ensuite seulement, découper le périmètre remplaçable

Ce n’est pas spectaculaire, mais en pratique, c’est ce qui fonctionne le mieux.

6. Anti-patterns courants

Anti-pattern Ce qui est pénible Première correction
Tout réécrire parce qu’il y a de l’ActiveX Des lacunes de spécification et une explosion de charge sont probables D’abord faire l’inventaire et découper les frontières
Vouloir mettre tel quel un OCX 32 bits dans une application 64 bits Impossible en principe Isoler du côté 32 bits, ou changer la configuration
Appeler directement l’API du contrôle depuis tout l’écran Tend à devenir impossible à remplacer Se rabattre sur un adapter / une facade
Exploiter la procédure regsvr32 à la main Des incidents à chaque fois à cause des différences d’environnement Envisager un installateur, des scripts, ou une manifestation
Se rassurer parce qu’il y a le mode IE Facile de confondre maintien en vie et solution permanente Fixer un plan de remplacement et des conditions de fin
Ne pas enregistrer le comportement avant de remplacer Impossible de juger si c’est terminé Rassembler tests de fumée, données d’exemple et journaux

Parmi ceux-ci, trois sont particulièrement fréquents en pratique.

  1. Se précipiter vers une réécriture complète
  2. Sous-estimer le mur de la bitness
  3. Disperser l’API dans toute l’application

Éviter seulement ces trois-là fait déjà nettement baisser le taux d’incidents.

7. Liste de contrôle pour démarrer une migration

Les projets ActiveX / OCX réussissent mieux en faisant d’abord l’inventaire plutôt qu’en se lançant directement dans l’implémentation. L’ordre est généralement le suivant.

  1. Recenser les OCX / DLL utilisés
    • Nom de fichier, version, ProgID, CLSID, éditeur, présence d’une licence
  2. Recenser où ils sont utilisés
    • Écrans, fonctionnalités, rapports, équipements, traitements batch, intégration Office, etc.
  3. Vérifier la bitness et les conditions d’hébergement
    • 32 bits / 64 bits, in-proc / out-of-proc, hypothèse STA, dépendance au navigateur
  4. Vérifier les conditions de distribution
    • Méthode d’enregistrement, DLL dépendantes, droits administrateur, installation silencieuse, reproduction en environnement propre
  5. Construire des tests de fumée
    • Pas seulement le cas nominal, mais aussi les échecs, les cas non connectés et les timeouts
  6. Construire la frontière
    • Adapter, service, facade, pont vers un processus séparé, etc.
  7. Faire un essai sur une petite unité - un écran, une fonctionnalité, un équipement
  8. À partir des frontières qui ont fonctionné, étendre progressivement conserver / envelopper / remplacer

Sauter ces étapes rend difficile, plus tard, d’expliquer ne serait-ce que « ce qui était difficile ».

8. Guide de choix rapide

Situation Premier choix
Interne uniquement, stable, changements faibles Conserver
On veut moderniser seulement les alentours en .NET Envelopper
Le 32 bits / 64 bits entre en collision Envelopper / changer la configuration
Dépendance à IE / WebBrowser / ActiveX dans le navigateur Remplacer
Simple composant d’interface avec une alternative Remplacer
Porte du contrôle d’équipement, des rapports, des spécifications propriétaires Envelopper
Trébuche à chaque fois sur l’enregistrement ou la distribution Envelopper ou remplacer

En cas d’hésitation, distinguer d’abord s’il s’agit d’un composant d’interface ou d’une surface frontière porteuse de spécifications rend le choix beaucoup plus difficile à rater.

9. Ce type de sujet se prête bien à ces consultations

Sur ce thème, la simple clarification de la politique avant de se lancer directement dans le développement fait déjà souvent apparaître de la valeur.

Par exemple, ce genre de consultation convient particulièrement bien :

  • Vous voulez faire l’inventaire pour savoir quel OCX doit vraiment être remplacé
  • Vous voulez d’abord clarifier uniquement les points de blocage 32 bits / 64 bits
  • Vous voulez vous rapprocher de .NET, mais ne conserver que le point d’entrée COM
  • Vous voulez comparer les mesures de maintien en vie et la stratégie de sortie pour un ActiveX dont l’éditeur a disparu
  • Vous voulez voir par où commencer à retirer la dépendance à IE / WebBrowser
  • Vous voulez d’abord séparer en toute sécurité un seul écran, une seule fonctionnalité

Dans les projets ActiveX / OCX, la façon de découper les frontières décide souvent de l’issue avant même l’implémentation. Comme étape préliminaire à une refonte complète, ne serait-ce que partir d’une clarification de l’état actuel, d’une comparaison de configurations et de la conception de l’ordre de migration a déjà beaucoup de sens.

10. Résumé

La façon de traiter ActiveX / OCX n’est pas une décision qui se prend en le détestant simplement parce que c’est ancien.

Il y a d’abord quatre points à regarder.

  1. Ce composant est-il un simple élément d’interface, ou une surface frontière porteuse de spécifications ?
  2. A-t-il besoin de tourner dans le même processus ?
  3. Le 32 bits / 64 bits, l’enregistrement, la dépendance au navigateur ou les licences vont-ils poser problème ?
  4. Peut-on observer le comportement avant de remplacer ?

Une fois ces quatre points clarifiés, on peut à peu près organiser les choses ainsi.

  • Si ça tourne de façon stable et que la durée de vie est prévisible : conserver
  • Si l’on veut moderniser seulement les alentours : envelopper
  • Pour un composant d’interface ou une dépendance au navigateur : remplacer
  • Pour un composant portant une masse de spécifications : envelopper d’abord, puis remplacer par étapes

La technologie héritée n’est pas un objet de moquerie, mais un artefact réel chargé d’histoire et de contrats. Cependant, cohabiter avec cet artefact réel nécessite une conception des frontières.

Une fois que vous parvenez à penser en mélangeant « conserver, envelopper, remplacer », les projets ActiveX / OCX se transforment soudain en problèmes maîtrisables.

11. Références

  • Microsoft Learn: AxHost Class (System.Windows.Forms)
    • https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.axhost
  • Microsoft Learn: Aximp.exe (Windows Forms ActiveX Control Importer)
    • https://learn.microsoft.com/en-us/dotnet/framework/tools/aximp-exe-windows-forms-activex-control-importer
  • Microsoft Learn: How to: Add ActiveX Controls to Windows Forms
    • https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-add-activex-controls-to-windows-forms
  • Microsoft Learn: Expose .NET Core components to COM
    • https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
  • Microsoft Learn: Registration-Free COM Interop
    • https://learn.microsoft.com/en-us/dotnet/framework/interop/registration-free-com-interop
  • Microsoft Learn: Frequently Asked Questions about Microsoft Edge
    • https://learn.microsoft.com/en-us/deployedge/microsoft-edge-frequently-asked-questions
  • Microsoft Learn: What is Internet Explorer (IE) mode?
    • https://learn.microsoft.com/en-us/deployedge/edge-ie-mode
  • Microsoft Learn: WebBrowser Class (System.Windows.Forms)
    • https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.webbrowser
  • Microsoft Learn: Introduction to Microsoft Edge WebView2
    • https://learn.microsoft.com/en-us/microsoft-edge/webview2/
  • KomuraSoft Blog : Les bases pour éviter les blocages avec COM STA/MTA
    • https://comcomponent.com/fr/blog/2026/01/31/000-sta-mta-com-relationship/
  • KomuraSoft Blog : Pourquoi il vaut mieux créer un wrapper C++/CLI pour utiliser une DLL C++ native depuis C#
    • https://comcomponent.com/fr/blog/2026/03/07/000-cpp-cli-wrapper-for-native-dlls/
  • KomuraSoft Blog : Étude de cas COM - Quand on veut appeler une DLL 64 bits depuis une application 32 bits
    • https://comcomponent.com/fr/blog/2026/01/25/002-com-case-study-32bit-to-64bit/

Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.

Ces pages replacent le sujet dans un contexte plus large de services et de décisions.

Cet article est directement lié aux services suivants.

Questions fréquentes

Questions souvent posées lors d’une consultation sur le sujet de cet article.

Peut-on utiliser un OCX 32 bits depuis une application 64 bits ?
Pas en in-proc. Un OCX doit avoir la même bitness que le processus qui le charge : c'est une contrainte de principe qu'aucun réglage de build ne permet de contourner. Les options réalistes sont au nombre de trois : garder pour l'instant l'application hôte elle-même en 32 bits, confiner l'OCX dans un processus 32 bits séparé (helper EXE ou COM LocalServer) et communiquer avec le côté 64 bits via IPC ou COM out-of-proc, ou bien remplacer d'abord la dépendance là où elle peut être retirée. Lorsqu'on fait le pont entre processus, mieux vaut utiliser une API à granularité grossière plutôt que de relayer chaque appel de méthode fin.
Faut-il remplacer un contrôle ActiveX simplement parce qu'il est ancien ?
Pas automatiquement. Le premier critère n'est pas « est-ce ancien ? » mais ce que ce composant a pris en charge. S'il s'agit d'un simple composant d'interface pour lequel une alternative existe, le remplacer est comparativement facile. S'il porte du contrôle d'équipement, de la génération de rapports, des formats de fichiers propriétaires ou des années de comportement opérationnel, il est plus sûr de commencer par l'envelopper derrière une frontière étroite plutôt que de se lancer dans une réimplémentation complète ; et un composant de bureau qui tourne de façon stable avec un périmètre de changement restreint peut raisonnablement être simplement conservé.
Que faire de la dépendance à ActiveX dans le navigateur, ainsi que du mode IE ?
Mieux vaut considérer le remplacement comme la priorité. Microsoft Edge lui-même ne prend pas en charge ActiveX, et le mode IE est positionné comme une couche de compatibilité : il peut donc maintenir les choses en vie pour l'instant, mais il a peu d'avenir en tant que conception à long terme. Pour les applications qui intègrent le contrôle WebBrowser simplement comme visionneuse HTML, WebView2 est le candidat naturel, mais ce n'est pas un remplacement direct : les scripts reposant sur le DOM d'IE, les dépendances à ActiveX, les hypothèses autour de window.external et le comportement lié aux zones de sécurité ne se transposent pas tels quels, si bien que la surface d'intégration native doit être reconçue.
Qu'implique concrètement le fait d'« envelopper » un OCX ?
Envelopper signifie confiner l'ActiveX/OCX à l'intérieur d'une frontière étroite et le présenter au reste de l'application comme une nouvelle API ou un nouveau composant d'interface. Les formes établies incluent un hôte WinForms avec AxHost/Aximp, un helper EXE 32 bits ou un COM LocalServer pour faire le pont via un processus séparé, et une façade compatible COM du côté .NET. La règle la plus importante est de ne pas copier l'ancienne API telle quelle : utiliser des méthodes à granularité grossière, empêcher le code d'écran de toucher directement l'OCX, capturer les journaux et la traduction des erreurs à la frontière, et rendre le futur remplacement interchangeable derrière la même interface.

Profil de l’auteur

Page de présentation de l’auteur de l’article.

Go Komura

Représentant de KomuraSoft LLC

Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.

Retour au blog