55

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

ASPNETCOMPILER 错误 ASPCONFIG:找不到 CodeDom 提供程序类型“Microsoft.VisualC.CppCodeProvider,CppCodeProvider,Version=10.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”。

这是构建服务器环境:

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

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

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

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

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

有谁知道可能导致此问题的原因?

更新

请看下面我的回答。

4

16 回答 16

84

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

于 2017-04-07T10:00:50.877 回答
35

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

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

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

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

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

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

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

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

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

于 2014-01-07T03:00:57.353 回答
23

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

根本原因

正如错误所暗示的那样,找不到程序集“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”。

于 2019-08-08T13:30:24.580 回答
10

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

<MvcBuildViews>false</MvcBuildViews>

于 2017-05-09T00:27:02.370 回答
6

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

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

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

在 Project contexts 表中,排除 Angular 网站(其中包含 node_modules)

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

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

于 2019-05-16T06:26:21.847 回答
4

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

关键要点:

在通过 AspNetCompiler 任务运行 aspnet_compiler.exe 之前和之后使用Exec命令。attrib +H Directoryattrib -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 启发的回答。

于 2017-05-26T19:49:20.747 回答
1

就我而言,它是 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>
于 2021-07-12T06:41:02.967 回答
0

尝试执行以下操作。

将 RequireTargetFramework 设置为 4.0。

链接:ASPNETCOMPILER 错误 ASPCONFIG:无法加载文件或程序集“Microsoft.VisualBasic.Activities.Compiler”或其依赖项之一

于 2013-12-12T15:29:44.530 回答
0

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

于 2016-05-16T14:17:17.523 回答
0

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

  • 右键单击引用>>添加引用
  • 然后搜索 Microsoft.VisualC
  • 勾选 Microsoft.VisualC 和 Microsoft.VisualC.VSCodeProvider
  • 点击确定。错误消失了!
于 2021-12-16T09:24:29.710 回答
0

一个简单的解决方法是引用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 文件夹中。

在此处输入图像描述

于 2021-08-19T09:50:28.317 回答
0

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

于 2017-08-15T01:35:44.033 回答
0

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

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

于 2015-09-08T06:08:51.277 回答
0

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

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

于 2021-03-27T07:06:26.793 回答
0

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

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

于 2018-06-20T09:13:31.860 回答
0

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

于 2021-01-27T16:22:58.667 回答