I need 2 assemblies for my .NET Core 3 WPF App - System.Windows.Forms and System.Drawing.Common.
When I try to add them as references in Visual Studio 2019 from the common shared folder (C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.0.0) i get an exception message box saying "The reference is invalid or unsupported".
I would expect this kind of thing to happen with framework mismatches, but this is from the dotnet core v3 shared folder, so everything should line up.
Is there any particular trick to adding these references that I am unaware of?
csproj file:
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="logo.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
In the .NET Core, the project system does not handle well binary assembly references. It may not always work and is an unsupported and unrecommended way to reference assemblies. The proper way is to use package references or framework references. The latter are expressed at the top level of the project via the Sdk attribute i.e. <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">.
First of all, you should not add assembly references but add package references either manually or using the package manager. The reference to System.Drawing.Common assembly for .NET Core 3.0 target should look as follows:
<PackageReference Include="System.Drawing.Common" Version="4.6.0" />
Related
The use case is pretty simple:
I have two projects (ProtoProvider & ProtoConsumer).
ProtoProvider has the proto file (to_import.proto) and the message I want to use on the ProtoConsumer.
ProtoConsumer has a referrence on ProtoProvider and attempts to use the ProvidedMessage in the imported.proto.
I cannot use the the message because I get "File not found." on the impoort and "ProvidedMessage is not defined" on the compiler for the imported.proto.
EDIT2>>>
To clarify I want to create a message like google's google.protobuf.Timestamp and distribute it to another project or projects without the other projects while having the project/projects (consumer) getting the message from the dll. The whole premise of the question is how to use the message defined in to_import.proto in another project through the dll (think of it as a common.grpc lib).
EDIT1>>>
The error messages I'm getting
Is there a solution that allows the importing of the proto files from a project reference?
I'm looking for something like google's solution for the well-known-types
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
source: https://developers.google.com/protocol-buffers/docs/csharptutorial#where-to-find-the-example-code.
(Copying the proto files or moving the files is not an elegant solution).
Below I'll provide the .csproj files
ProtoProvider:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="to_import.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="to_import.proto" GrpcServices="None" />
</ItemGroup>
</Project>
ProtoConsumer:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Protobuf Include="Protos\imported.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProtoProvider\ProtoProvider.csproj" />
</ItemGroup>
</Project>
Edit>>3
Some context : The purpose of this question is to help me understand a clearer way to implement decimal once (as specified here) and reuse them in each project.
AFAIK, compiling proto files requires all files (including imports) to exist on disk.
The way this works for the well known types is that they are included in Grpc.Tools nuget package.
So its not possible to ship a class library that accomplishes what you want.
Discussion on a related grpc-dotnet issue suggests using a combination of:
Building a nuget package containing your common proto and associated class library
In the consuming code's package reference, use GeneratePathProperty to generate a variable holding the path to the nuget package content
In the consuming code's Protobuf Include, use AdditionalImportDirs to include the common proto from the nuget package.
I'm trying to use Xplot.Plotly in an f# project using
Visual Studio for Mac. When I debug I obtain
"Could not load file or assembly
'FSharp.Core, Version=4.7.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
If If I do dotnet run I obtain:
Unhandled exception.
Cannot print exception string because Exception.ToString() failed.
the project file references are as follows
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MathNet.Numerics.FSharp" Version="4.9.1" />
<PackageReference Include="XPlot.Plotly" Version="3.0.1" />
<PackageReference Include="FSharp.Core" Version="4.7.1" />
</ItemGroup>
</Project>
and the project view screen shot as follows:
I'm not clear why VS shows 4.5.2 instead of 4.7.0.0?
I've also tried moving explicityly the Fsharp.core.dll version 4.7.0.0 to the bin directory. From the console the result is the same. If I run via Visual studio Fsharp.core.dll version 4.7.0.0 gets overwritten with 4.5.2.0 and fails in the same way as above.
Update: Workaround is simply do Clean from Visual Studio. and then run dotnet build from the console. Then you can debug from Visual Studio if needed.
Currently, VS for Mac requires Mono, which is locked to F# 4.5 and has numerous other troubles loading .NET Standard 2.0 components. Eventually, VS for Mac will be updated and it will support loading higher versions of the F# compiler and FSharp.Core.
Wondering if there is any legitimate reason for a .csproj to contain an assembly reference to an assembly w/ a hint path under the dotnet installation directory (default: c:\Program Files\dotnet on Windows).
In particular, the directories
packs
sdk
shared
An example of such a reference:
<ItemGroup>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>..\..\..\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.0\ref\netcoreapp3.1\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
Surely not. This application would not work on other machines.
It looks like someone inserted code that uses Microsoft.Extensions.Configuration.Abstractions package which was not referenced and then probably applied "Quick fix" action from Resharper/Rider. Sometimes it leads not to referencing Nuget package
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
</ItemGroup>
but to referencing locally placed assembly.
I'm hoping someone has some advice on the best way to use Teamcity to build and publish a solution that has both .NET Core/standard 2.0 projects and .NET framework 4.6.x projects in it.
Currently, I can build the project, run tests, but I can't figure out a way to publish it via the dotnet-cli. We have a relatively large solution, approximately 75 projects in .NET core/standard and 5 or some framework projects. Running dotnet publish on our solution results in the following error on the .NET framework projects:
error: C:\Program Files\dotnet\sdk\2.0.3\Microsoft.Common.CurrentVersion.targets(3861,5): error MSB4062: The "Microsoft.Build.Tasks.ResolveManifestFiles" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. Confirm that the 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.
It would be ideal if the cli could attempt to ignore publishing the .NET Framework projects, but it doesn't seem to be possible. I'm thinking about writing a powershell script to check all csproj files in our solution for an appropriate TargetFramework value (i.e netstandard2.0/netcoreapp2.0), and publish them individually, but maybe someone knows a better way?
If anyone is facing the same issue, you need to restructure your csproj file as suggested by #nvoigt.
You can follow the steps as described in the post Old csproj to new csproj
You can start clearing out your csproj file and start with below format.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net462</TargetFramework> // if your target is 4.6.2
</PropertyGroup>
</Project>
And now you can add remaining of your dependency like below.
...
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.4" />
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0.0" />
<PackageReference Include="Microsoft.Azure.KeyVault" Version="2.0.6" />
<PackageReference Include="NLog" Version="4.7.5" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.5" />
</ItemGroup>
...
you can find more details on the post.
Start new project, pick .netcore2 console app.
Change the target framework to .net 461. You do this by editing the .csproj file as shown:
<TargetFramework>net461</TargetFramework>
netcore has ran on the full framework for years. so no surprises. now add a new project: .net standard 2.0 class library. your .csproj on that library should now contain
<TargetFramework>netstandard2.0</TargetFramework>
reference this standard 2 assembly from your console app. Your .csproj file for the console app now reads:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LibStandard\LibStandard.csproj" />
</ItemGroup>
create an enum on your .net standard 2 library
namespace LibStandard
{
public class Class1
{
}
public enum TestEnum
{
One, Two
}
}
use said enum in your console app
class Program
{
static void Main(string[] args)
{
TestEnum t = TestEnum.One;
Console.WriteLine("Hello World!");
}
}
works. cool. Now change your target framework on the console app to .net471. like so
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net471</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LibStandard\LibStandard.csproj" />
</ItemGroup>
and now you will get this error on build:
2>Program.cs(10,13,10,21): error CS0012: The type 'Enum' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
2>Program.cs(10,26,10,34): error CS0012: The type 'Enum' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
2>Program.cs(10,35,10,38): error CS0012: The type 'Enum' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
2>Done building project "ConsoleOne.csproj" -- FAILED.
I tried adding (via nuget) .netstandard 2.0.0 to the console app project, but that doesn't solve the problem.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net471</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LibStandard\LibStandard.csproj" />
</ItemGroup>
If you haven't tried this before, you could always run .net standard libraries in 461 for 1.x standard. But the same doesn't work for .netstandard 2 and 471. You can also try adding a new console app (desktop app full netcore 471). Same result. Starting with a .netcore console app and then targeting the .netfx or starting without .net core gets the same error.
I'm stumped.
SAMPLE SOLUTION: SAMPLE
Seems related to this per VS team
https://github.com/Microsoft/msbuild/pull/2567
workaround seems to work: add _HasReferenceToSystemRuntime
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net471</TargetFramework>
<_HasReferenceToSystemRuntime>true</_HasReferenceToSystemRuntime>
</PropertyGroup>
seems Visual Studio still a bit confused dealing with .net standard