【问题标题】:Web Application Build Error: The CodeDom provider type Microsoft.VisualC.CppCodeProvider could not be locatedWeb 应用程序生成错误:无法找到 CodeDom 提供程序类型 Microsoft.VisualC.CppCodeProvider
【发布时间】:2013-12-30 23:10:50
【问题描述】:

我正在构建服务器中构建/打包一个 Web 应用程序,但它失败并显示以下消息:

ASPNETCOMPILER 错误 ASPCONFIG:CodeDom 提供程序类型 “Microsoft.VisualC.CppCodeProvider,CppCodeProvider,版本=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 不能 位于。

这是构建服务器环境:

  • Windows Server 2008 R2 标准版
  • TeamCity 8.0.4
  • .NET 4.5
  • 适用于 Windows 7 和 .NET 4 的 Windows SDK
  • 适用于 Windows 8 和 .NET 4.5 的 Windows SDK
  • 可移植类库工具
  • ASP MVC 4

它是一个 ASP MVC 4 Web 应用程序,面向 .NET 4.5。

构建配置包括使用 MSBuild 构建解决方案,并将其部署到包中,以便稍后发布。

通过TeamCity的日志可以看到MSBuild运行aspnet_compiler.exe时出现的错误。

在我的 DEV 机器上构建没有问题,也可以毫无问题地将其发布到本地 IIS。

有谁知道是什么导致了这个问题?

更新

See my answer below.

