Aller au contenu

Chargement automatique des DLLs .NET


(gile)

Messages recommandés

Salut,

 

Je vais essayer de faire ici la synthèse de ce que j'ai pu dire ici ou là pour automatiser le chargement des DLLs .NET pour AutoCAD.

 

 

Préambule

 

Dans tous les cas (excepté l'utilisation de la technique AutoLoader), si la DLL n'est pas placée dans un répertoire des chemins de support il est nécessaire de spécifier le chemin complet.

Dans les exemples suivants, on considèrera que le fichier : "SuperApplication.DLL" est dans un répertoire des chemins de support.

 

Pour AutoCAD 2014 (et plus probablement), il faut aussi ajouter le chemin du répertoire dans les Emplacements approuvés (commande Options... > Fichiers ou variable TRUSTEDPATHS). Si le chemin du dossier se termine par "\...", tous ses sous-dossiers sont également approuvé. Le dossier d'installation AutoCAD et les dossiers de plug-ins (voir Autoloader plus bas), ainsi que tous leurs sous-dossiers, sont toujours implicitement approuvés.

 

Les applications .NET n'ont pas besoin d'être chargées pour chaque document (comme les applications AutoLISP).

 

 

Utilisation du fichier "acad.lsp"

 

Un fichier nommé "acad.lsp" (à créer s'il n'existe pas) placé dans les chemins de support est automatiquement chargé et exécuté au démarrage d'AutoCAD.

Il suffit donc d'ajouter à ce fichier une expression LISP qui charge la DLL avec la commande NETLOAD :

 

(command "netload" "SuperApplication.dll")

 

 

Utilisation de la base de registre

 

Il est possible d'automatiser le chargement d'une DLL .NET en créant quelques clés dans la base de registre.

Cette méthode permet une exécution plus rapide et plus silencieuse du chargement et aussi de pouvoir ne charger l'application qu'au premier appel d'une commande qui y est définie (un peu comme la fonction LISP autoload).

Dans les deux cas, si les clés sont créées dans HKEY_CURRENT_USER le chargement ne se fera que pour l'utilisateur, si elles sont créées dans HKEY_LOCAL_MACHINE (droit d'administrateur requis) le chargement se fera pour tous les utilisateurs.

 

Pour charger l'application systématiquement au démarrage.

  • Créer une clé dans : "HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\\\Applications" avec le nom de l'application (SuperApplication, par exemple).
  • Ajouter 4 valeurs das cette clé :
    • DESCRIPTION (valeur chaîne) : une description de l'application
    • LOADCTRLS (valeur DWORD) : 2 dans ce cas
    • LOADER (valeur chaîne) : le nom du fichier (éventuellement le chemin complet)
    • MANAGED (valeur DWORD) : toujours 1 pour les applications .NET

NetAutoLoad_1.png

 

On peut utiliser la routine LISP suivante pour créer la clé dans HKEY_CURRENT_USER

;;; NetStartupAutoLoad
;;; Inscrit une application .NET dans la base de registre pour
;;; un chargement automatique au démarrage
;;;
;;; Arguments
;;; key       : la clé de l'application (string)
;;; descr     : une description (string)
;;; filename  : le chemin complet de la dll ou le nom du fichier avec l'extension .dll
;;;             si le fichier est dans un chemin de recherche (string)

(defun NetStartupAutoLoad (key descr filename / fullpath)
 (vl-load-com)
 (if (setq fullpath (findfile filename))
   (mapcar
     '(lambda (k v)
        (vl-registry-write
          (strcat "HKEY_CURRENT_USER\\"
                  (vlax-product-key)
                  "\\Applications\\"
                  key
          )
          k
          v
        )
      )
     '("DESCRIPTION" "LOADCTRLS" "LOADER" "MANAGED")
     (list descr 2 fullpath 1)
   )
   (princ (strcat "\nLe fichier \"" filename "\"  est introuvable"))
 )
)

Exemple :

(NetStartupAutoLoad "SuperApplication"
                   "Fait plein de supers trucs dans AutoCAD"
                   "SuperApplication.dll"
)

 

 

Utilisation du mécanisme Autoloader

 

