我真的很喜欢这种新.csproj格式.它比可怕的(有限的)好得多project.json.
但是,有一件事我想解决.我已将我的(多个)测试项目合并到一个多目标项目中.
<TargetFrameworks>netcoreapp1.0;net40;net35</TargetFrameworks>
Run Code Online (Sandbox Code Playgroud)
但是,在Visual Studio中的测试资源管理器中似乎没有任何工具来选择目标框架 - 它总是只运行第一个.我找到了一个解决方法 - 添加一个<TargetFramework>具有特定框架的元素......
<TargetFramework>net35</TargetFramework>
Run Code Online (Sandbox Code Playgroud)
但是,有没有办法选择目标框架而不需要手工编辑MSBuild(.csproj)文件?我正在寻找GUI中的一些选项来执行此操作 - 特别是因此我不必记住编辑.csproj文件以便在调试测试之前切换框架或记住在发布之前必须删除此行.
我已经阅读了一些帖子(参见下面的参考资料),还没有找到特定于我的技术堆栈的最佳实践指南.
目标:创建一个NuGet包,其目标是使用MSBuild和NuGet通过TeamCity从单个.csproj文件构建的多个.NET框架.
约束:
我有两种方法:
创建单个构建配置.它将包含三个构建步骤:编译.NET 3.5,编译.NET 4.0,使用NuGet打包.每个构建步骤都取决于最后一个成功.我用这种方法看到的唯一真正的问题(希望有一个我不知道的解决方案)是每个构建步骤都需要自己的一组构建参数(例如,system.TargetFrameworkVersion和system.OutputPath)来指定DLL的唯一位置(例如,bin\release\v3.5和bin\release\v4.0),以便NuGet包步骤能够根据.nuspec文件中的Files部分执行其操作.
创建多个构建配置.每个构建步骤的一个构建配置.使用这种方法,很容易解决TargetFrameworkVersion和OutputPath构建参数问题,但我现在必须创建快照依赖项并在构建中共享程序集版本号.它也会占用构建配置插槽,这对我们来说是好的(但不是最佳的),因为我们拥有Enterprise许可证.
选项#1似乎是显而易见的选择.选项#2感觉很脏.
所以我的两个问题是:
参考文献:
msbuild teamcity .net-framework-version multitargeting nuget
我想让使用Visual Studio的开发人员能够针对替换.NET的自定义框架编写程序(类似于Windows Phone和Silverlight框架,它们不是现有框架的子集或配置文件),并且具有完整的IntelliSense支持,并且所有.
Visual Studio 2010支持多目标,如果安装了适当的目标包,则可以在其中定位任何框架(如.NET,Silverlight,Robotics,XNA,Windows Phone和Mono).
我发现框架通常有一些参考程序集,它们%programfiles%\Reference Assemblies\Microsoft\Framework与子文件夹FrameworkList.xml中的RedistList文件一起放入.我已经尝试过创建一个新文件夹,将我的程序集(例如MyFramework.dll)放在那里以及包含FrameworkList.xml文件的RedistList子文件夹.我清除了文件但是有一个条目类似于:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FileList Redist="MyFramework_1_0">
<File AssemblyName="MyFramework" Version="1.0.0.0"
PublicKeyToken="be3ea0d08db41157" Culture="neutral"
ProcessorArchitecture="MSIL" InGAC="false" />
</FileList>
Run Code Online (Sandbox Code Playgroud)
但是Visual Studio在创建新项目时(重启VS后)没有在可用框架列表中列出我的框架.显然,我遗漏了一些东西,但我无法弄清楚是什么.
如何创建这样的Targeting Pack,允许Visual Studio查看自定义框架,或具有相同效果的东西?目标包中通常包含哪些内容?可以添加自定义构建步骤吗?
的背景:
我有一个应用程序需要在已安装的.NET框架范围从2.0到4.5的客户端上运行.此应用程序必须能够枚举和执行大量文件(在特定情况下超过200k离散文件).
要构建文件索引,应用程序当前使用System.IO.DirectoryInfo.GetFiles().这会带来性能损失,因为处理组件必须等待整个Path树在开始工作之前被索引.由于一些过时的磁带多重读取器和一些写得不好的固件,遍历某些目录可以触发从磁带读取 - 将处理时间从几十秒增加到几十分钟.
.NET 4.0提供了System.IO.Directory.EnumerateFiles(Path)方法,可以缓解此问题.但是,只有少数数据控制台升级到4.0+,我们对现代化的恳求遭到了敌意.
问题:
是否可以在单个二进制文件中实现GetFiles和EnumerateFiles的方法?实际上,这将是针对.NET 2.0的单个二进制文件,如果在运行时确定4.0框架可用,则能够调用.NET 4.0方法.
在提到之前:更换数据不是我们客户的选择.我试过了.我曾经尝试过吗?
通过各种博客后,我对"多目标"或并列执行的术语感到很困惑.
一些博客说,并行执行意味着一个进程中有两个版本的CLR.其他一些人声称,它就像.net 2.0和.net 3.0程序集并行执行.我非常失望,我不确定谁是对的谁是错的.
我也在许多博客中看到过像Scott Hanselman的博客等(这让人很困惑),如果目标框架是4.0,.NET 4.5的任何功能都将无效.我同意.但是我不能同意或理解这样一个事实:如果我使用4.5构建它并在4.0中部署,那么4.0中修复了其bug的功能将被隐藏.在这里,我不理解"隐藏"一词,没有人敢解释它究竟意味着什么.这意味着运行时错误?这意味着编译时错误?它不能这样.这意味着行为不一致?例外?如果是这种情况,我想知道为什么MS在VS中开发这种类型的灵活性.它是否符合任何目的?我理解,第一个案例是有意义的,但不理解或同意第二个案例.
我还在Rick/Scott Hanselman的帖子中看到,主要的变化意味着包括CLR在内的完整升级.然后,我应该看到3.0作为主要升级,但它不是仍然使用.NET 2.0 CLR.那么为什么命名术语是3.0.xx/3.5.xx?与.NET 4.0.30319.x中的情况类似,其中CLR也是新的,所以我同意这一点.我很惊讶谁是正确的.这些人或MSDN都与他们的原则相矛盾(就像MSDN所说格式为Major.Minor.Build.Revision,Hanselman或其他人说,Major意味着CLR升级,而它不在.NET 3.0中)
参考:http://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx
http://msdn.microsoft.com/en-us/library/bb822049(v=vs.110).aspx
对上述两个问题的想法?
我正在创建一个多平台应用程序.我有一个多目标共享库(目标.netstandard 2.0和.net 4.5)...请参阅项目文件:
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
当我在Windows上的visual studio 2017中构建项目时,我在输出中有两个目录(netstandard2.0,net45)和相应的dll.构建是成功的.
当我在Mac上的visual studio 2017中构建完全相同的项目(相同的代码)时,我得到了这种性质的错误:
类型'OptionAttribute'存在于'CommandLine.DotNetStandard,Version = 1.0.30'和'CommandLine,Version = 1.9.71.2'中
我通过以下方式有条件地引用了命令行解析器库:
<!-- CommandLineParser library -->
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="CommandLine.DotNetStandard">
<Version>1.0.3</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="CommandLineParser">
<Version>1.9.71</Version>
</PackageReference>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
这适用于Windows,但在Mac上它似乎没有观察到这种情况.这是mac上visual studio的已知错误吗?难道我做错了什么?
msbuild multitargeting nuget-package msbuild-projectreference visual-studio-mac
是的,我知道这听起来有点疯狂,但我已经在现场部署了.Net 3.5,我想使用新的4.0编译器来定位它.
我想在最新版本的Vb.Net和C#中使用几种新的语法糖功能,但我(目前尚未)在我的客户端基础上强制推出新版本的.Net框架和CLR.
在反对者双脚跳入之前...我刚刚成功使用Studio 2010来编译一个使用VB.Net自动属性的3.5目标应用程序(VB.Net 10中的一个新功能)所以我知道编译器能够以某种方式.
回到我的问题.... 我如何说服Nant使用4.0编译器,但目标是.Net 3.5(CLR 2.0)
更新:我使用的是csc和vbc任务,而不是解决方案任务.虽然我现在已经决定如何直接与编译器这样做了.
假设我有两个项目,P4和P3,分别针对.net 4.0和3.5.
每个项目还有一个System.Data的引用.在P4的情况下,它将是System.Data v4.0.0.0在P3的情况下,它将是System.Data v2.0.0.0
P4项目也参考了P3.
如果加载并执行P4,它将使用.net 4.0 CLR.在运行时,对System.Data的引用似乎在P4和P3内解析为v4.0.我可以通过使用assemblyBinding重定向覆盖它,但P4和P3都解析为v2.0.
有什么方法可以配置我的应用程序,以便P4使用v4.0和P3使用v2.0?
尝试编译使用具有多个目标(netstandard2.0和xamarin.iOS)的C#7元组的代码时,出现以下错误:
预定义类型'System.ValueTuple`2'在多个引用的程序集中声明
假设您正在编写一些与 BenchmarkDotNet 一起使用的基准测试,这些基准测试多目标为net48和net6.0,并且这些基准测试之一只能针对该net6.0目标进行编译。
显而易见的事情是使用类似的方法从构建中排除该特定基准net48:
#if NET6_0_OR_GREATER
[Benchmark]
public void UsingSpan()
{
using var stream = new MemoryStream();
writeUsingSpan(stream, _array);
}
static void writeUsingSpan(Stream output, double[] array)
{
var span = array.AsSpan();
var bytes = MemoryMarshal.AsBytes(span);
output.Write(bytes);
}
#endif // NET6_0_OR_GREATER
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,并且它不起作用的方式取决于TargetFrameworks项目文件中的属性中指定的目标的顺序。
如果您订购框架,那么net6.0首先<TargetFrameworks>net6.0;net48</TargetFrameworks>(在上面的示例中)该UsingSpan()方法将包含在两个目标中,导致目标net48和输出出现 BenchmarkDotNet 构建错误,如下所示:
| Method | Job | Runtime | Mean | Error | StdDev |
|------------------ |------------------- |------------------- |-----------:|----------:|----------:|
| …Run Code Online (Sandbox Code Playgroud)