ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Roslyn通过NuGet库修改应用程序入口函数

2021-06-29 10:05:02  阅读:272  来源: 互联网

标签:文件 System 应用程序 NuGet 文件夹 Roslyn Program targets lindexi


title author date CreateTime categories
Roslyn 通过 NuGet 库修改应用程序入口函数 lindexi 2019-11-29 08:37:49 +0800 2019-04-21 16:46:29 +0800 Roslyn MSBuild 编译器

我和小伙伴说只要你安装我的 NuGet 库无论你怎么做,都会调用我的 Main 函数,默认的主函数不会调用

在程序编译的时候可以通过指定 StartupObject 指定某个命名空间里面的某个类的主函数作为入口

在做 NuGet 包可以通过 Build 文件夹里面添加一些有趣的代码,简单的调试请创建一个简单的 Nuget 包,创建方法请看 VisualStudio 使用新项目格式快速打出 Nuget 包

在做一个 Nuget 包的时候可以直接纯手工写一个 nuget 包,或者修改现有的 Nuget 包文件

如我使用新项目格式打出一个 lindexi 的包,我通过安装本地nuget包

安装完成可以在用户名的 .nuget 文件夹找到

c:\Users\lindexi\.nuget\packages\lindexi\1.0.0\

在这个文件夹里面创建 Build 文件夹,在 Build 文件夹创建 nuget 库的 id .targets 文件,如我这里的是 lindexi 就创建 lindexi.targets 文件,此时看到的文件夹如下

│  .nupkg.metadata
│  lindexi.1.0.0.nupkg
│  lindexi.1.0.0.nupkg.sha512
│  lindexi.nuspec
│
├─build
│      lindexi.targets
│
├─package
│  └─services
│      └─metadata
│          └─core-properties
└─_rels

在 lindexi.targets 文件里面可以尝试添加代码,在测试的项目每次都需要运行 git clean -xdf 清理之后才可以使用 dotnet run 运行,这样就可以减少打包

在 targets 文件里面写的内容,只需要下一次在测试项目使用 dotnet run 就会使用

先通过WriteLinesToFile写一个新的文件,这个文件里面包括主函数

然后在 StartupObject 指定入口函数为刚才创建的文件

在 targets 文件定义临时文件的存放的路径

  <PropertyGroup>
    <_GeneratedEntryPointFile>$(IntermediateOutputPath)$(MSBuildProjectName).Program.g$(DefaultLanguageSourceExtension)</_GeneratedEntryPointFile>
  </PropertyGroup>

这里的 $(IntermediateOutputPath) 是常量,更多请看项目文件中的已知属性(知道了这些,就不会随便在 csproj 中写死常量啦) - walterlv

上面代码是定义路径是 obj 文件夹的 xx.Program.g.cs 的文件

然后写入新的代码

     <PropertyGroup>
         <_GeneratedProgramFileContent >

<![CDATA[
        // <auto-generated>This file was created automatically</auto-generated>
        using System;
        using System.Runtime.CompilerServices;

        namespace Lindexi
        {
            [CompilerGenerated]
            class Program
            {
                static void Main(string[] args)
                {
                    Console.WriteLine("林德熙是逗比");
                }
            }
        }
       
]]>

       </_GeneratedProgramFileContent>

    </PropertyGroup>

将代码写入到文件可以使用WriteLinesToFile写入到上面定义的文件

注意文件里面有逗号,在Roslyn how to use WriteLinesToFile to write the semicolons to file告诉大家如何解决逗号的坑

    <WriteLinesToFile File="$(_GeneratedEntryPointFile)"
                      Overwrite="true"
                      Lines="$([MSBuild]::Escape($(_GeneratedProgramFileContent)))"
                      Encoding="Unicode"/>

文件写入之后还需要添加文件到编译

    <ItemGroup>
      <Compile Include="$(_GeneratedEntryPointFile)" />
    </ItemGroup>

因为文件需要编译,所以这个时机需要 CoreCompile 之前,需要设置启动项目为这个文件,全部代码有点长

<Project>

  <PropertyGroup>
    <_GeneratedEntryPointFile>$(IntermediateOutputPath)$(MSBuildProjectName).Program.g$(DefaultLanguageSourceExtension)</_GeneratedEntryPointFile>
  </PropertyGroup>

  <Target Name="_GenerateRealEntryPointType"
          BeforeTargets="CoreCompile"
          DependsOnTargets="PrepareForBuild;CoreGenerateDragonFruitProgramFile"
          Condition="'$(DisableAutoGeneratedMain)' != 'true'">
    <PropertyGroup>
      <StartupObject>Lindexi.Program</StartupObject>
    </PropertyGroup>
  </Target>

  <Target Name="CoreGenerateDragonFruitProgramFile"
          Condition="'$(Language)' == 'C#'"
          Outputs="$(_GeneratedEntryPointFile)">

      <PropertyGroup>
         <_GeneratedProgramFileContent >

<![CDATA[
        // <auto-generated>This file was created automatically</auto-generated>
        using System;
        using System.Runtime.CompilerServices;

        namespace Lindexi
        {
            [CompilerGenerated]
            class Program
            {
                static void Main(string[] args)
                {
                    Console.WriteLine("林德熙是逗比");
                }
            }
        }
       
]]>

       </_GeneratedProgramFileContent>

    </PropertyGroup>

    <WriteLinesToFile File="$(_GeneratedEntryPointFile)"
                      Overwrite="true"
                      Lines="$([MSBuild]::Escape($(_GeneratedProgramFileContent)))"
                      Encoding="Unicode"/>

    <ItemGroup>
      <Compile Include="$(_GeneratedEntryPointFile)" />
    </ItemGroup>
  </Target>
</Project>

通过这个方法就可以修改应用程序的入口,将入口程序修改为特殊的,那么这样有什么用?在System.CommandLine就使用这个方法让用户可以写出多个参数的主函数

关于System.CommandLine请看dotnet 使用 System.CommandLine 写命令行程序

 

标签:文件,System,应用程序,NuGet,文件夹,Roslyn,Program,targets,lindexi
来源: https://blog.51cto.com/u_11283245/2952346

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有