J'ai des applications (certaines natives, d'autres .NET) qui utilisent des fichiers manifestes afin de pouvoir être déployées de manière totalement isolée , sans nécessiter d'enregistrement COM global. Par exemple, la dépendance sur le serveur dbgrid32.ocx com est déclarée comme suit dans le fichier myapp.exe.manifest qui se trouve dans le même dossier que myapp.exe:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity type="win32" name="myapp.exe" version="1.2.3.4" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" />
</dependentAssembly>
</dependency>
</assembly>
Le dbgrid32.ocx est déployé dans le même dossier, avec son propre fichier dbgrid32.ocx.manifest:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity type="win32" name="dbgrid32.ocx" version="5.1.81.4" />
<file name="dbgrid32.ocx">
<typelib
tlbid="{00028C01-0000-0000-0000-000000000046}"
version="1.0"
helpdir=""/>
<comClass progid="MSDBGrid.DBGrid"
clsid="{00028C00-0000-0000-0000-000000000046}"
description="DBGrid Control" />
</file>
</assembly>
Tout cela fonctionne bien, mais la maintenance manuelle de ces fichiers manifestes est un peu pénible. Existe-t-il un moyen de générer ces fichiers automatiquement? Idéalement, je voudrais simplement déclarer la dépendance de l'application sur une liste de serveurs COM (natifs et .NET), puis laisser le reste être généré automatiquement. C'est possible?
Réponses:
Il semble que la solution parfaite n'existe pas encore. Pour résumer quelques recherches:
Créer mon manifeste ( lien )
Cet outil analyse un projet VB6 pour rechercher les dépendances COM, mais il prend également en charge la déclaration manuelle des dépendances COM à liaison tardive (c'est-à-dire celles utilisées via CreateObject).
Fait intéressant, cet outil met toutes les informations sur les dépendances dans le manifeste de l'application. L'exe d'application et ses dépendances sont décrits comme un seul assembly composé de plusieurs fichiers. Je n'avais pas réalisé avant que c'était possible.
Cela semble être un très bon outil, mais à partir de la version 0.6.6, il présente les limitations suivantes:
Je n'ai pas testé s'il prend en charge les bibliothèques .NET com.
regsvr42 ( lien codeproject )
Cet outil de ligne de commande génère des fichiers manifestes pour les bibliothèques COM natives. Il invoque DllRegisterServer, puis espionne l'auto-enregistrement à mesure qu'il ajoute des informations dans le registre. Il peut également générer un manifeste client pour les applications.
Cet utilitaire ne prend pas en charge les bibliothèques .NET COM, car elles n'exposent pas une routine DllRegisterServer.
L'utilitaire est écrit en C ++. Le code source est disponible.
mt.exe
Une partie du SDK Windows (peut être téléchargé à partir de MSDN ), que vous avez déjà si vous avez installé Visual Studio. Il est documenté ici . Vous pouvez générer des fichiers manifestes pour les bibliothèques COM natives avec comme ceci:
Vous pouvez générer des fichiers manifestes pour les bibliothèques .NET COM comme ceci:
Cependant, il y a quelques problèmes avec cet outil:
<runtime>
et des<mvid>
éléments qui doivent être dépouillés avant que les manifestes fonctionnent réellement.Peut-être que les futures versions du SDK amélioreront cet outil, j'ai testé celui du SDK Windows 6.0a (vista).
la source
Avec la tâche MSBuild GenerateApplicationManifest, j'ai généré un manifeste sur la ligne de commande identique au manifeste généré par Visual Studio. Je soupçonne que Visual Studio utilise le GenerateApplicationManifest pendant la génération. Voici mon script de construction qui peut être exécuté à partir de la ligne de commande en utilisant msbuild "msbuild build.xml"
Merci à Dave Templin et à son message qui m'a indiqué la tâche GenerateApplicationManifest et la documentation supplémentaire de MSDN sur la tâche .
build.xml
la source
Make My Manifest (MMM) est un bon outil pour ce faire. Il est également possible d'écrire un script pour traiter tous vos fichiers DLL / OCX à l'aide de mt.exe pour générer un manifeste pour chacun d'eux, puis les fusionner tous ensemble. MMM est généralement meilleur / plus facile, car il gère également de nombreux cas spéciaux / étranges.
la source
Vous pouvez utiliser le spin off Unattended Make My Manifest pour générer des manifestes directement dans des builds automatisés. Il utilise un fichier de script pour ajouter des composants COM dépendants. Ceci est un extrait de l'exemple d'ini avec les commandes disponibles:
Il fonctionnera sous Windows 32 ou 64 bits.
la source
Pour remplir les ProgID que mt.exe n'inclut pas, vous pouvez appeler
ProgIDFromCLSID
pour les rechercher dans le registre. Cela nécessite une inscription COM traditionnelle avant de terminer le fichier manifeste, mais par la suite, le fichier manifeste sera autonome.Ce code C # ajoute les ProgID à toutes les classes COM dans un manifeste:
var manifest = XDocument.Load(fileName); var namespaceManager = new XmlNamespaceManager(new NameTable()); namespaceManager.AddNamespace("s", "urn:schemas-microsoft-com:asm.v1"); foreach (var classElement in manifest.XPathSelectElements("s:assembly/s:file/s:comClass", namespaceManager)) { var clsid = Guid.Parse(classElement.Attribute("clsid").Value); int result = ProgIDFromCLSID(ref clsid, out string progId); if (result != S_OK) throw new COMException($"ProgID lookup failed for {clsid}.", result); classElement.SetAttributeValue("progid", progId); } manifest.Save(fileName);
Le code repose sur ces définitions d'interopérabilité:
[DllImport("ole32.dll")] static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID); const int S_OK = 0;
la source