Depuis AutoCAD 2012, il est possible d'utiliser une nouvelle technique de chargement automatique des applications .NET (mais aussi LISP ou ObjectARX). Cette technique facilite grandement le déploiement d'applications elle est recommandée par Autodesk qui l'utilise pour les applications d'Exchange Apps Store.

 

La variable système APPAUTOLOAD gère la manière dont les plug-ins sont chargés. Elle doit avoir le code binaire 2 actif pour que les plug-ins soient chargés au démarrage (défaut 14 = 8 + 4 +2).

 

Il s'agit d'un dossier avec l'extension : .bundle qui doit être placé dans un des répertoires suivant (les chemins sont spécifié avec les variables d'environnement Windows, il suffit de les copier dans la barre d'adresse de l'explorer quel que soit l'OS -XP, 7 ou 8-).

Pour désinstaller l'application, il suffit de supprimer le dossier.bundle.

 


  • Pour l'utilisateur courant :
    • %appdata%\Autodesk\ApplicationPlugins\

    [*]Pour tous les utilisateurs :

    • %allusersprofile%\Autodesk\ApplicationPlugins\
    • %programdata%\Autodesk\ApplicationPlugins\ (Windows 7 ou 8)
    • %programfiles%\Autodesk\ApplicationPlugins\

Le dossier .bundle doit contenir un fichier PackageContents.xml et tous les fichiers nécessaires à l'application (ceux-ci peuvent être répartis dans différents sous-dossiers).

Le fichier PackageContents.xml est un fichier XML qui désigne les différents composants de l'application et décrit comment l'application est chargée.

Ce fichier doit contenir les nœuds suivants :

  • ApplicationPackage
    • CompanyDetails (facultatif)
    • Components
      • RuntimeRequirements
      • ComponentEntry (un noeud par composant)

 

Exemple pour un dossier .bundle de base :

Le dossier SuperApplication.bundle contient

  • le fichier PackageContents.xml
  • le sous-dossier Contents qui contient le fichier SuperApplication.dll
  • le sous-dossier Help qui contient un fichier d'aide SuperApplicationHelp.html

 

Le fichier PackageContents.xml

- dans le nœud ApplicationPackage, l'attribut ProductCode doit être un GUID unique (il y a un générateur de GUID dans les outils de Visual Studio et de nombreux autres sur le net)

- dans le nœud RuntimeRequirement, l'attribut SupportPath permet d'ajouter le dossier .\Help\ aux chemins de recherche.

<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage
   SchemaVersion="1.0"
   AppVersion="1.0"
   Author="SuperMan"
   ProductCode="{Ajouter un GUID unique ici}"
   Name="Super Application"
>
 <CompanyDetails
   Name="SuperMan, Inc."
 />
 <Components>
   <RuntimeRequirements SupportPath="./Help"/>
   <ComponentEntry
     AppName="SuperApplication"
     ModuleName="./Contents/SuperApplication.dll"
   />
 </Components>
</ApplicationPackage>

 

Pour plus de renseignements sur le mécanisme Autoloader, voir l'aide :

A2012 : Guide de personnalisation > Introduction aux interfaces de programmation > Installer et désinstaller des applications plug-in

A2013/2014 (et tant qu'on ne retrouvera pas de table des matières dans l'aide...) Rechercher : ApplicationPlugins

  • Upvote 1

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

merci

une réponse, avant d'avoir pu posé la question.

en effet layerFilter sont des dllS

dans l’embarra que jetait dans l’embarra.

je n'est plus qu'à utiliser cet aide.

merci

et merci

 

 

Nous vivons tous dans le ventre d'un chien géant

Tout le monde le sait mais personne ne dit rien du tout

 

ultra Vomit

Lien vers le commentaire
Partager sur d’autres sites

Merci à vous.

 

On pousse un peu plus loin.

 

Pour ne pas trop ralentir le démarrage d'AutoCAD, il est possible de ne charger les DLLs .NET qu'au premier appel d'une commande définie dans l'application un peu comme avec la fonction LISP autoload.

Ceci n'est faisable automatiquement qu'avec les clés de registre ou le mécanisme Autoloader.

 

 

Utilisation de la base de registre

 

