Ошибка сборки веб-приложения: не удалось найти тип поставщика CodeDom Microsoft.VisualC.CppCodeProvider

Я собираю/упаковываю веб-приложение на сервере сборки, и оно выдает следующее сообщение:

Ошибка ASPNETCOMPILER ASPCONFIG: не удалось найти тип поставщика CodeDom "Microsoft.VisualC.CppCodeProvider, CppCodeProvider, версия = 10.0.0.0, культура = нейтральный, PublicKeyToken = b03f5f7f11d50a3a".

Это среда сервера сборки:

  • Windows Server 2008 R2 Standard
  • TeamCity 8.0.4
  • .NET 4.5
  • Windows SDK для Windows 7 и .NET 4
  • Windows SDK для Windows 8 и .NET 4.5
  • Портативные инструменты библиотеки классов
  • ASP MVC 4

Это веб-приложение ASP MVC 4, предназначенное для .NET 4.5.

Конфигурация сборки состоит в том, чтобы собрать решение с помощью MSBuild и развернуть его в пакете, чтобы я мог опубликовать его позже.

Через журнал TeamCity я вижу ошибку, возникающую, когда MSBuild запускает aspnet_compiler.exe.

Сборки без проблем на моем компьютере DEV, а также могут без проблем публиковать их в локальном IIS.

Кто-нибудь знает, что может быть причиной этой проблемы?

ОБНОВИТЬ

Смотрите мой ответ ниже.

Ответ 1

Для меня эта ошибка появлялась в VS2017 при создании веб-проекта. Исправление заключалось в том, чтобы сделать каталог node_modules скрытым в Проводнике. По-видимому, это останавливает компилятор ASP.NET от сканирования всех этих файлов и, таким образом, предотвращает ошибку.

Ответ 2

Этот пост дал мне важный ключ: видимо, предварительная компиляция ASP.NET сканирует проект и выводит файлы и пытается скомпилировать каждый исходный файл, который он находит на своем пути, несмотря на его язык (см. здесь).

В этом случае мое веб-приложение зависит от проекта, который включает в себя некоторую неуправляемую dll вдоль файла ".h". Эти файлы копируются в выходной каталог ( "Копировать, если новый" ), поэтому я могу вывести его во время выполнения.

Кажется, что прекомпиляция ASP.NET находит ".h" и пытается ее скомпилировать, хотя в этом нет необходимости. И, как я вижу, он терпит неудачу, потому что у моего сервера сборки нет инструментов для работы (похоже, что CppCodeProvider поставляется с .NET 2.0 SDK).

Когда я изменил проект, чтобы не копировать эти файлы в выходной каталог, сборка прошла нормально. Я также протестировал копирование файлов, но с параметром "PrecompileBeforePublish" установлен в false в профиле публикации, и он также работал.

Теперь у меня есть несколько вариантов, но мне не нравится их:

  • Отключите "PrecompileBeforePublish". Я считаю, что основным недостатком этого является то, что опыт пользователей приложений будет медленнее при первом доступе к сайту.

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

  • Попробуйте указать "aspnet_compiler.exe", чтобы исключить файлы/папки, которые могут быть нарушены при выполнении. Я не знаю, как это сделать, используя профиль публикации, потому что у меня есть только контроль над "PrecompileBeforePublish". Кроме того, кажется, что "aspnet_compiler.exe" не предлагает эту опцию (здесь и здесь).

Я думаю, что пока я отключу "PrecompileBeforePublish", потому что это кажется быстрым путем с небольшими оговорками. Но я считаю, что должен быть лучший способ справиться с этим, исключая папки или типы файлов из предварительной компиляции с использованием профиля публикации.

Ответ 3

Это начало происходить, когда я обновлялся до VS2017. Для меня проблема заключалась в файле node.js, если бы я удалил папку node_modules, проект был бы собран без ошибок. Оказывается, что изменение значения MvcBuildViews на false в файле csproj, как предложено здесь, исправляет это. Это не идеально, так как представления mvc не будут скомпилированы, пока IIS их не отобразит. Лично я просто скрываю папку node_modules, чтобы обойти проблему, но я хотел добавить этот ответ на случай, если он поможет пролить свет на основную проблему для кого-то еще.

