Сборка и развертывание DLL на Windows: SxS, манифесты и все такое джаз - PullRequest
3 голосов
/ 21 сентября 2008

Начиная с VS 2005, я вижу, что невозможно просто создать dll для среды выполнения MS и развернуть их вместе (http://www.ddj.com/windows/184406482). Я глубоко сбит с толку манифестом, SxS и co: документация MSDN действительно плохая, с циклическими ссылками, особенно потому, что я в большей степени парень из Unix, я нахожу все это неинформативным. Моя основная проблема - связать dll с msvc9 или msvc8: поскольку эти среды выполнения не распространяются повторно, каковы шаги для связывания и развертывания такой dll? В частности, как генерируется манифест (я не хочу mt.exe, я хочу что-то переносимое между компиляторами), как они встраиваются, используются? Что означает параллельная сборка?

В основном, где я могу найти какую-либо спецификацию вместо жаргона MS?

Спасибо всем, кто ответил, это было действительно полезно,

Ответы [ 8 ]

3 голосов
/ 22 сентября 2008

Мы используем простой включаемый файл во всех наших приложениях и DLL-файлах, vcmanifest.h, затем устанавливаем для всех проектов встроенный файл манифеста.

vcmanifest.h

/*----------------------------------------------------------------------------*/

#if _MSC_VER >= 1400

/*----------------------------------------------------------------------------*/

#pragma message ( "Setting up manifest..." )

/*----------------------------------------------------------------------------*/

#ifndef _CRT_ASSEMBLY_VERSION
#include <crtassem.h>
#endif 

/*----------------------------------------------------------------------------*/

#ifdef WIN64
    #pragma message ( "processorArchitecture=amd64" )
    #define MF_PROCESSORARCHITECTURE "amd64"
#else
    #pragma message ( "processorArchitecture=x86" )
    #define MF_PROCESSORARCHITECTURE "x86"
#endif 

/*----------------------------------------------------------------------------*/

#pragma message ( "Microsoft.Windows.Common-Controls=6.0.0.0") 
#pragma comment ( linker,"/manifestdependency:\"type='win32' " \
                  "name='Microsoft.Windows.Common-Controls' " \
                  "version='6.0.0.0' " \
                  "processorArchitecture='" MF_PROCESSORARCHITECTURE "' " \
                  "publicKeyToken='6595b64144ccf1df'\"" )

/*----------------------------------------------------------------------------*/

#ifdef _DEBUG
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' "         \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#else
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif

/*----------------------------------------------------------------------------*/

#ifdef _MFC_ASSEMBLY_VERSION
    #ifdef _DEBUG
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #else
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #endif
#endif /* _MFC_ASSEMBLY_VERSION */

/*----------------------------------------------------------------------------*/

#endif /* _MSC_VER */

/*----------------------------------------------------------------------------*/
3 голосов
/ 22 октября 2008

Самое простое, что нужно сделать: Предполагая установку VS2005 по умолчанию, вы получите путь, подобный следующему:

C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT

Перейдите, возьмите файлы в этой папке для пересылки и поместите файл .manifest И файл msvcr80.dll (как минимум) в папку .exe приложений. Эти файлы, находящиеся в корне вашей установки, должны позволить вашему exe-файлу и всем dll, связанным с ними, работать без сбоев, не прибегая к слиянию модулей, MSI или даже к любому своевременному обнаружению, что среда выполнения не установлена.

2 голосов
/ 21 сентября 2008

Вот запись в блоге , объясняющая рациональное решение SxS crt для VC ++ . Он включает в себя объяснение того, как плохо статически связывать CRT, и почему вы не должны этого делать.

Вот документация о том, как статически связать crt .

2 голосов
/ 21 сентября 2008

Ну, я столкнулся с некоторыми из этих проблем, так что, возможно, некоторые из моих комментариев будут полезны.

  1. Манифест представляет собой файл XML. В то время как VS может сделать и сделает это для вас при компиляции, другое решение - создать файл ресурсов (.rc) и скомпилировать его в скомпилированный файл ресурсов (.res), используя компилятор ресурсов (rc.exe), включенный в VS , Вы захотите запустить командную строку VS из меню инструментов, что приведет к тому, что rc будет в пути, а также к правильной установке различных переменных среды. Затем скомпилируйте ваш ресурс. Полученный файл .res может использоваться другими компиляторами.
  2. Убедитесь, что размер XML-файла манифеста делится на 4. Добавьте пробел в середине, чтобы при необходимости добиться этого. Старайтесь избегать использования символов перед открывающим тегом xml или после закрывающего тега xml. У меня иногда были проблемы с этим. Если вы выполните шаг 2 неправильно, ожидайте получения ошибок конфигурации. Вы можете проверить, является ли это вашей ошибкой, открыв исполняемый файл в редакторе ресурсов (например, devenv.exe) и изучив ресурс манифеста. Вы также можете увидеть пример правильного манифеста, просто открыв встроенный файл, хотя обратите внимание, что dll и exe имеют небольшие различия в том, какой id должен быть предоставлен ресурс.

Возможно, вы захотите протестировать Vista, чтобы убедиться, что она работает правильно.

1 голос
/ 21 сентября 2008

Они являются распространяемыми, и у вас есть распространяемые пакеты в каталоге msvs.

Сборка с выбранной вами средой выполнения, добавьте соответствующий пакет в ваш установщик и не беспокойтесь - он будет работать. Разница в том, что они установлены в другом месте (но именно там ваше приложение будет искать библиотеки).

В противном случае, MSDN или любая другая не слишком старая книга по программированию на Windows c ++.

0 голосов
/ 07 мая 2009

Если вы собираетесь развертывать файлы Microsoft DLLs / .manifest и используете Java JNI, вам нужно будет поместить их в каталог bin вашего JDK / JRE.

Если вы запускаете приложение в JBoss, вам нужно будет поместить их в каталог JBoss / bin.

Вы можете поместить свою библиотеку JNI там, где это необходимо для вашего приложения.

0 голосов
/ 16 октября 2008

Нельзя использовать CRT VC ++ 8 SP1 / 9 в качестве модуля слияния в Vista и Windows Server 2008, если у вас есть службы, которые вы хотите запустить, или программы, которые вы хотите запустить перед действием «InstallFinalize» в MSI.

Это потому, что библиотеки DLL установлены в WinSXS в действии «InstallFinalize».

Но действие MSI "ServiceStart" предшествует этому.

Так что используйте либо загрузчик "http://www.davidguyer.us/bmg/publish.htm"

Или изучите использование цепочек установщика в установщике 4.5. Но это означает, что вам нужен загрузчик для установки 4.5, поэтому он кажется немного бессмысленным.

0 голосов
/ 21 сентября 2008

Спасибо за ответ. Для развертывания как такового я вижу 3 варианта, а затем:

  • Использование директивы слияния .msi.
  • Используя распространяемый пакет VS и запустите его перед моим собственным установщиком
  • Копирование распространяемых файлов вместе с моим собственным приложением. Но как в этом случае ссылаться на него в иерархии файловой системы (скажем, bar / foo1 / foo1.dll и bar / foo2 / foo2.dll ссылаются на msvcr90.dll в bar /)? Я имею в виду, помимо очевидного и уродливого "скопировать dll в каждый каталог, где у вас есть dll, который зависит от него).
...