Comme ci-dessus, on choisira la racine pour l'utilisateur courant ou tous les utilisateurs.

  • Créer une clé dans : "HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\\\Applications" avec le nom de l'application (SuperApplication, par exemple).
  • Ajouter 4 valeurs das cette clé :
    • DESCRIPTION (valeur chaîne) : une description de l'application
    • LOADCTRLS (valeur DWORD) : 12 cette fois ci
    • LOADER (valeur chaîne) : le nom du fichier (éventuellement le chemin complet)
    • MANAGED (valeur DWORD) : toujours 1 pour les applications .NET

    [*]Créer une sous clé Commands dans la clé SuperApplication

    [*]Ajouter une valeur de type chaîne pour chaque commande avec comme nom et comme valeur le nom de la commande (CMD1 : CMD1)

    [*]Ajouter une autre sous clé Groups dans la clé SuperApplication (facultatif)

    [*]Ajouter une valeur de type chaîne pour chaque groupe avec comme nom et comme valeur le nom du groupe (SUPER_GROUP : SUPER_GROUP)

 

NetAutoLoad_2.png

 

Ici encore, un petit LISP peut simplifier les choses.

 

;;; NetDemandAutoLoad
;;; Inscrit une application .NET dans la base de registre pour
;;; un chargement automatique au lancement d'une commande
;;;
;;; Arguments
;;; key : la clé de l'application (string)
;;; descr : une description (string)
;;; filename : le chemin complet de la dll (string)
;;; commands : la liste des noms de commande (list)
;;; groups : la liste des noms de groupes de commande ou nil

(defun NetDemandAutoLoad (key descr filename commands groups / regpath)
 (vl-load-com)
 (if (setq fullname (findfile filename))
   (progn
     (mapcar
       '(lambda (k v)
          (vl-registry-write
            (setq regpath (strcat "HKEY_CURRENT_USER\\"
                                  (vlax-product-key)
                                  "\\Applications\\"
                                  key
                          )
            )
            k
            v
          )
        )
       '("DESCRIPTION" "LOADCTRLS" "LOADER" "MANAGED")
       (list descr 12 filename 1)
     )
     (foreach n commands
       (vl-registry-write (strcat regpath "\\Commands") n n)
     )
     (foreach n groups
       (vl-registry-write (strcat regpath "\\Groups") n n)
     )
   )
   (princ (strcat "\nLe fichier \"" filename "\"  est introuvable"))
 )
)

Exemple :

(NetDemandAutoLoad "SuperApplication"
                  "Fait plein de supers trucs dans AutoCAD"
                  "SuperApplication.dll"
                  '("CMD1" "CMD2")
                  '("SUPER_GROUP")
)

 

 

Utilisation du mécanisme Autoloader

 

Ici aussi les commandes peuvent optionnellement appartenir à un groupe de commande. Cela se fait en utilisant les surcharges de constructeur de la classe CommandMethodAttribute qui prennent un argument "group name"

Exemples :

C#

[CommandMethod("SUPER_GROUP", "CMD1", CommandFlags.Modal)]
...
[CommandMethod("SUPER_GROUP", "CMD2", CommandFlags.UsePickSet)]
...

 

VB

<CommandMethod("SUPER_GROUP", "CMD1", CommandFlags.Modal)> _
...
<CommandMethod("SUPER_GROUP", "CMD2", CommandFlags.UsePickSet)> _
...

 

Ici, il suffit d'utiliser un attribut (LoadReasons) du nœud ComponentEntry et de lui mettre la valeur LoadOnCommandInvocation="True" (on ne l'a pas utilisé précédemment parce que sa valeur par défaut est LoadOnAutoCADStartup="True").

 

On va profiter de l'occasion pour compliquer un peu l'application et voir d'autres attributs du PackageContents.

imaginons que notre application doive être chargée indifféremment sur AutoCAD 2012 et 2013 ou ultérieur, cela suppose que nous ayons deux DLLs (SuperApplication_18.dll et SuperApplication_19.dll toujours dans le sous-dossier Contents). On peut avoir aussi en plus un fichier CUIX partiel (à charger au démarrage, lui) dans un sous dossier Resources.

Le dossier SuperApplication.bundle contient

  • le fichier PackageContents.xml
  • le sous-dossier Contents qui contient les fichiers SuperApplication_18.dll et SuperApplication_19.dll
  • le sous-dossier Help qui contient un fichier d'aide SuperApplicationHelp.html
  • le sous-dossier Resources qui contient SuperApplication.cuix

 

