Зависимости времени выполнения Visual studio 2015 или как избавиться от Universal CRT?

составлен пару .dll использует visual studio 2015 и пытался развернуть на некоторых старых Windows 7 / 64 бит. Пытался также угадать, какие dll необходимы для запуска приложения и скопировали MSVCP140.БИБЛИОТЕКИ DLL & VCRUNTIME140.DLL - но приложение не может загрузить ДЛЛ vs2015. Начал анализировать, что не так-и dependency walker показал зависимости от следующих dll:

API-MS-WIN-CRT-MATH-L1-1-0.DLL
API-MS-WIN-CRT-HEAP-L1-1-0.DLL
API-MS-WIN-CRT-CONVERT-L1-1-0.DLL
API-MS-WIN-CRT-STRING-L1-1-0.DLL
API-MS-WIN-CRT-STDIO-L1-1-0.DLL
API-MS-WIN-CRT-RUNTIME-L1-1-0.DLL
API-MS-WIN-CRT-FILESYSTEM-L1-1-0.DLL
API-MS-WIN-CRT-TIME-L1-1-0.DLL

Это было особенно удивительно, так как для моего лучшего понимания CRT отвечает за запуск dll / exe, он не предоставляет никаких услуг более высокого уровня.

Ok, попытался выяснить, как избавиться от них или, по крайней мере, свести к минимуму.

нашел одну статью: https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/

в нем упоминается о статических библиотеках release-поэтому я подумал, что могу связать с ними и избавиться от *L1-1-0.DLL * зависимость ад, но независимо от того, что я пробовал - у меня не было успеха. Я пытался ссылка против libvcruntime.Либ, либукрт.lib, libcmt.lib, попытался отключить параметр компоновщика " / nodefaultlib: vcruntime.lib", и даже попытался добавить Include directory $(UniversalCRT_IncludePath), а также переопределить некоторые из define, поскольку я попытался угадать, что они работают - ни одна из моих попыток не помогла.

в качестве промежуточного решения я вернулся к использованию Visual studio 2013, где dll CRT только два: msvcp120.библиотеки DLL, msvcr120.файл DLL.

конечно, вы, вероятно, рекомендую чтобы установить время выполнения Visual studio 2015, но одним из наших требований является поддержка автономного исполняемого файла, который работает без какой - либо установки, поэтому о дополнительной установке пока не может быть и речи.

можете ли вы порекомендовать мне что-нибудь еще, кроме как ждать прибытия Visual studio 2017 ?

4 ответов


я смог решить эту проблему, установив C/C++ > Code Generation > Runtime Library опции компилятора

  • для отладки: с /MDd to /MTd
  • для выхода: с /MD to /MT

этого удалить все API-MS-WIN-CRT-* и ссылки dll во время выполнения и вызвали статическую связь всего кода CRT.

подробности о новой универсальной ЭЛТ VS2015 (динамической и статической) здесь: https://msdn.microsoft.com/en-us/library/abx4dbyh.aspx


Я тоже боролся со статической связью решения с несколькими компонентами/зависимостями библиотеки проектов, импортирующими функции из разных частей MSVCRT, UCRT и ядра. Надежда заключалась в том, что полученный EXE можно было просто скопировать туда, где это было необходимо (это был не продукт, который оправдывал бы полную установку MSI).

после почти отказа я нашел лучшее решение-следовать рекомендациям, скрытым в универсальное объявление времени выполнения c, в частности:

мы настоятельно рекомендуем против статического связывания Visual C++ библиотеки, по причинам производительности и работоспособности

просто удалите все" специальные " параметры компоновщика, которые вы пробовали, вернитесь к|MT/|MD (многопоточный CRT DLL Release / Debug) выбор библиотеки времени выполнения, и он работает везде, например, новые рабочие станции Windows 10, серверы 2012 R2 и Windows 7). Просто установите / распространите библиотеки msvcrt (VC_Redist*.exe) и KB2999226 (UCRT через Центр обновления Windows) как Microsoft говорит нам делать, потому что, как они также говорят:

универсальный ЭЛТ является компонентом операционной системы Windows. Он входит в состав Windows 10, начиная с января Технический предварительный просмотр, и он доступен для более старых версий операционные системы через Центр обновления Windows.

поэтому логически единственное дополнительное развертывание зависимость наши решения C++ добавляют для клиента MSVCRT, потому что UCRT уже должен быть там на современных / ухоженных машинах. Конечно, это добавляет немного неопределенности; вы не можете просто скопировать EXE и запустить на любой машине, хорошей или плохой.

