- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直无法让 C# 代码生成在我的 .NET 项目中可靠地工作。我可以让它构建(a)当源文件预先存在时或(b)当源文件预先不存在时。我无法在两种情况下使用相同的设置。
为什么这很重要:如果我在我的开发机器上构建,我可能以前构建过代码,所以我需要它来重新生成现有的源代码。但是,在构建机器上构建时,这些文件不存在,因此在这种情况下我需要它从头开始生成代码。
复制它只需要一个 csproj 和一个源文件。
这是一个引用示例的简单程序 GeneratedClass
:
class Program
{
public static void Main(string[] args)
{
System.Console.WriteLine(GeneratedClass.MESSAGE);
}
}
这是我能想到的最简单的 csproj 文件。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Target Name="GenerateCode" BeforeTargets="CoreCompile">
<!-- Removing the source code beforehand makes no difference
<Exec Command="rm $(ProjectDir)Generated/*.cs" IgnoreExitCode="true" />
-->
<Exec Command="echo 'class GeneratedClass { public static int MESSAGE = 1; }' > Generated/GeneratedClass.cs" />
<!-- Toggling this setting will cause failures in some scenarios and success in others
<ItemGroup>
<Compile Include="Generated/*$(DefaultLanguageSourceExtension)" />
</ItemGroup> -->
</Target>
</Project>
创建一个名为“Generated”的空目录。
要构建,请运行 dotnet build
从 csproj 和 Program.cs 文件所在的目录。
我在 Linux 上运行 .NET Core 2.0.3。我的 Docker 构建容器使用 microsoft/dotnet:2.0-sdk
图片;我可以在 Docker 内部和外部复制该问题。
请注意,在上面的 csproj 文件中有一个 <Compile Include
被注释掉的设置。另请注意,多次运行构建将生成代码。 (可手动删除代码,复制构建开始时代码不存在的情况。)
这是我发现错误和未发现错误的矩阵:
+----------------------+----------------------+-----------------------------------+| Compile Include=...? | Code Already Exists? | Result |+----------------------+----------------------+-----------------------------------+| Present | YES | ERROR! "specified more than once" || Present | NO | SUCCESS! || Commented Out | YES | SUCCESS! || Commented Out | NO | ERROR! "does not exist" |+----------------------+----------------------+-----------------------------------+
“多次指定”错误的完整错误文本:/usr/share/dotnet/sdk/2.0.3/Roslyn/Microsoft.CSharp.Core.targets(84,5): error MSB3105: The item "Generated/GeneratedClass.cs" was specified more than once in the "Sources" parameter. Duplicate items are not supported by the "Sources" parameter. [/home/user/tmp/CodeGenExample.csproj]
“不存在”错误的完整错误文本:Program.cs(5,34): error CS0103: The name 'GeneratedClass' does not exist in the current context [/home/user/tmp/CodeGenExample.csproj]
我最好的猜测是我的 BeforeTargets="CoreCompile"
是错的。我在那里尝试了很多不同的值(抱歉不记得是哪些),而且我总是遇到这样或那样的问题。这只是一个猜测。
我做错了什么?
最佳答案
免责声明:您的实际项目中似乎有上述内容中没有的内容,因此我不确定此解决方案是否有效。
以下是一个 hacky 方法,因为它的行为并不像它应该的那样。
然而,它可能足以满足您的目的 - 这由您决定。我说它有问题的原因是预构建文件删除似乎执行了不止一次。1
我的 csproj 文件是这样做的:
在此处完成 csproj 文件:
<Project InitialTargets="CleanGen" Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Target Name="CleanGen">
<Exec Command="echo 'Cleaning files...'" />
<Exec Command="rm $(ProjectDir)Generated/*$(DefaultLanguageSourceExtension)" IgnoreExitCode="true" />
</Target>
<Target Name="GenerateCode" BeforeTargets="CoreCompile">
<Exec Command="echo 'Generating files... $(NuGetPackageRoot)'" />
<Exec Command="echo 'class GeneratedClass { public static int MESSAGE = 1; }' >> Generated/GeneratedClass.cs" />
<ItemGroup>
<Compile Include="Generated/*$(DefaultLanguageSourceExtension)" />
</ItemGroup>
</Target>
</Project>
这看起来确实比它应该做的要难...
1 OP 指出,为避免多次执行 rm
命令,您可以将 Condition
添加到 Exec
:
<Exec
Command="rm $(ProjectDir)Generated/*$(DefaultLanguageSourceExtension)"
Condition="Exists('$(ProjectDir)Generated/GeneratedClass$(DefaultLanguageSourceExtension)')" />
不幸的是,Exists
不接受 glob,因此您必须至少指定一个您知道将在该文件夹中生成的特定文件。通过这种妥协,您还可以摆脱 IgnoreExitCode="true"
,因为它只应在有要删除的文件时执行。
关于c# - 在 .NET Core 2.x csproj 项目中可靠地生成 C# 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49075282/
我正在尝试运行以下内容:: Press to see code - name: Snapshot BI nodes hosts: [CLUSTER-BI,CLUSTER-BI-REPL
在这里尝试心理重置:我尝试使用 MSMQ 创建一个可靠、持久的堆栈,但没有成功 所以更一般地说: 我有生产者(一个 web 服务,虽然“只有一个”,但也是多线程的)/消费者(多个进程,根据需要设置)。
试图为分布式系统找到一个商业日志框架。此框架必须允许远程服务器上的 .NET 应用程序记录可以在中央位置收集的消息。如果可能,中央位置应将消息存储在 SQL Server 数据库中。 要求: 能够在远
我正在开发 Restful 服务,我们将在数据库中插入/更新新记录。 由于REST使用HTTP进行通信,而HTTP并不可靠,我担心如果连接失败,请求可能无法发送到服务器。 我在 link 中找到的建议
我正在尝试实现一个页面,员工可以在其中登录并添加、修改、更新工作案例。 我有一个选择列表,其中包含从数据库加载的数据(员工姓名)。在这个数据库中,我有基本信息、用户名、ID、密码、电子邮件。 选择列表
我在 C 代码和 Python 代码之间(偶尔)得到略有不同的计算结果,并设法找到了一个例子。在 Python 中,我得到了这个: >>> print "%.55f" %\ ... (-2.49999
例如如果我将计时器设置为每天午夜到期,如果一个“失火”(例如,由于服务器关闭而不会触发回调)会发生什么?我在文档中找不到它。 有没有办法让这个定时器在服务器重启时立即触发回调? PS:我了解 Quar
我有一组不同长度的非零序列,我正在使用 Keras LSTM 对这些序列建模。我使用 Keras Tokenizer 进行分词(分词从 1 开始)。为了使序列具有相同的长度,我使用了填充。 填充示例:
我遇到了一个非常有趣的可靠 session 行为。我正在使用 netTcp 绑定(bind) + 双工 channel + 可靠 session 。 当我尝试在 channel.faulted 上收听
问题: 给定表 table_a 和 table_b,每当 table_a 更新时,我都需要可靠地(并发地)执行这样的操作: SELECT table_a 中的一些行。 在应用程序代码中计算一些内容。
我们目前的设计 环境 Redis 2.8.17 我们已经实现了我们的可靠队列,使用类似于 redis 文档中描述的模式的模式,在 RPOPLPUSH 下 但是,考虑到其阻塞性质,我们正在使用 BRPO
在我们的 WCF 应用程序中,我正在尝试配置可靠的 session 。 服务: 客户:
我使用这个 Delphi 7 代码来检测 Internet Explorer 是否正在运行: function IERunning: Boolean; begin Result := FindWi
我正在准备构建一个应用程序,该应用程序能够向 GPS 设备发送/接收航路点。通过一些谷歌搜索,我发现了很多可能对此目的有用的库: Java Chaeron GPS GPSLib4J Python Py
我有几个关于 WCF 可靠 session 可靠性的问题: WCF 是否在重试期间重新序列化消息? 2。如果 1 是正确的 - 它是否在消息参数被处理后发生? 3. 如果 2 是正确的 - 是否有任何
对于使用 $(this)[0].defaultValue 来确定文本框值是否已从原始值发生变化的一些反馈,我将不胜感激,例如 //keyUp event if($(this)[0].defaultVa
我正在开发一个具有以下特征的实时应用程序: 数百个客户端将同时插入行/文档,每个客户端每隔几秒插入一行。 大部分仅追加;几乎所有的行/文档,一旦插入,就永远不会改变。 只有当数据刷新到磁盘时,客户端才
场景:最终用户(不受信任的)提供了一个字符串,例如 "Hello, {name}!" .在服务器上,我想以 my_string.format(name="Homer") 的形式对该用户提供的字符串进行
我在推送通知方面遇到一些问题。我们使用 Firebase 来推送通知。问题是我可以在一台 iPhone 上正确接收 PushNotifications,但无法在另一台 iPhone 上接收它们。我在
从 python 到 c++,这是我能得到的最接近 python 的装饰器。 这个解决方案感觉有点像 hack,因为在要装饰的函数之后运行的代码在 Timer 析构函数中是隐式调用的。不过它确实有效。
我是一名优秀的程序员,十分优秀!