Сборка и развертывание dll в windows: SxS, манифесты и все такое

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

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

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


person David Cournapeau    schedule 21.09.2008    source источник


Ответы (8)


Мы используем простой включаемый файл во всех наших приложениях и библиотеках 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 */

/*----------------------------------------------------------------------------*/
person titanae    schedule 22.09.2008
comment
Надеюсь, вы все еще просматриваете эту ветку. К сожалению, я не могу использовать ваш файл как есть. Где мне включить этот файл? Что мне делать, если я хочу поддерживать более раннюю версию, чем на ПК клиента, чем на ПК разработчика? Любые предложения, которые вы можете дать, будут благословением. Если нет, я отправлю еще один вопрос в stackoverflow. - person ossandcad; 25.09.2010

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

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

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

person Chris Becke    schedule 22.10.2008


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

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

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

person Brian    schedule 21.09.2008

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

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

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

person ima    schedule 21.09.2008
comment
Ммм, странно, я могу поклясться, что видел где-то в MSDN, что вы не можете распространять их, но теперь я больше не могу найти ссылку, я, должно быть, неправильно прочитал. Однако использование распространяемого пакета не вариант (я не использую MSI). - person David Cournapeau; 21.09.2008
comment
Вы не можете распространять debug CRT. Релизный предназначен для распространения. - person Nicolás; 09.08.2013

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

  • Использование директивы слияния .msi.
  • Использование распространяемого пакета VS и запуск его до моего собственного установщика
  • Копирование распространяемых файлов вместе с моим собственным приложением. Но в этом случае, как мне ссылаться на него в иерархии файловой системы (скажем, bar / foo1 / foo1.dll и bar / foo2 / foo2.dll относятся к msvcr90.dll в bar /)? Я имею в виду, помимо очевидного и уродливого «скопируйте dll в каждый каталог, где у вас есть dll, которая от нее зависит).
person David Cournapeau    schedule 21.09.2008
comment
Если вы связываете файлы redist (согласно моему ответу) со своим приложением, поместите их в ту же папку, что и exe. К счастью, загрузчик fusion по-прежнему сначала просматривает папку exe при попытке найти библиотеки DLL. - person Chris Becke; 22.10.2008

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

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

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

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

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

person garthy    schedule 16.10.2008

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

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

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

person EricJ    schedule 07.05.2009