title author date CreateTime categories
Roslyn 通过 NuGet 库修改应用程序入口函数
lindexi
2019-4-21 17:37:1 +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 写命令行程序

更多编译相关请看手把手教你写 Roslyn 修改编译

2019-4-21-Roslyn-通过-NuGet-库修改应用程序入口函数的更多相关文章

  1. 2019-11-29-Roslyn-通过-NuGet-库修改应用程序入口函数

    title author date CreateTime categories Roslyn 通过 NuGet 库修改应用程序入口函数 lindexi 2019-11-29 08:37:49 +080 ...

  2. 小白学 Python 爬虫(21):解析库 Beautiful Soup(上)

    小白学 Python 爬虫(21):解析库 Beautiful Soup(上) 人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前 ...

  3. vs中使用过的扩展和好的nuget库

    扩展 ReAttach ReAttach gives you an easy way to ReAttaching your prior debug targets. ReAttach stores ...

  4. 2019年11个javascript机器学习库

    Credits: aijs.rocks 虽然python或r编程语言有一个相对容易的学习曲线,但是Web开发人员更喜欢在他们舒适的javascript区域内做事情.目前来看,node.js已经开始向每 ...

  5. 2019.3.18考试&2019.3.19考试&2019.3.21考试

    2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...

  6. 凹凸曼的修改zencart 程序(经典!)

    ==================================================================================================== ...

  7. 背景建模技术(三):背景减法库(BGS Library)的基本框架与入口函数main()的功能

    背景减法库(BGS Library = background subtraction library)包含了37种背景建模算法,也是目前国际上关于背景建模技术研究最全也最权威的资料.本文将更加详细的介 ...

  8. gcc 头文件是用户应用程序和函数库之间的桥梁和纽带 功能的真正逻辑实现是以硬件层为基础

    gcc GCC, the GNU Compiler Collection - GNU Project - Free Software Foundation (FSF) http://gcc.gnu.o ...

  9. 用PYTHON首选的GUI库WXPYTHON做程序界面

    大家好,我是A8U神经网络,今天又要跟大家分享一下wxWidgets开发神经网络程序界面的一些经验,希望对开发有兴趣的朋友有所帮助.跨平台的GUI工具库以GTK +,Qt和wxWidgets闻名. G ...

随机推荐

  1. HDU 6614 AND Minimum Spanning

    Time limit 1000 ms Memory limit 131072 kB OS Windows 中文题意 给一张n个点的无向完全图(输入一个n就完事了),每个点标号为1~n,每条边的边权为它 ...

  2. Android环境配置之正式版AndroidStudio1.0

    昨天看见 Android Studio 1.0 正式版本发布了:心里挺高兴的. 算是忠实用户了吧,从去年开发者大会一开始出现 AS 后就开始使用了:也是从那时开始就基本没有用过 Eclipse 了:一 ...

  3. 20180829-Java多线程编程

    Java 多线程编程 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分. 程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...

  4. RedisTemplate访问Redis数据结构(前言)

    Redis五种基本数据结构 redis提供键值对的形式对数据进行存储.支持五种数据类型:String(字符串),List(链表),Hash(散列),Set(无序集合),ZSet(有序集合).下面是网上 ...

  5. [洛谷P3940]:分组(贪心+并查集)

    题目传送门 题目描述 小$C$在了解了她所需要的信息之后,让兔子们调整到了恰当的位置.小$C$准备给兔子们分成若干个小组来喂恰当的胡萝卜给兔子们吃.此时,$n$只兔子按一定顺序排成一排,第$i$只兔子 ...

  6. 20175221曾祥杰 实验三《敏捷开发与XP实践》

    实验三<敏捷开发与XP实践> 实验报告封面 课程:Java程序设计 班级:1752班 姓名:曾祥杰 学号:20175221 指导教师:娄嘉鹏 实验日期:2019年4月30日 实验时间:13 ...

  7. Microsoft Visual Studio 2013 Language Pack

    Microsoft Visual Studio 2013 Language Pack Microsoft Visual Studio 2013 各版本语言包下载地址: https://my.visua ...

  8. 三十三、python中configparser配置文件相关操作

    配置文件ini [a1]age = 18sex = 'man' [a2]age = 19sex = 'woman'name = False 1.对配置文件进行操作 import configparse ...

  9. Vue音乐播放器(三):项目目录介绍,以及图标字体、公共样式等资源准备

    我们所有的开发都是基于修改src下面的目录 里面的文件去做开发即可 stylus的使用是需要下载stylus-loader的包的 渲染效果 配置修改eslintrc.js 配置了webpack.bas ...

  10. plsql汉化后,表格列注释中文显示成?号