У меня есть некоторые приложения (некоторые из них, некоторые из .NET), которые используют файлы манифеста, поэтому их можно развернуть в полной изоляции , не требуя какой-либо глобальной регистрации COM. Например, зависимость от сервера dbgrid32.ocx com объявлена следующим образом в файле myapp.exe.manifest, который находится в той же папке, что и 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>
Dbgrid32.ocx развертывается в той же папке вместе с собственным файлом 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>
Все это работает нормально, но поддерживать эти файлы манифеста вручную немного затруднительно. Есть ли способ автоматически сгенерировать эти файлы? В идеале я просто хотел бы объявить зависимость приложения от списка COM-серверов (как собственных, так и .NET), а затем позволить автоматически сгенерировать остальные. Является ли это возможным?
Ответы:
Похоже, идеального решения пока не существует. Подведем итоги некоторых исследований:
Сделать мой манифест ( ссылка )
Этот инструмент сканирует проект VB6 на предмет зависимостей COM, но он также поддерживает ручное объявление зависимостей COM с поздним связыванием (то есть тех, которые используются через CreateObject).
Что интересно, этот инструмент помещает всю информацию о зависимостях в манифест приложения. Приложение exe и его зависимости описываются как единая сборка, состоящая из нескольких файлов. Раньше я не понимал, что это возможно.
Похоже на очень хороший инструмент, но начиная с версии 0.6.6 он имеет следующие ограничения:
Я не проверял, поддерживает ли он библиотеки .NET com.
regsvr42 ( ссылка на код проекта )
Этот инструмент командной строки создает файлы манифеста для собственных библиотек COM. Он вызывает DllRegisterServer, а затем следит за саморегистрацией, добавляя информацию в реестр. Он также может создавать клиентский манифест для приложений.
Эта утилита не поддерживает библиотеки .NET COM, поскольку они не предоставляют подпрограмму DllRegisterServer.
Утилита написана на C ++. Исходный код доступен.
mt.exe
Часть Windows SDK (можно загрузить с MSDN ), которая у вас уже есть, если у вас установлена Visual Studio. Это задокументировано здесь . Вы можете сгенерировать файлы манифеста для собственных COM-библиотек следующим образом:
Вы можете сгенерировать файлы манифеста для .NET COM-библиотек следующим образом:
Однако с этим инструментом есть некоторые проблемы:
<runtime>
и<mvid>
элементы , которые должны быть удалены перед манифестов на самом деле работает.Возможно, будущие выпуски SDK улучшат этот инструмент, я тестировал его в Windows SDK 6.0a (vista).
источник
С помощью задачи MSBuild GenerateApplicationManifest я создал в командной строке манифест, идентичный манифесту, создаваемому Visual Studio. Я подозреваю, что Visual Studio использует GenerateApplicationManifest во время сборки. Ниже мой сценарий сборки, который можно запустить из командной строки с помощью msbuild "msbuild build.xml".
Спасибо Дэйву Темплину и его сообщению, в котором я указал на задачу GenerateApplicationManifest , а также за дальнейшую документацию MSDN по этой задаче .
build.xml
источник
Make My Manifest (MMM) - хороший инструмент для этого. Также можно написать сценарий для обработки всех ваших файлов DLL / OCX с помощью mt.exe, чтобы сгенерировать манифест для каждого из них, а затем объединить их все вместе. MMM обычно лучше / проще, потому что он также обрабатывает множество особых / странных случаев.
источник
Вы можете использовать дополнительный модуль Unattended Make My Manifest для создания манифестов непосредственно в автоматизированных сборках. Он использует файл сценария для добавления зависимых компонентов COM. Это отрывок из образца ini с доступными командами:
Он будет работать в 32- или 64-битной Windows.
источник
Чтобы заполнить идентификаторы ProgID, которые не включает mt.exe, вы можете позвонить,
ProgIDFromCLSID
чтобы найти их в реестре. Для этого требуется традиционная регистрация COM до завершения файла манифеста, но впоследствии файл манифеста будет самодостаточным.Этот код C # добавляет идентификаторы ProgID ко всем классам COM в манифесте:
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);
Код полагается на эти определения взаимодействия:
[DllImport("ole32.dll")] static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID); const int S_OK = 0;
источник