Приложение Visual Studio 2015 для С++ требует api-ms-win-crt-runtime-l1-1-0.dll для клиентских клиентов

Я создал приложение с редакцией Visual Studio 2015 Community. Когда некоторые из моих пользователей пытаются запустить его, они получают следующую ошибку:

Программа не может запускаться, потому что api-ms-win-crt-runtime-l1-1-0.dll отсутствует на вашем компьютере. Попробуйте переустановить программу, чтобы устранить эту проблему.

Ясно, что это решается установкой Обновление для универсального времени выполнения C в Windows (KB2999226). Я могу проверить исправление во время установки script, но все методы, которые я нашел для этого, являются слишком медленными или ненадежными.

Как предотвратить эту ошибку? Могу ли я изменить свое решение, чтобы я не нуждался в этой зависимости? Я связываюсь с чем-то, что могу удалить? Можно ли перераспределить исправление вместе с моим приложением?

Изменить: В свойствах проекта "Версия целевой платформы" - 8.1, а "Platform Toolset" - "Visual Studio 2015 (v140)", если это вообще помогает.

Изменить 2: Я попытался скопировать всю библиотеку DLL Universal C Runtime в каталог приложения, так как Теперь Microsoft разрешает (но не рекомендуется) локального режима установки UCRT. В C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x64 есть 41 файл, а api-ms-win-crt-runtime-l1-1-0.dll - один из них. Однако при запуске приложения результат этой ошибки:

Приложение не смогло начать правильно (0xc0000142). Нажмите "ОК", чтобы закрыть приложение.

Я пробовал отлаживать приложение с помощью MSVS 2015, но нигде не попадал. Я открыл исполняемый файл в Dependency Walker, и кажется, что я пропускаю похожие DLL, перечисленные в этом ответе, в котором говорится, что Dependency Walker устарел, и это красная селедка.

Я попробовал запустить приложение через Process Monitor (procmon), и там ничего необычного. Приложение просто вызывает "Создание процесса" на WerFault.exe, а затем "Выход из темы".

Изменить 3: Я включил загрузчик щелчком в исполняемом файле и получил это при запуске из cdb, если это помогает:

...
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - ENTER: DLL name: api-ms-win-core-sysinfo-l1-2-1.dll.
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - INFO: DLL name api-ms-win-core-sysinfo-l1-2-1.dll was redirected to C:\WINDOWS\SYSTEM32\kernelbase.dll by SxS.
00c0:1200 @ 02106250 - LdrpFindOrMapDll - ENTER: DLL name: C:\WINDOWS\SYSTEM32\kernelbase.dll
00c0:1200 @ 02106250 - LdrpResolveDllName - ENTER: DLL name: C:\WINDOWS\SYSTEM32\kernelbase.dll
00c0:1200 @ 02106250 - LdrpResolveDllName - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpFindOrMapDll - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpFindOrMapDependency - RETURN: Status: 0x00000000
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlSetLastWin32Error" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlLeaveCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlEnterCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlInitializeCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlDeleteCriticalSection" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlQueryPerformanceCounter" by name
00c0:1200 @ 02106250 - LdrpGetProcedureAddress - INFO: Locating procedure "LdrResolveDelayLoadedAPI" by name
00c0:1200 @ 02106250 - LdrpMergeNodes - INFO: Merging a cycle rooted at USER32.dll.
00c0:1200 @ 02106250 - LdrpMergeNodes - INFO: Adding cyclic module GDI32.dll.
(c0.1200): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll -
ntdll!LdrInitShimEngineDynamic+0x330:
00007ffc`d68732e8 cc              int     3
0:000>

Ответы

Ответ 1

Вы должны статически связываться с ЭЛТ. Для потребительского приложения существует множество сценариев, которые приводят к отсутствию определенной DLL или сбою в конфигурации. Я был техническим руководителем установщика для очень популярного приложения Windows (тысячи инсталляций в день), и вы не поверили бы, как распространены ошибочно настроенные машины Windows. Внизу я дам короткий список.

Универсальный CRT - хорошая идея, но относительно новая, и это будет некоторое время (возможно, долгое время) до тех пор, пока оно не сломается, что не позволит компьютеру ваших клиентов загрузиться. Это должно быть пороговым значением: если ваш клиент не может войти в систему без DLL X, тогда это нормально, если вы зависнете от него.

Общие странные состояния:

  • Выполняется MSI: почему-то Windows думает, что есть незавершенная работа.
  • База данных COM несовместима: часть HKCU реестр является грубым местом.
  • Отсутствуют прошивки MSVC или предварительные версии там
  • Предварительные версии Windows: мы предполагаем, что pre-release Windows легче пиратствовать.
  • Еще в sysprep: OEM забыл запечатать конфигурацию машины.
  • Шрифты повреждены: особенно болезненно, если вы используете DirectWrite
  • Overclocked: возможные бит перевертывает в буферах файловой системы одинаковые поврежденные файлы.

Ответ 2

Я могу проверить исправление

Довольно важно помнить, что это не исправление. Это обычное обновление, которое автоматически доставляется через Центр обновления Windows. Итак, есть один факт, который вы знаете, эти машины не поддерживаются. Конечно же, это очень плохая новость и наличие проблем.

api-ms-win-crt-runtime-l1-1-0.dll отсутствует

Это DLL операционной системы, которая обычно поставляется вместе с установкой операционной системы, начиная с Win7. Это должно сузить то, что неправильно с этими машинами, они, скорее всего, загрузят XP. Небольшие шансы для Vista. XP больше не поддерживается Microsoft, поэтому просмотр отсутствующего обновления не является совпадением.

"Версия целевой платформы" - 8.1, а "Platform Toolset" - "Visual Studio 2015 (v140)"

Это хорошо, но вам нужно дважды проверить это в своем установщике и отказаться от установки на XP. Таргетинг на XP по-прежнему возможен, вам нужно изменить параметр "Набор инструментов платформы" на "v140_xp". Не уверен, что этот вариант доступен в издании Community, это меня удивило бы, если бы это было.

Есть 41 файл в...

Только один подсчет, ucrtbase.dll. Остальные из них - файлы api-ms-win *.dll, которые должны присутствовать в каталоге установки Windows. Они включены, поэтому вы все равно можете использовать XP и Vista, их следует развернуть в c:\windows\system32 или c:\windows\syswow64, в зависимости от битности. Обратите внимание, что вы задокументировали каталог x64, проверяя, что у пользователя 64-разрядная версия Windows - это еще одна вещь, которую вы должны дважды проверить в своем установщике.

Приложение не смогло начать правильно (0xc0000142).

Это STATUS_DLL_INIT_FAILED, точка входа DllMain() одной из DLL, у которой есть зависимость от возвращенного FALSE. Довольно плохие новости, не так легко отлаживать, и вы, конечно же, не будете пытаться решить эту проблему с помощью VS2015, так как это не подведет на вашей машине. Вам нужно включить привязки загрузчика, чтобы загрузчик ОС стал болтливым. Доступ к машине, у которой есть эта проблема, конечно, обязателен.

Очевидно, это решается установкой Update...

Да, время, чтобы сократить ваши потери, я бы сказал. Никто не может разумно ожидать, что ваше приложение будет работать, когда они намеренно не будут поддерживать свою машину или откажутся ее обновлять. Убедитесь, что в вашем установщике присутствует ucrtbase.dll, а когда нет, просто прекратите установку и скажите им сначала обновить свою машину.