代码改变世界

天行健,君子以自强不息

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

摘要

基于.NET Framework 4.8.1的传统ASP.NET Web程序,使用Gitlab Runner自动集成,在发布的网站目录下,没有bin\Roslyn文件夹。这里涉及到容易被忽视的Roslyn编译器的知识点。

Roslyn是什么?

在我们的ASP.NET Web项目源代码中有什么体现?

1、web.config下有配置节点

一般在web.config末尾能看到如下配置。

<configuration>
    ………………
	<system.codedom>
		<compilers>
			<!-- For Roslyn -->
			<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.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=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
		</compilers>
	</system.codedom>

</configuration>

上边需要注意最新的包的版本号,目前是4.1.0.0最新。

2、Web项目需要引用两个包

<Project ToolsVersion="12.0" DefaultTargets="Build" Sdk="Microsoft.NET.Sdk.Web" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	
	<ItemGroup>
		<PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="4.1.0" />
		<PackageReference Include="Microsoft.Net.Compilers" Version="4.2.0">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
	</ItemGroup>
    
</Project>

Microsoft.CodeDom.Providers.DotNetCompilerPlatform包和嵌入的文件

img

Microsoft.Net.Compilers包和嵌入的文件

img

在MSBuild过程中,Roslyn要做什么?

在我给msbuild.exe带上/v:diag后,得到了详细的日志:

PS:Gitlab Runner控制台的日志超过了4M默认大小,最后修改了Gitlab Runner的日志限制为8M,才得到了如下珍贵的内容。

……………………省略……………………

WebProjectOutputDir = X:\gitlab-runner\builds\01\nxx6sgtBR\0\loda.framework.erp\framework\passport\单点登录系统\Yee.Passport.Web
WebProjectOutputDirInsideProject = True
WebProjectOutputDirInsideProjectDefault = True

……………………省略……………………

标“CopyRoslynCompilerFilesToOutputDirectory: (目标 ID: 725)”(目标“PrepareForRun”依赖于它):
任务“Copy” (任务 ID: 612)
  任务参数:DestinationFolder=X:\gitlab-runner\builds\01\nxx6sgtBR\0\loda.framework.erp\framework\passport\单点登录系统\Yee.Passport.Web\bin\roslyn (任务 ID: 612)
  任务参数:SkipUnchangedFiles=True (任务 ID: 612)
  任务参数:
      SourceFiles=
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\csc.exe
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\csc.exe.config
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\csc.rsp
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\csi.exe
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\csi.exe.config
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\csi.rsp
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.Build.Tasks.CodeAnalysis.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.CodeAnalysis.CSharp.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.CodeAnalysis.CSharp.Scripting.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.CodeAnalysis.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.CodeAnalysis.Scripting.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.CodeAnalysis.VisualBasic.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.CSharp.Core.targets
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.DiaSymReader.Native.amd64.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.DiaSymReader.Native.x86.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.Managed.Core.CurrentVersions.targets
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.Managed.Core.targets
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\Microsoft.VisualBasic.Core.targets
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Buffers.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Collections.Immutable.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Memory.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Numerics.Vectors.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Reflection.Metadata.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Runtime.CompilerServices.Unsafe.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Text.Encoding.CodePages.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\System.Threading.Tasks.Extensions.dll
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\vbc.exe
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\vbc.exe.config
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\vbc.rsp
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\VBCSCompiler.exe
          C:\Users\loda\.nuget\packages\microsoft.codedom.providers.dotnetcompilerplatform\4.1.0\tools\roslyn-4.1.0\VBCSCompiler.exe.config (任务 ID: 612)
  任务参数:Retries=0 (任务 ID: 612)
  正在创建目录“X:\gitlab-runner\builds\01\nxx6sgtBR\0\loda.framework.erp\framework\passport\单点登录系统\Yee.Passport.Web\bin\roslyn”。 (任务 ID: 612)

上述日志是关键的内容,有两个看点:

  • WebProjectOutputDir没有使用我在msbuild.exe传入的参数 /p:WebProjectOutputDir=$web_output_path
    很奇怪,网站的确发布到了msbuild.exe指定的WebProjectOutputDir目录下。
  • Roslyn工作正常,只是把产物拷贝到了解决方案之内,Gitlab Runner去了接下来的stage发布网站,是找不到上一个stage的目录下的文件的。

解决办法

在.csproj的Project定义一个自定义复制的任务:

<Target Name="CopyRoslynCompilerFilesToOutputDirectory2" AfterTargets="_CopyWebApplication">
	<ItemGroup>
		<RoslynFiles Include="$(CscToolPath)\*" />
	</ItemGroup>
	<PropertyGroup>
		<!--<LodaRoslynFolder>$(WebProjectOutputDir)\bin\roslyn</LodaRoslynFolder>-->
	</PropertyGroup>
	<MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
	<Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>

上边的配置的看点是AfterTargets="_CopyWebApplication",之所以设置在“_CopyWebApplication”这个Target之后,是我发现msbuild.exe最终把网站发布到了我指定的WebProjectOutputDir。因此_CopyWebApplication这个Target之后,WebProjectOutputDir这个参数是正常采用了msbuild.exe中接收到的参数。

至于Roslyn工作的时候,为什么日志里清晰的表明WebProjectOutputDir不采用msbuild.exe接收的参数呢?暂时没时间去查文档了。

后记

折腾了接近2天,写出来让大家少走弯路。已经很少有基于.NET Framework的项目还要老树发新枝了吧?

posted on 2024-05-27 18:56  终南山人  阅读(58)  评论(0编辑  收藏  举报