Если вы создаете достойный пакет развертывания, такой как MSI, то его легко включить, когда у вас есть такие инструменты, как WIX. Также следует отметить, что с недавнего SDK вы можете включать 40-нечетные библиотеки DLL локально, но это не удовлетворяет принцип обновления безопасности, поэтому я бы этого не делал.

Это действительно единственный поддерживаемый способ сделать это, см. другой пример здесь. В этой статье также предлагается связать с " mincore_downlevel.lib", который является важным советом, имеет решающее значение для того, получаете ли вы эти" api-ms-win* " отсутствующие ошибки DLL. Например:

  1. версия SDK проекта установлена в 10, связь с mincore.lib = работает только в Windows 10, но не 8.1 / 2012 R2 или Windows 7/2008 R2 сервер.
  2. версия SDK проекта установлена в 8.1, ссылка с mincore.lib = работает как на сервере Windows 10, так и на сервере 8.1/2012 R2,но не на сервере Windows 7/2008 R2.
  3. версия SDK проекта установлена в 10, ссылка с mincore_downlevel.lib = работает на всех!

в итоге:

  1. не связывайте статически, оставьте время выполнения DLL C по умолчанию, выбранное в настройках проекта.
  2. вам не нужны старые SDKs, смогите превратиться с последний Windows 10 SDK, но вы должны связать с " mincore_downlevel.Либ" не "системный вызов mincore.lib", если вы хотите поддерживать более старые версии Windows.
  3. для удобства использования добавьте это в targetver.h или stdafx.h который также документирует ваш выбор (удалите другую строку):
// Libraries
#pragma comment(lib, "mincore.lib")             // Lowest OS support is same as SDK
#pragma comment(lib, "mincore_downlevel.lib")   // Support OS older than SDK

(Обновлено 11.10.2016).

можно избавиться от universal CRT, связав его статически, я доберусь до него позже, но давайте возьмем посмотрите, если вы продолжаете использовать universal CRT как таковой.

согласно статье https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ - это возможно, чтобы запустить приложение с помощью универсальной CRT dll файлы distributables из следующей папке: C:\Program Files (x86)\Windows Kits\Redist\ucrt

есть 41 файлы полностью в списке с размером 1.8 Mb в общей сложности. (пример для 64-разрядной платформы)

конечно, этого недостаточно, вам понадобится дополнительно vcruntime140.библиотеки DLL & msvcp140.dll из следующей папки: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x64\Microsoft.VC140.CRT

Итак, после этого вы отправите полностью 43 дополнительных dll, кроме вашего приложения.

также возможно статически скомпилировать библиотеку ucrt внутри вашего приложения, после чего вам не понадобится 43 dll - но статическая ссылка для после связывания или нет-зависит от вашего приложения - сколько dll и какие api используются. Обычно после того, как ucrt связывается с двумя разными dll, они не обязательно разделяют одни и те же глобалы друг с другом, что может привести к ошибкам.

вам нужно связать против vcruntime.lib / msvcrt.lib, но этого недостаточно - есть дополнительные _VCRTIMP= и _ACRTIMP= определяет, какие функции должны быть отключены от вытягивания из ucrt.

если вы используете premake5 вы можно настроить свой проект следующим образом:

defines { "_VCRTIMP="}
linkoptions { "/nodefaultlib:vcruntime.lib" }
links { "libvcruntime.lib" }

затем:

defines { "_ACRTIMP="}
linkoptions { "/nodefaultlib:msvcrt.lib" }
links { "libcmt.lib" }

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

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

что касается библиотек boost - мне также удалось скомпилировать boost, используя b2.exe boostrapper

boost>call b2 threading=multi toolset=msvc-14.0 address-model=64 --stagedir=release_64bit --build-dir=intermediate_64but release link=static,shared --with-atomic --with-thread --with-date_time --with-filesystem define=_VCRTIMP= define=_ACRTIMP=

когда устранение неполадок связывания - обратите внимание, что неразрешенные __imp* имена функций из-за dllimport использование ключевых слов - и если вы свяжетесь с libvcruntime.Либ, у тебя не должно быть никаких __imp* ссылки.


Я слишком много боролся, выясняя DLL времени выполнения, необходимые для запуска приложения, которое было построено в Visual Studio 2015.

здесь я нашел следующие вещи, которые позволяют VS-2015 встроенное приложение для запуска.

Примечание. : Поместите версии DLL в соответствии с архитектурой системного процессора (x86, x64..).