【问题讨论】:

    标签: c# asp.net msbuild teamcity build-server


    【解决方案1】:

    对我来说,这个错误是在构建 web 项目时在 VS2017 中弹出的。修复是使 node_modules 目录隐藏在文件资源管理器中。显然,这会阻止 ASP.NET 编译器扫描所有这些文件,从而防止错误。

    【讨论】:

    • 这绝对是一种解决方法(我无法使用,因为隐藏了 node_module 文件夹会破坏其他工作流程。)我发现安装 .NET 3.5 可以解决这个问题。
    • 遇到了类似的问题,原因是 npm 包“uws”及其*.c 文件。我只是在构建之前将它从文件夹中移出,然后再放回去。不幸的是,为了我们的目的隐藏整个文件夹也不可行。
    • 为我工作。这项工作确实显示了 Visual Studio 的时代。
    【解决方案2】:

    This post 给了我一个重要的线索:显然 ASP.NET 预编译会扫描项目和输出文件,并尝试编译以它的方式找到的每个源文件,尽管它的语言(参见 here)。

    在这种情况下,我的网络应用程序依赖于一个项目,该项目包含一些非托管 dll 以及“.h”文件。这些文件被复制到输出目录(“如果较新则复制”),因此我可以在运行时对其进行 pinvoke。

    似乎 ASP.NET 预编译找到了“.h”并尝试编译它,即使不需要它。而且,正如我所见,它失败了,因为我的构建服务器没有用于这项工作的工具(看起来CppCodeProvider 带有.NET 2.0 SDK)。

    当我将项目更改为不将这些文件复制到输出目录时,构建运行良好。我还测试了复制文件,但在发布配置文件中将“PrecompileBeforePublish”设置为 false,它也可以工作。

    现在我有一些选择,但我不喜欢其中任何一个:

    • 禁用“PrecompileBeforePublish”。我认为这样做的主要缺点是应用程序用户在首次访问网站时的体验会变慢。

    • 尝试从输出文件夹中排除文件,并在预编译后再次添加。对于我最初不应该担心的事情来说,这似乎需要做很多工作。

    • 尝试告诉“aspnet_compiler.exe”在执行时排除有问题的文件/文件夹。我不知道如何使用发布配置文件,因为我只能控制“PrecompileBeforePublish”。此外,“aspnet_compiler.exe”似乎不提供该选项(herehere)。

    我认为现在我将禁用“PrecompileBeforePublish”,因为它似乎是一条快速的路径,几乎没有警告。但我相信应该有更好的方法来处理它,使用发布配置文件从预编译中排除文件夹或文件类型。

    【讨论】:

    • 天哪! - 非常感谢你的这篇文章 - 你可能救了我几天的挫败感,因为这正是发生在我们身上的事情。你有没有找到忽略文件夹的方法? (虽然我的第一选择是从 repo 中删除有问题的文件。)
    • 不,Edward,我必须禁用“PrecompileBeforePublish”。但是,在这个问题发生后不久我就停止了该项目的工作,所以也许答案仍然存在=]
    • @Edward 我也遇到了这个问题。到目前为止,我很幸运,在运行 aspnet_compiler.exe 之前在我的构建脚本中使用隐藏属性 (attrib +H c:\path\to\problem\directory) 标记了我不需要编译的文件夹,然后在完成后重置隐藏属性。
    • 这是另一个不错的选择@twamley。我能够删除文件,所以它再次为我工作。不过,您的方法听起来像是对这个问题的有效答案。如果你把它写出来,请联系我,我会投票给它。
    • 这个信息是黄金!我们的前端有一个node_modules 文件夹,这会导致一些问题,因为某些模块包含不适用于 Visual Studio 的 c 文件和头文件。避免此错误的唯一方法是让 msbuild 删除该文件夹。
    【解决方案3】:

    为了那些后来在谷歌上找到这个的人的利益......

    根本原因

    正如错误所暗示的,无法找到程序集“Microsoft.VisualC.CppCodeProvider”。

    这是作为 Visual Studio 2015 安装的一部分添加到全局程序集缓存 (GAC) 中的,但不是 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 错误 ASPCONFIG:找不到 CodeDom 提供程序类型“Microsoft.VisualC.CppCodeProvider, CppCodeProvider, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”。

    【讨论】:

    • 这个应该被标记为答案。谢谢丹尼尔
    • 如果你根本没有 CppCodeProvider.dll 怎么办?这似乎是可以解决我的问题的答案,但是在搜索了我的整个 C: 驱动器后,我发现我在任何地方都没有 .dll。
    • 尝试修改您的 Visual Studio 安装并选择“使用 C++ 进行桌面开发”。
    • 帮我解决了,谢谢!根据您使用的 VS 版本,您的路径可能会有所不同
    • 解决了我的问题。这应该是答案。
    【解决方案4】:

    当我更新到 VS2017 时,这开始发生。对我来说问题是 node.js,如果我删除了 node_modules 文件夹,那么项目将构建而不会出现错误。事实证明,按照 anders here 的建议,在 csproj 文件中将 MvcBuildViews 的值更改为 false 可以修复它。这并不理想,因为在 IIS 呈现它们之前不会编译 mvc 视图。就个人而言,我只是隐藏了 node_modules 文件夹来解决这个问题,但我想添加这个答案,以防它有助于为其他人阐明潜在问题。

    <MvcBuildViews>false</MvcBuildViews>

    【讨论】:

    【解决方案5】:

    在我的情况下,我在我的解决方案中添加了一个有角度的网站,这导致了这个错误。

    通过以下步骤解决了错误。

    在菜单栏上,选择构建 > 配置管理器。

    在项目上下文表中,排除 Angular 网站(其中包含 node_modules)

    在项目的 Build 列中,清除复选框。

    选择关闭按钮,然后重新构建解决方案。

    【讨论】:

    • 我也是,这是因为我从我的 React 应用程序中添加了我的 App 文件夹,只是因为我想在 Visual Studio 中查看所有内容,尽管对应用程序使用 VS Code,对 Api 使用 Visual Studio
    • 这实际上是更好的答案。确保在配置管理器中未选中任何不是 VS 构建的项目。
    【解决方案6】:

    在我的场景中,我必须在我的 ASP.Net 网站上附带一个 Perl 解释器(不要问我为什么需要 Perl,很抱歉我提前这样做了!),其中包括导致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 文件中,作为 &lt;project&gt; 节点的子文件。

    要点:

    在通过 AspNetCompiler 任务运行 aspnet_compiler.exe 之前使用Exec 命令到attrib +H Directory,之后使用attrib -H Directory

    创建一个ItemGroup 以吸收所有仍需要复制的文件。

    运行Copy 任务,利用ItemGroup 将文件放在需要的位置,以便发布任务的其余部分包含它们。我们可以使用 Microsoft 在创作此任务时创建的所有变量,因此我们也可以在此处使用这些变量。

    修改原始任务的优点:对正常行为的改变很小,所以它应该仍然可以工作。

    修改原始任务的可能性:微软将来可能会更改此任务,使我们的副本过时。

    如果你没有我奇怪的要求,更简单的隐藏文件夹的解决方案如下:

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

    受 Arthur Nunes 回答中的评论 twamley 启发的回答。

    【讨论】:

      【解决方案7】:

      在我的例子中,它是 node_modules 文件夹。我在我的 csproj 文件中进行了此更改以修复它。

      这只会将 hidden 属性添加到 nod_modules 文件夹中,然后在 Razor 页面编译后取消隐藏。

      <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
        <Exec Command="attrib +H &quot;$(ProjectDir)node_modules&quot;" />
        <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
        <Exec Command="attrib -H &quot;$(ProjectDir)node_modules&quot;" />
      </Target>
      

      【讨论】:

        【解决方案8】:

        【讨论】:

          【解决方案9】:

          在我的情况下,问题是 IIS 中的父解决方案(根级项目)的 Web 配置在它的 Web 配置中有这个(错误地,不确定它是如何到达那里的)。花了很长时间才找到,因为我在我的解决方案/项目中所做的一切都不会以任何方式影响它。

          因此可能值得检查所有可能涉及的 web.config。

          【讨论】:

            【解决方案10】:

            对我来说,当我的网站的物理路径在 IIS 中无效时,就会显示此错误。要解决该问题,请右键单击网站(管理网站 -> 高级设置 -> 物理路径)。

            【讨论】:

              【解决方案11】:

              在我的情况下,在一台新机器上,安装了 VS2017 并从源代码管理中打开了一个 asp.net core 1.1 Web 应用程序。错误出现了。我安装了 node.js 并编译了项目。

              【讨论】:

                【解决方案12】:

                我对此错误的解决方案是结合此页面上的两个预先存在的答案。在我尝试在 VS 2017 机器上构建项目之前,我的 Web 项目目录中有一个 .h 文件没有引起问题。

                在我的情况下,我只是将其压缩,但结果似乎是您不能再将不相关的代码文件保留在 web 目录中,否则 VS 会在尝试编译它们时出错。

                【讨论】:

                  【解决方案13】:

                  我通过删除节点模块文件夹然后从 git bash 而不是从内置终端的 VS2019 运行 npm i 来解决它。

                  【讨论】:

                    【解决方案14】:

                    cppprovider.dll从Visual Studio 2015安装路径复制到:

                    C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies

                    【讨论】:

                      【解决方案15】:

                      一个简单的解决方法是引用CppCodeProvider.dll。 它可能位于

                      C:\Program Files (x86)\Microsoft Visual Studio{version}\{edition}\Common7\IDE\PublicAssemblies

                      例如:

                      C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\PublicAssemblies\CppCodeProvider.dll
                      

                      它将在 bin 文件夹中。

                      【讨论】:

                        【解决方案16】:

                        我将解决方案从 VS2019 移至 VS2022,并在尝试发布解决方案时出现此错误。这就是我使错误消失的方法。

                        • 右键单击引用>>添加引用
                        • 然后搜索 Microsoft.VisualC
                        • 勾选 Microsoft.VisualC 和 Microsoft.VisualC.VSCodeProvider
                        • 点击确定。 错误消失了!

                        【讨论】:

                          猜你喜欢
                          • 2018-02-27
                          • 2016-07-23
                          • 1970-01-01
                          • 1970-01-01
                          • 2020-09-21
                          • 1970-01-01
                          • 2019-03-26
                          • 1970-01-01
                          • 2023-03-29
                          相关资源
                          最近更新 更多