我正在尝试运行从 TFS (Team Foundation Server) 源代码控制中检索到的 ASP.NET MVC (model-view-controller) 项目。我已添加所有程序集引用,并且能够成功构建和编译,而不会出现任何错误或警告。
但是我在浏览器中收到以下错误:
找不到路径“C:\B8akWorkspace\B8akProject\B8akSolution\B8AK.Portal\bin\roslyn\csc.exe”的一部分。
这是错误页面的完整屏幕截图。
https://i.stack.imgur.com/lkxJP.png
经过几天的研究,我了解到 Roslyn 是一个提供高级编译功能的 .NET 编译器平台。但是,我不明白为什么我的构建试图找到 \bin\roslyn\csc.exe,因为我没有配置任何与 Roslyn 相关的东西。我也不打算在我的项目中使用 Roslyn。
TL;博士
在包管理器控制台中运行它:
Update-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform -r
更多信息
此问题与 Visual Studio 本身无关,因此建议添加构建步骤以复制文件的答案是一种解决方法。与手动将编译器二进制文件添加到项目中相同。
Roslyn 编译器来自 NuGet 包,并且该包的某些版本中存在/曾经存在错误(我不确切知道哪些版本)。解决方案是将该软件包重新安装/升级到无错误版本。最初在我在 2015 年写下答案之前,我通过在特定版本中安装以下软件包来修复它:
Microsoft.Net.Compilers 1.1.1
Microsoft.CodeDom.Providers.DotNetCompilerPlatform 1.0.1
然后我查看了 .csproj 并确保包的路径正确(在我的情况下为 ..\..\packages\*.*)在顶部的标签 <ImportProject>
和名称为“EnsureNuGetPackageBuildImports”的 <Target>
中底部。这是在 MVC 5 和 .NET Framework 4.5.2 上。
默认 VS2015 模板的问题在于编译器实际上并未复制到 tfr\bin\roslyn\
目录,而是复制到 {outdir}\roslyn\
目录
将此代码添加到您的 .csproj 文件中:
<Target Name="CopyRoslynFiles" AfterTargets="AfterBuild" Condition="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'">
<ItemGroup>
<RoslynFiles Include="$(CscToolPath)\*" />
</ItemGroup>
<MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
<Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>
清洁和重建对我有用!
Copying file from "C:\Users\medmondson\Source\UK\Portal\Branches\v12\Source\packages\Microsoft.Net.Compilers.1.3.2\tools\csi.exe" to "bin\Debug\roslyn\csi.exe".
中注意到了这一点
您的构建正在尝试查找 \bin\roslyn\csc.exe
,因为以下包已添加到您的项目中。只需查看您的 packages.config
文件,您可以同时拥有这两个文件
Microsoft.CodeDom.Providers.DotNetCompilerPlatform
Microsoft.Net.Compilers
什么是 Roslyn 以及谁在项目中添加了它们(包):如果您使用 .net Framework 4.5.2 使用 VS2015 创建项目,您可能已经注意到项目模板默认使用 Roslyn。实际上,Roslyn 是 Microsoft 的 .NET 语言的开源编译器之一。我们为什么要删除 Roslyn :如果您的项目有 Roslyn 引用并且您有兴趣将其部署在服务器上,您将在网站上收到不需要的错误,因为许多托管服务提供商仍未升级其服务器,因此不支持 Roslyn。要解决此问题,您需要从项目模板中删除 Roslyn 编译器。
如果您对使用 Roslyn 不感兴趣,请按照以下步骤将其删除
1. 删除 NuGet 包,使用 Nuget 包控制台中的以下命令
PM> Uninstall-package Microsoft.CodeDom.Providers.DotNetCompilerPlatform
PM> Uninstall-package Microsoft.Net.Compilers
2. 完成此操作后,您的 web.config 文件应该会自动更新。如果不是,请在 web.config
文件中查找以下代码,如果找到,则删除该代码段。
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"></compiler>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"></compiler>
</compilers>
</system.codedom>
<system.codedom>
块我的应用程序开始像魅力一样运行。
这是执行此操作的更多 MSBuild 方式。
<Target Name="CopyRoslynFiles" AfterTargets="AfterBuild" Condition="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'">
<ItemGroup>
<RoslynFiles Include="$(CscToolPath)\*" />
</ItemGroup>
<MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
<Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>
但我注意到 roslyn 文件也在我的 bin 目录中(而不是在文件夹中)。不过,该应用程序似乎可以工作。
答案为时已晚,但仍然发布它可以帮助任何人。按照以下步骤为我修复了错误:
删除包文件夹打开VS重建观察NuGet包已恢复,但bin\roslyn未创建卸载项目重新加载项目重建观察bin\roslyn现在已创建。
如 an issue in the Roslyn project on GitHub 中所述,一个解决方案(对我有用)是在 Visual Studio 中简单地卸载并重新加载项目。
在我重新加载项目之前,不会在构建或重建时创建“bin\roslyn”文件夹。
0. 快速修复
如 the currently highest voted answer 中所述,快速解决方法是使用包管理器 Tools > Nuget 包管理器 > 包管理器控制台,运行
更新包 Microsoft.CodeDom.Providers.DotNetCompilerPlatform -r
https://i.stack.imgur.com/fdWOj.png
1.重现错误的代码
下面是重现错误的代码:
https://user.it.uu.se/%7Ehesc0353/SrvrErr-reproduce.zip
(最初来自 https://github.com/aspnet/AspNetDocs/tree/master/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client/sample/server/ProductsApp)
考虑尝试上面 zip 文件中提供的示例代码。如果未进行任何更改,Ctrl+F5 将重现错误。
https://i.stack.imgur.com/u4Qc5.png
2. 更强大的解决方案
另一种解决方案是从项目的 Web.config
文件中删除一个属性。
(Web.config
与 .csproj
文件位于同一目录中。)
这将自动且静默地重新创建您的包(如果它们是)失踪。
在文本编辑器或 Visual Studio 中打开 Web.config
文件。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings></appSettings>
...
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
</configuration>
在标签配置 > system.codedom > 编译器 > compiler language="c#;cs;csharp",完全移除 type
属性。 – 简而言之,删除以 type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider,
开头的行。 1
Visual Studio 将负责其余的工作。 – 不再有 Server Error in '/' Application
。
3. HTTP 错误 403
在上面提供的示例中,现在按 Ctrl+F5 将导致 HTTP 错误 403。
https://i.stack.imgur.com/UfSsT.png
尝试将您的网络浏览器中的 http://localhost:64195
替换为 http://localhost:64195/api/products
。 Web API 现在可以正确显示:
https://i.stack.imgur.com/Fd5oQ.png
作为一种挑衅,我尝试从 Visual Studio 项目中删除整个 package
目录。
一旦项目重建,它就会自动且静默地重新创建。
参考
重现错误的项目文件
原项目
据推测,相同的修复程序适用于 Visual Basic 和 C#,但我还没有尝试过。
我按照这些步骤操作,效果很好
删除所有 bin 和 obj 文件夹
清理解决方案并重建
在 powershell 中运行此命令
Update-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform -r
我在运行项目时也遇到了同样的问题。这是我遵循的步骤。
在解决方案中右键单击选择清理解决方案清理成功后,再次构建您的项目再次运行项目
这次我没有看到同样的错误。这按预期工作。
清洁解决方案重建解决方案,这两个步骤对我有用。
git
中的一个分支时,我不小心按了 Ctrl C
,它搞砸了我的 repo。 git reset --hard
不起作用,所以我 git clean -xdf
不得不重新构建项目。但是我遇到了这个错误,所以我只是再次清理并重建了项目,它对我有用。
在尝试了所有没有雪茄的修复后,我通过在 Visual Studios 中更新这个 Nuget 包来修复它:
Microsoft.CodeDom.Providers.DotNetCompilerPlatform
我的是从 1.0.0 到 2.0.0 供参考(错误不再显示)
roslyn
文件夹。我在我的 csproj 中也没有看到“roslyn”参考。 可能 Target Name="CopyRoslyn...
是 VS2015 的东西,在我拥有的 2017 (版本)中不是必需的。值得注意的是:自从我更新了 DotnetCompilerPlatform 之前 我尝试添加一个复制目标(我提到的那个)我有一个更干净的 csproj。
对于 VS 2019,完全删除以下节点:
<system.codedom>
</system.codedom>
https://i.stack.imgur.com/gOv27.png
您需要安装 Microsoft.CodeDom.Providers.DotNetCompilerPlatform.BinFix,专为该错误创建
右键单击您的项目并选择管理 Nuget 包
找到“Microsoft.CodeDom.Providers.DotNetCompilerPlatform”
只需更新到较旧或较新的版本(不管是哪个版本),然后再次更新回您的原始版本。
这将重新安装包的所有依赖项和文件(如 csc.exe)
https://i.stack.imgur.com/sDltU.png
就我而言,在尝试任何其他解决方案之前,我切换到“发布”配置,重建(文件夹已创建),然后切换回“调试”,而文件夹保持不变。
这是从旧解决方案的源代码控制中签出的,显然原始(自动)包还原和构建项目并未在 bin 目录中创建该文件夹。
请注意,在撰写本文时,被指责的组件已达到 v.2。
更新 nuget 包对我有用 右键单击解决方案 > 管理 NuGet 包以获取解决方案并更新所有包,特别是:Microsoft.Net.Compilers 和 Microsoft.CodeDom.Providers.DotNetCompilerPlatform
因此,Rob Cannon's answer 基本上对我有用,但我不得不调整一些选项。具体来说,我必须删除目标上的条件,并更改 Include 属性,因为在我们的构建服务器上构建项目时,$CscToolPath 是空的。奇怪的是,在本地运行时 $CscToolPath 不是空的。
<Target Name="CopyRoslynFiles" AfterTargets="AfterBuild" >
<ItemGroup>
<RoslynFiles Include="$(SolutionDir)packages\Microsoft.Net.Compilers.1.1.1\tools\*" />
</ItemGroup>
<MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
<Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>
就我而言,当 Jenkins 尝试在 Octopus 中部署它时遇到以下错误:
MSBUILD : OctoPack error OCT-1676060969: Failed to build the path for '\bin\roslyn\csc.exe' relative to 'T:\workspace\machine.engine\Machine.engine.Test': Invalid URI: The format of the URI could not be determined.. See the inner exception for more details. [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: System.Exception: Failed to build the path for '\bin\roslyn\csc.exe' relative to 'T:\workspace\machine.engine\Machine.engine.Test': Invalid URI: The format of the URI could not be determined.. See the inner exception for more details. ---> System.UriFormatException: Invalid URI: The format of the URI could not be determined. [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind) [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: at System.Uri..ctor(String uriString) [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: at OctoPack.Tasks.Util.OctopusPhysicalFileSystem.GetPathRelativeTo(String fullPath, String relativeTo) in Z:\buildAgent\workDir\20ba9f2e0d5e4022\source\OctoPack.Tasks\Util\OctopusPhysicalFileSystem.cs:line 211 [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: --- End of inner exception stack trace --- [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: at OctoPack.Tasks.Util.OctopusPhysicalFileSystem.GetPathRelativeTo(String fullPath, String relativeTo) in Z:\buildAgent\workDir\20ba9f2e0d5e4022\source\OctoPack.Tasks\Util\OctopusPhysicalFileSystem.cs:line 224 [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: at OctoPack.Tasks.CreateOctoPackPackage.AddFiles(XContainer nuSpec, IEnumerable`1 sourceFiles, String sourceBaseDirectory, String targetDirectory, String relativeTo) in Z:\buildAgent\workDir\20ba9f2e0d5e4022\source\OctoPack.Tasks\CreateOctoPackPackage.cs:line 443 [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
MSBUILD : OctoPack error OCT-1676060969: at OctoPack.Tasks.CreateOctoPackPackage.Execute() in Z:\buildAgent\workDir\20ba9f2e0d5e4022\source\OctoPack.Tasks\CreateOctoPackPackage.cs:line 190 [T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj]
Done Building Project "T:\workspace\machine.engine\Machine.engine.Test\Machine.engine.Test.csproj" (default targets) -- FAILED
原因
花了一些时间后,我使用了一个使用 Microsoft.Net.Compilers
的内部开发组件。内部组件使用 Microsoft.Net.Compilers
的原因是为了克服这个问题 (C#: throw invalid expression compilation) 并以这种方式解决 (How to use C# 7 with Visual Studio 2015?)。这导致,当我在主程序上安装组件时,Microsoft.Net.Compilers
会自动添加。
解决方案
我的解决方法是,从我们的内部组件中卸载(按照@malikKhalil 回答)
PM> Uninstall-package Microsoft.CodeDom.Providers.DotNetCompilerPlatform
PM> Uninstall-package Microsoft.Net.Compilers
并在 Jenkins 中选择 C# 7 编译器而不是 C# 6 并重新构建,这是为了确保一切正常工作和构建。
最后,在我的主程序中,我尝试更新我的内部组件。一切都比重新构建。它的构建没有任何问题或问题。
根据上面 Daniel Neel 的评论:
Microsoft.CodeDom.Providers.DotNetCompilerPlatform Nuget 包的 1.0.3 版适用于我,但 1.0.6 版会导致此问题中的错误
降级到 1.0.3 为我解决了这个问题。
在我的情况下,我只需要转到 Visual Studio 解决方案资源管理器(Web 应用程序项目)中的 bin 目录并直接包含 roslyn 项目。通过右键单击文件夹并选择包含在项目中。并再次签入解决方案以触发构建过程。
默认情况下不包括 roslyn 文件夹。
将 Microsoft.CodeDom.Providers.DotNetCompilerPlatform
从 1.0.0 升级到 1.0.1 为我解决了这个问题。
如果您要添加 ASPNETCOMPILER 以在 MVC 中编译 Razor 视图,例如在 this StackOverflow question 中,则将 PhysicalPath 更改为 Roslyn nuget 包所在的位置(通常通过 $CscToolPath 变量指向):
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(CscToolPath)" />
就我而言,只需删除 bin 文件夹中的所有内容并重新编译即可为我完成所有工作。
打开项目文件并使用 Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0... 删除所有引用。
打开 web.config 并删除所有 system.codedom 编译器属性
默认 VS2015 模板的问题在于编译器实际上并未复制到 {outdir}_PublishedWebsites\tfr\bin\roslyn\
目录,而是复制到 {outdir}\roslyn\
目录。这可能与您的本地环境不同,因为 AppHarbor
使用输出目录构建应用程序,而不是“就地”构建解决方案。
要修复它,请在 xml 块 <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">...</Target>
之后的 .csproj
文件末尾添加以下内容
<PropertyGroup>
<PostBuildEvent>
if not exist "$(WebProjectOutputDir)\bin\Roslyn" md "$(WebProjectOutputDir)\bin\Roslyn"
start /MIN xcopy /s /y /R "$(OutDir)roslyn\*.*" "$(WebProjectOutputDir)\bin\Roslyn"
</PostBuildEvent>
</PropertyGroup>
在我的例子中,类似于 Basim,有一个 NuGet 包告诉编译器我们需要 C# 6,而我们不需要。
我们必须删除 NuGet 包 Microsoft.CodeDom.Providers.DotNetCompilerPlatform
,然后将其删除:
在 system.codedom
节点中,您可以看到它引入 roslyn 的原因:compilerOptions="/langversion:6
删除解决方案资源管理器中的 Bin 文件夹并再次构建解决方案。那将解决问题
当一切在本地主机上完美运行时,我在服务器上安装我的应用程序时遇到了同样的问题。
这些解决方案都没有奏效,我总是遇到同样的错误:
Could not find a part of the path 'C:\inetpub\wwwroot\myApp\bin\roslyn\csc.exe'
我最终这样做了:
在我的设置项目上,右键单击,查看 > 文件系统
创建一个 bin/roslyn 文件夹
选择添加 > 文件并从 packages\Microsoft.Net.Compilers.1.3.2\tools 添加所有文件
这解决了我的问题。
不定期副业成功案例分享