I am trying to port a Windows.Forms application to .Net Standard 2.0 using Visual Studio Code. Based on responses to an earlier question (thank you guys), my plan is to try to use Xamarin.Forms to replace System.Windows.Forms. So, I add the Xamarin.Forms package to my project. When I try to run dotnet build, then I see the following error:
C:\Users\<user>\.nuget\packages\xamarin.forms\2.4.0.38779\build\netstandard1.0\Xamarin.Forms.targets(51,3): error MSB4062: The "Xamarin.Forms.Build.Tasks.FixedCreateCSharpManifestResourceName" task could not be loaded from the assembly C:\Users\<user>\.nuget\packages\xamarin.forms\2.4.0.38779\build\netstandard1.0\Xamarin.Forms.Build.Tasks.dll. Could not load file or assembly 'Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
I have tried to add various other Microsoft.Build packages but nothing seems to work. Is there a way forward here? Here's my current csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Microsoft.Build" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.3.409" />
<PackageReference Include="NUnit" Version="3.8.1" />
<PackageReference Include="System.Configuration" Version="2.0.5" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
<PackageReference Include="System.ServiceModel" Version="1.0.0" />
<PackageReference Include="Xamarin.Forms" Version="2.4.0.38779" />
</ItemGroup>
</Project>
I think that I may be asking the same question as here: Where is the difference of dotnet build on cmd vs VS2017? but am not sure.
I'm working on a Xamarin.Forms application and I'm migrating my libraries from PCL to NetStandard.
It seems that you can build the project with MsBuild.exe (I used C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe).
I found it mentioned in this blog post: https://oren.codes/2017/04/23/using-xamarin-forms-with-net-standard-vs-2017-edition/
You will need to use MSBuild.exe to build this, either on Windows with a VS 2017 command prompt or a Mac with Visual Studio for Mac. You cannot use dotnet build for these projects types. dotnet build only supports .NET Standard, .NET Core and .NET Framework project types. It is not able to build the Xamarin projects and the custom tasks in Xamarin Forms have not yet been updated to support .NET Core.
An additional note: I had to delete AssemblyInfo.cs, otherwise MsBuild complained about duplicate properties.
Related
tl/dr;
My project-referenced Roslyn analyzer works fine in Visual Studio 2019 but fails to load in dotnet build with the following build warning:
CSC : warning CS8032: An instance of analyzer Nearmap.CodeAnalysers.UseCtorInjection.UseCtorInjectionAnalyser cannot be created from [solution path]\MyCodeAnalysers\bin\Debug\netstandard2.0\MyCodeAnalysers.dll : Could not load file or assembly 'Microsoft.CodeAnalysis, Version=4.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
Details
I have a Roslyn analyzer in a project which is loaded into the other projects in the solution.
The analyzer works as expected, and produces the expected warnings, during build in Visual Studio 2019.
When I try to build the solution from the command line (as our CI pipeline does) using dotnet build MySolution.sln I get the following build warning for every project that references the analyzer project:
CSC : warning CS8032: An instance of analyzer Nearmap.CodeAnalysers.UseCtorInjection.UseCtorInjectionAnalyser cannot be created from [solution path]\MyCodeAnalysers\bin\Debug\netstandard2.0\MyCodeAnalysers.dll : Could not load file or assembly 'Microsoft.CodeAnalysis, Version=4.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
where [solution path] is the full path to the folder containing the solution.
The analyzer project looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<!-- added in an attempt to fix the problem -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
</ItemGroup>
</Project>
Projects reference this analyzer as:
<ItemGroup>
<ProjectReference Include="..\MyCodeAnalysers\MyCodeAnalysers.csproj"
PrivateAssets="all"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
I've checked the build output folder of the analyzer project and it contains all the DLL dependencies needed to load the analyzer, but it's obviously not being looked at when try to load the analyzer.
What am I missing?
The problem was the SDK version.
Aparently the Microsoft.CodeAnalysis.dll (and others) are loaded from the .Net SDK in use. We're currently still using the .Net 6.0 SDK to build our solutions. .Net 6.0 includes Microsoft.CodeAnalysis.dll 4.1.0 not the 4.4.0 version I was using. VS2019 runs the build differently, and didn't have the DLL resolution problem.
I fixed it by rolling the package references back to v4.1.0:
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" />
</ItemGroup>
I am trying to get Microsoft Fakes to work properly with my unit test project (net47) wherein my project file format is using the new NetSDK format.
With Visual Studio 2019, I can add a Fakes Assembly and things seem to work fine, until we try to build/run the tests on our build agent. It seems as though when you compile/build a project the fakes assemblies are generated, but they are done either in parallel or after the build (I'm not sure). This same problem happens on my development machine running Visual Studio 2019 Enterprise.
I noticed that if no FakesAssemblies folder exists, one is created during the build, but the compilation fails because none of the *.Fakes namespaces were discovered. A second compilation/build works because now the FakesAssemblies folder is populated. One thing to note is that I took the dll file for Microsoft Fakes and put it in a NuGet package in our companies private feed, that way I can pull it down as a NuGet package instead of a reference.
SampleUnitTests.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net47</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Microsoft.QualityTools.Testing.Fakes" Version="16.0.28621.142" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
</ItemGroup>
<ItemGroup>
<Fakes Include="Fakes\*.fakes" />
<Reference Include="FakesAssemblies\*.dll" />
</ItemGroup>
</Project>
I have a .NetStandard project that uses System.ValueTuple.
It builds fine in visual studio whether or not I include the System.ValueTuple nuget package.
However it fails either way when I build it on team-city with the error:
error CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?
Teamcity is hosted on an environment with both the latest .Net Core SDK and the latest .NetFramework SDK.
When I change the target framework to .NetCoreApp2.0 it builds fine.
Any ideas as to what could be going on?
For Reference, here is my csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<Version>$(VersionSuffix)</Version>
<Authors>**********</Authors>
<Product>**********</Product>
<Description>**********</Description>
<PackageTags>**********</PackageTags>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Copyright>**********</Copyright>
<PackageProjectUrl>http://**********</PackageProjectUrl>
<PackageLicenseUrl>http://**********</PackageLicenseUrl>
<PackageIconUrl>http://**********</PackageIconUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.4.1" />
<PackageReference Include="RabbitMQ.Client" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="**********" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\**********" />
</ItemGroup>
The error went away when I started using DotNet Restore instead of Nuget Restore.
I have no idea why.
You most probably need to add a reference to System.ValueTuple.dll. You can do this by installing the System.ValueTuple package from nuget.
Apologies if this is a very naive question. I wrote a Windows Form application using .Net 4.5 sometime ago. Recently, I thought it would be a good idea to port it to a .Net Standard 2.0 application using VS Code.
There were a couple of problems with missing libraries and classes (System.ServiceModel being the biggest gap), but I have got to the point of building the application successfully. However, when I come to run it, I see the following error:
Unhandled Exception: System.BadImageFormatException: Could not load file or assembly 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058) ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
Here's the project file if it's useful:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Microsoft.CSharp" Version="4.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NUnit" Version="3.8.1" />
<PackageReference Include="System.CodeDom" Version="4.4.0" />
<PackageReference Include="System.Configuration" Version="2.0.5" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
<PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="System.ServiceModel" Version="1.0.0" />
<PackageReference Include="System.ServiceModel.Security" Version="4.4.0" />
<PackageReference Include="System.Windows.Forms" Version="4.0.0.0" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>
Is there some way to run the application using the System.Windows.Forms library, or should I replace it with a different library for .Net Standard 2.0?
You cannot build an application that targets .NET Standard 2.0. Only libraries can target .NET Standard. Applications still have to target a specific runtime - .NET Framework, .NET Core, Xamarin, etc.
Judging by your project file, you're actually targeting .NET Core 2.0.
System.Windows.Forms is part of the .NET Framework (and Mono). It does not exist as part of .NET Standard or .NET Core.
Your project file has a PackageReference to System.Windows.Forms, which will pull in this NuGet package. It's unofficial and unlisted. Its very description is "unsupported library".
The DLL inside that package is only a reference assembly, i.e. none of the methods contain any actual code. That assembly only contains definitions.
This is what the error message means by "Reference assemblies should not be loaded for execution." The assembly in that package will let you compile, but nothing else.
There is no formal way to run a Windows Forms application on .NET Core (prior to 3.0). There may be a benefit to pulling our your business logic into a .NET Standard assembly, but your user interface will still have to be a .NET Framework application.
I don't know much about .NET yet, so I guess I'm missing something obvious.
I created a library (targeted as a DLL file, set for .NET standard 2.0), packaged it both as a DLL file and as a NuGet package. Now I want to use the library in another project, on ASP.NET Core 2.0. How should I do it?
I am currently on a Linux VM, so I use Visual Studio Code, and therefore I would prefer some solution without using the full Visual Studio. I tried some solutions using the full Visual Studio, but that didn't work for me, because I haven't found a reference explorer anywhere.
You would have to reference your library in the .csproj file:
An empty .csproj file would look like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
</Project>
Now, you can have two types of references:
Project Reference - You have a project that serves as a class library in your solution and you want to reference it directly:
<ProjectReference Include="..\..\src\mylib.csproj" />
Package Reference - You have a link to a NuGet package:
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.2" />
Inside your .csproj file, the references should be inside an "ItemGroup" block, and each reference type should have its own "ItemGroup".
Here's an example of a .csproj file with some package references and some project references:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.1.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="1.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.1" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\mylib.csproj" />
<ProjectReference Include="..\..\src\mylib2.csproj" />
</ItemGroup>
</Project>
A lot of people recommend one of two solutions:
Copy the library into your solution folder.
cp -r foo/foo ./foo
dotnet sln add foo/foo.csproj
cd bar
dotnet add reference ../foo/foo.csproj
This is a terrible solution.
Don't do this (i.e., copy and paste your library code every time you want to use it. It is bad for obvious reasons).
Setup a local NuGet repository, copy your library into the local repository, and then add it.
nuget add -name "Local" -source /home/doug/packages
nuget add ~/foo/foo.nupkg -source /home/doug/packages
Then install the package:
cd bar
dotnet add package foo
This is an acceptable solution, but the workflow is quite irritating if you are actively working on your library (foo), because the -source path must be absolute.
--
I recommend you look at dotnet add package with local package file, which explains how you can have a local cache of any custom .nupkg files you want to work with.
Basically, just drop this into your solution folder:
File NuGet.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="local" value="./packages" />
</packageSources>
</configuration>
(Notice that ./packages is a relative path, that will work even when you check your project out on an entirely different machine or OS.)
Now if you call dotnet add package X it will also look for any file called x.nupkg in your ./packages/ folder.
Now if you want to use any custom local library, all you need to do is:
cp ~/foo/foo.nupkg ./packages
cd bar
dotnet add package foo
(Note: by default NuGet caches your .nupkg files in ~/.nuget and will restore packages from that folder if you call dotnet add package X, even if you have a different X.nupkg in your local ./packages folder. You may find the command dotnet nuget locals all --clear useful if you encounter strange behaviour to ensure you're getting the exact version of the .nupkg file you want, not some arbitrary cached version)
Another way to reference the local package in the .csproj file:
<ItemGroup>
<Reference Include="MyAssembly">
<HintPath>path\to\MyAssembly.dll</HintPath>
</Reference>
</ItemGroup>
Given that the DLL file you want to reference in the new ASP.NET Core 2.0 project is relatively fresh, I suspect you will need to make changes to this original DLL file as you develop the ASP.NET project.
In this situation I would add the original DLL project as part of the ASP.NET solution so you can work on both sets of source code, including setting of breakpoints within the same solution workspace.
NuGet packaging of the original DLL project can be delayed until the first release of your whole combined solution has stabilised and you want to make that DLL file available to a larger developer audience beyond the scope of your ASP.NET application.
A good solution will be to add the library (.dll file) that you want to use to the Project's References of your project in which you want to use the library:
Right Click on the project → Add → Reference → Project → Browse → Path_to_your_generated_library (.dll)
This will automatically generate the following node in the .csproj file:
<ItemGroup>
<Reference Include="DotNetCoreClassLibraryCodeParser">
<HintPath>..\..\DotNetCoreClassLibrary\DotNetCoreClassLibrary\bin\Debug\netcoreapp2.1\DotNetCoreClassLibrary.dll</HintPath>
</Reference>
</ItemGroup>