<MvcBuildViews>false</MvcBuildViews>

Ответ 4

В моем сценарии я должен отправить интерпретатор Perl с моим веб-сайтом ASP.Net(не спрашивайте, зачем мне нужен Perl, и мне жаль, что я делаю это заранее!), и это включало файлы .c, которые вызвали в aspnet_compiler.exe, чтобы ошибка, так как другие упомянули, что это их проблема. Каталог perl находится в моей папке bin и требуется во время выполнения.

Проблема, которую я обнаружил, заключалась в том, что вы attrib +H в папке, это действительно было пропущено aspnet_compiler, но тогда не было бы в моей папке вывода публикации. Поэтому мне пришлось взломать его еще больше, спрятав папку, скомпилировав представления, выделив папку и скопировав папку в нужное место. Это включало изменение первоначальной задачи AspNetPreCompile. См. Ниже:

<!-- Overwrite AspNetPreCompile task because it was trying to compile .c files found in the Perl directory. This prevents that but still copies Perl to publish file. -->
<!-- Taken from: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\VisualStudio\v15.0\Web\Transform -->
<Target Name="AspNetPreCompile" DependsOnTargets="$(AspNetPreCompileDependsOn)"  Condition="'$(AspNetPreCompile)' != 'false'">

    <PropertyGroup  Condition="'$(UseMetabasePath)' == 'true'" >
        <_PreAspnetCompileMergeSingleTargetFolderFullPath></_PreAspnetCompileMergeSingleTargetFolderFullPath>
        <_AspNetCompilerVirtualPath></_AspNetCompilerVirtualPath>
    </PropertyGroup>
    <PropertyGroup  Condition="'$(UseMetabasePath)' != 'true'" >
        <_PreAspnetCompileMergeSingleTargetFolderFullPath>$([System.IO.Path]::GetFullPath($(_PreAspnetCompileMergeSingleTargetFolder)))</_PreAspnetCompileMergeSingleTargetFolderFullPath>
    </PropertyGroup>

    <PropertyGroup>
        <_PostAspnetCompileMergeSingleTargetFolderFullPath>$([System.IO.Path]::GetFullPath($(_PostAspnetCompileMergeSingleTargetFolder)))</_PostAspnetCompileMergeSingleTargetFolderFullPath>
    </PropertyGroup>

    <!-- Modification #1. -->
    <Exec Command="attrib +H &quot;$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl&quot;" />

    <AspNetCompiler
        PhysicalPath="$(_PreAspnetCompileMergeSingleTargetFolderFullPath)"
        TargetPath="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)"
        VirtualPath="$(_AspNetCompilerVirtualPath)"
        Force="$(_AspNetCompilerForce)"
        Debug="$(DebugSymbols)"
        Updateable="$(EnableUpdateable)"
        KeyFile="$(_AspNetCompileMergeKeyFile)"
        KeyContainer="$(_AspNetCompileMergeKeyContainer)"
        DelaySign="$(DelaySign)"
        AllowPartiallyTrustedCallers="$(AllowPartiallyTrustedCallers)"
        FixedNames="$(_AspNetCompilerFixedNames)"
        Clean="$(Clean)"
        MetabasePath="$(_AspNetCompilerMetabasePath)"
        ToolPath="$(AspnetCompilerPath)"
        />

    <!-- Modification #2. -->
    <Exec Command="attrib -H &quot;$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl&quot;" />

    <!--
        Removing APP_DATA is done here so that the output groups reflect the fact that App_data is
        not present
        -->
    <RemoveDir Condition="'$(DeleteAppDataFolder)' == 'true' And Exists('$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\App_Data')"
                Directories="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\App_Data" />


    <CollectFilesinFolder Condition="'$(UseMerge)' != 'true'"
        RootPath="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)" >
        <Output TaskParameter="Result" ItemName="_AspnetCompileMergePrecompiledOutputNoMetadata" />
    </CollectFilesinFolder>

    <ItemGroup Condition="'$(UseMerge)' != 'true'">
        <FileWrites Include="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\**"/>
    </ItemGroup>

    <!-- Modification #3. -->
    <ItemGroup>
        <Perl Include="$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl\**\*.*" />
    </ItemGroup>

    <!-- Modification #4. -->
    <Copy SourceFiles="@(Perl)" DestinationFolder="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\bin\perl\%(RecursiveDir)"></Copy>