Le fichier PackageContents.xml peut ressembler à ça (si les commandes n'appartiennent pas à un groupe, il suffit de ne pas utiliser d'attribut 'GroupName' dans la balise ) :

 

<?xml version="1.0" encoding="utf-8" ?>
<ApplicationPackage
 SchemaVersion="1.0"
 AppVersion="1.0"
 Author="SuperMan"
 ProductCode="[Ajouter un GUID unique ici]"
 Name="Super Application"
Description="Fait plein de supers trucs dans AutoCAD">

 <CompanyDetails
   Name="SuperMan, Inc." />

 <Components Description="2012 parts">
   <RuntimeRequirements
  SupportPath="./Help"
  OS="Win32|Win64"
  SeriesMin="R18.2"
  SeriesMax="R18.2" />

   <ComponentEntry
     AppName="SuperApplication"
     Version="1.0"
     ModuleName="./Contents/SuperApplication_18.dll"
     LoadOnCommandInvocation="True">
     <Commands GroupName="SUPER_GROUP">
       <Command Global="CMD1" />
       <Command Global="CMD2" />
     </Commands>
   </ComponentEntry>

   <ComponentEntry
     AppName="SuperApplication"
     Version="1.0"
       ModuleName="./Contents/SuperApplication.cuix"
     LoadOnAutoCADStartup="True" />
 </Components>

 <Components Description="2013 parts">
   <RuntimeRequirements
  SupportPath="./Help"
  OS="Win32|Win64"
  SeriesMin="R19.0" />

   <ComponentEntry
     AppName="SuperApplication"
     Version="1.0"
     ModuleName="./Contents/SuperApplication_19.dll"
     LoadOnCommandInvocation="True">
     <Commands GroupName="SUPER_GROUP">
       <Command Global="CMD1" />
       <Command Global="CMD2" />
     </Commands>
   </ComponentEntry>

   <ComponentEntry
     AppName="SuperApplication"
     Version="1.0"
       ModuleName="./Contents/SuperApplication.cuix"
     LoadOnAutoCADStartup="True" />
 </Components>
</ApplicationPackage>

 

On note deux nœuds Components, un pour 2012 et un pour 2013. Ils se différencient par :

  • les attributs SerieMin et SerieMax qui indiquent les versions d'AutoCAD pour lesquelles les composants qu'ils contient doivent être utilisés.
  • l'attribut ModuleName du nœud Component qui spécifie la DLL à charger.

Le reste est identique pour ces deux nœuds.

On note aussi les attributs LoadReasons différents pour les nœuds ComponentEntry suivant qu'il s'agit de charger la DLL (LoadOnCommandInvocation="True") ou le CUIX (LoadOnAutoCADStartup="True").

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

J'ajouterai que si la DLL est téléchargée depuis Internet, Windows peut la bloquer pour des raisons de sécurité. On a alors une exception de type System.IO.FileLoadException quand on la charge avec NETLOAD.

 

Pour résoudre le problème, il suffit d'ouvrir une fenêtre d'explorateur Windows, d'aller dans le répertoire où la dll se trouve et de cliquer avec le bouton droit de la souris sur cette dernière pour afficher la fenêtre des propriétés.

 

Si la dll est bloquée, il doit y avoir en bas à droite un bouton Débloquer. Il suffit de cliquer sur ce bouton pour débloquer le fichier.

 

Et aussi : une DLL ne peut pas être déchargée une fois qu'elle a été chargée (http://through-the-interface.typepad.com/through_the_interface/2008/09/tired-of-not-be.html). Si on la charge deux fois, le deuxième appel de NETLOAD ne fait rien.

Maxence DELANNOY

Développement de compléments aux logiciels Autodesk : AutoCAD, Revit, Inventor, Vault, Navisworks... et autres logiciels de CAO

WIIP - http://wiip.fr

Lien vers le commentaire
Partager sur d’autres sites

Merci pour ce résumé, dans un Français impec' !

 

Je pourrai me pencher bientôt sur le sujet bien documenté.

 

Ah si seulement on pouvait revenir en arrière avec cette aide épouvantable qui nous cause tant de peine ; abandonner la 2010.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité