2009-11-08 1 views
0

У нас есть 32-битное смешанное приложение C/C++, которое мы пытаемся развернуть в мире. Он, естественно, использует библиотеки времени выполнения C и C++. Мы используем VS 2005Конфигурация сборки Microsoft для 32-разрядного смешанного приложения C/C++

манифеста построен VS2005 заключается в следующем:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

Мы грузим это как файл в том же каталоге, что и «приложение», названный (изменены, чтобы защитить невинных) "application.exe.manifest".

На первый взгляд это разумно. Но, при установке на некоторых системах , мы получаем сообщение, когда «application.exe» запускается:

Это приложение не удалось запустить из-за конфигурации приложения неверен

Один из способов вылечить это для запуска VCRedist_x86.exe из MSDN. (К сожалению, в то время как мы можем запустить его, мы не знаем точно, что это делает. Это, как представляется, парковочные библиотеки DLL в SxS каталогах. Но что еще это делает?)

а) МС docs, похоже, указывают, что сборка должна иметь assemblyIdentity тег непосредственно под блоком , который сам именует приложение. Это явно отсутствует здесь, но манифест частично работает в том, что , если мы его удалим, приложение не запускается, даже если библиотеки DLL присутствуют.

b) Замечательно, что в сборке не упоминается DLL C runtime. Нужно ли просто добавить это вручную?

c) Мы не хотим зависеть от того, присутствует ли на целевой машине подходящая DLL версии. Предполагая, что сборка дает понять, какие DLL использовать, как мы можем гарантировать, что DLL, которые нам нужны, находятся в целевой системе? (В частности, мы не хотим запускать VCRedist или просить нашего клиента сделать это). Перед тем, как были собраны сборки, мы решили эту проблему, просто разместив библиотеки C и C++ в том же каталоге, что и файл .exe приложения, и Windows сначала увидит их, чтобы забрать их. Можем ли мы по-прежнему отправлять C и C++ DLL в один и тот же каталог? Я не могу понять из документов MS, которые могут найти, как SxS находит соответствующие зависимые сборки.

Любая помощь приветствуется.

ответ

0

Вы можете связать время выполнения C/C++ статически.

Вы можете изменить связь с библиотекой в ​​параметрах компилятора C/C++ в разделе Code Generation. Изменить запись с Многопоточная [отладка] DLL до Многопоточность [отладка].

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

+0

Спасибо за предложение. Это вариант. Но я хотел бы понять, как работает манифест. –

0

Я никогда не понимал, как все вещи манифеста связывают друг с другом ... но вместо того, чтобы размещать библиотеки времени выполнения C в том же каталоге, что и ваш exe, попробуйте скопировать весь «Microsoft.VC90».CRT 'из папки redist в установке Visual Studio (C: \ Program Files (x86) \ Microsoft Visual Studio 9.0 \ VC \ redist \ x86 \ Microsoft.VC90.CRT на моей машине).

Я считаю, что Microsoft поощряет использование разделяемых библиотек и запуск официального переименования с момента установки библиотек «правильно» и означает, что они могут исправлять проблемы безопасности, которые могут быть найдены в них.

+0

... попробуйте скопировать всю папку ... туда, где? И * кто * должен сделать это копирование (я думаю, что мы говорим об установщике здесь, так как мы доставляем наше приложение). И я озадачен ... Я установил много загрузок, и мне НИКОГДА не просили запустить VCRedist загруженным инструментом. Покажите, как можно делиться библиотеками на практике? –

+0

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

+0

Это действительно правильная вещь. Fusion (загрузчик SxS) проведет проверку для «assemblyIdentity/@ name» .manifest (например: Microsoft.VC80.CRT.manifest) в том же каталоге, что и исполняемый файл, для разрешения сборок, не сохраненных в кеше сборки SxS. Если ваш клиент уже установил повторный набор CRT, вместо этого он будет использовать копию в папке SxS, предоставляя вам обновления для системы безопасности и может улучшить запуск приложений и использование памяти, если какое-либо другое запущенное приложение уже использует SxS CRT. –

1

a) Валидация манифеста xml явно имеет некоторые проблемы. В зависимости от версии Windows это может быть или не быть проблемой. Поскольку так много приложений не правильно следуют схеме (и потому, что она никогда не была должным образом применена), я сомневаюсь, что она будет когда-либо строгой здесь.

b) Среда выполнения C DLL ссылается в файле Microsoft.VC80.CRT.manifest, потянув его на график зависимости загрузчика. Если у вас есть зависимость от манифеста, вы также неявно будете иметь зависимость от DLL.

c) В моем предыдущем комментарии правильная вещь (помимо установки самой последней системы с переизданием) заключается в том, чтобы поместить манифест CRT и все три библиотеки DLL в каталог вашего приложения. Это плохо документировано под SxS: Private Assemblies и Installing Side-by-side Assemblies as Private Assemblies. Порядок зонда определяется в Assembly Searching Sequence.

Как правило, сбой привязки SxS помещает запись в приложение (для Vista +) или журнал системных событий (pre Vista), описывающее ошибку.

 
Activation context generation failed for "C:\TEMP\sxs\PEVerify.exe".Error in manifest or policy file "C:\TEMP\sxs\Microsoft.VC90.CRT.MANIFEST" on line 4. 
Component identity found in manifest does not match the identity of the component requested. 
Reference is Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a18e3b",type="win32",version="9.0.21022.8". 
Definition is Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.30729.1". 
Please use sxstrace.exe for detailed diagnosis. 

Вы можете использовать sxstrace.exe в (Vista +), чтобы увидеть, что загрузчик на самом деле делает. Junfeng более подробно описывает это в Diagnosing SideBySide failures.

Чтобы получить лучшее представление о том, что происходит во время выполнения (после анализа манифеста и зависимостей), включите «Показывать привязки загрузчика» для вашего файла изображения (просто имя файла и расширение, не вводите имя каталога , так: «notepad.exe») с использованием gflags.exe. Запустите приложение под номером windbg (также может работать отладчик Visual Studio) и посмотрите на результат. Обязательно отключите привязки загрузчика, когда вы закончите отладку, поскольку это замедлит работу приложения, даже если отладчик не подключен. Пример вывода выглядит следующим образом:

 
2d6c:36b4 @ 1246428223 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin\PEVerify.exe" imports "MSVCR90.dll" 
2d6c:36b4 @ 1246428223 - LdrpMapDll - INFO: Mapping static redirected DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" 
ModLoad: 4fbd0000 4fc73000 C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll 
2d6c:36b4 @ 1246428285 - LdrpMapDll - INFO: Mapped DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" at address 4FBD0000 
2d6c:36b4 @ 1246428285 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" imports "KERNEL32.dll"