</Target>

НЕ изменяйте исходный файл .targets, скопируйте его в файл .csproj в качестве дочернего элемента в <project> node.

Ключевые вынос:

Используйте команду Exec для attrib +H Directory перед запуском aspnet_compiler.exe с помощью задачи AspNetCompiler и attrib -H Directory после этого.

Создайте ItemGroup, чтобы сосать все файлы, которые все еще нужно скопировать.

Запустите задачу Copy, используя ItemGroup, чтобы поместить файлы там, где они должны быть, чтобы остальная часть задачи публикации включала их. Мы используем все переменные, созданные Microsoft при создании этой задачи, поэтому мы также можем использовать их здесь.

Pro для изменения исходной задачи: очень мало изменений в нормальном поведении, поэтому он все равно должен работать.

Возможна модификация исходной задачи: Microsoft может изменить эту задачу в будущем, сделав нашу копию устаревшей.

Если у вас нет моих странных требований, более простое решение для скрытия папки выглядит следующим образом:

<Target Name="Test" BeforeTargets="AspNetPreCompile">
    <Exec Command="attrib +H Directory" />
</Target>
<Target Name="Test" AfterTargets="AspNetPreCompile">
    <Exec Command="attrib -H Directory" />
</Target>

Ответ, вдохновленный комментарием twamley, сделанным в ответ Артура Нюнеса.

Ответ 6

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

Так что, возможно, стоит проверить файл web.config всего, что может быть задействовано.

Ответ 7

Для меня эта ошибка показывала, когда физический путь моего веб-сайта был недействителен в IIS. Чтобы устранить этот щелчок правой кнопкой мыши на веб-сайте (Управление веб-сайтом → Расширенные настройки → Физический путь).

Ответ 8

В моем случае на новой машине был установлен VS2017 и открылось веб-приложение asp.net core 1.1 из исходного элемента управления. Произошла ошибка. Я установил node.js и скомпилировал проект.

Ответ 9

Мое решение этой ошибки было сочетание двух ранее существовавших ответов на этой странице. У меня был файл .h в каталоге моего веб-проекта, который не вызывал проблем, пока я не попытался построить проект на компьютере VS 2017 года.

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

Ответ 10

В моем случае я добавил в свое решение угловой веб-сайт, который вызвал эту ошибку.

Устранена ошибка с помощью следующих шагов.

В строке меню выберите "Сборка"> "Диспетчер конфигурации".

В таблице контекстов проекта исключите угловой веб-сайт (который содержал node_modules)

В столбце Build для проекта снимите флажок.

Нажмите кнопку "Закрыть" и перестройте решение.

Ответ 11

Для тех, кто позже найдет это в Google...

Первопричина

Как следует из ошибки, сборка "Microsoft.VisualC.CppCodeProvider" не найдена.

Это было добавлено в глобальный кэш сборок (GAC) как часть установки Visual Studio 2015, но не Visual Studio 2017.

Исправление

Правильное решение - добавить недостающую ссылку в GAC.

Запустите "Командная строка разработчика" от имени администратора и выполните следующую

gacutil /i "path to CppCodeProvider.dll" или gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2 017\Professional\Common7\IDE\PublicAssemblies\CppCodeProvider.dll"

например


C:\Windows\System32>gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2
017\Professional\Common7\IDE\PublicAssemblies\CppCodeProvider.dll"
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Assembly successfully added to the cache

C:\Windows\System32>

При следующей сборке следующая ошибка больше не выдается.

ASPNETCOMPILER error ASPCONFIG: The CodeDom provider type "Microsoft.VisualC.CppCodeProvider, CppCodeProvider, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" could not be located.