I have a multi-targeted project (MultiTargetedProj) that targets .NET Standard 2.0 and UWP. This project refers a .NET Standard 2.0 project (SayClassLibraryProj).
When building MultiTargetedProj, I get an error saying ClassLibraryProj's dll cannot be found:
7>CSC : error CS0006: Metadata file 'C:\Users\sanjay\Downloads\NewProjectStructurePOC-master(2)\NewProjectStructurePOC-master\ClassLibraryProj\bin\x64\Debug\uap10.0\ClassLibraryProj.dll' could not be found
7>Done building project "MultiTargetedProj.csproj" -- FAILED.
As per my understanding, ClassLibraryProj's bin should only have a sub folder for .NET Standard and not for UWP. Since my reference to ClassLibraryProj is non-conditional, multi targeted project should resolve correctly.
When I replace project references with direct DLL reference to the .NET Standard subfolder, the build succeeds.
Project configuration for MultiTargetedProj:
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;uap10.0</TargetFrameworks>
<AssemblyName>MultiTargetedProj</AssemblyName>
<RootNamespace>MultiTargetedProj</RootNamespace>
<Platforms>AnyCPU;x64;x86</Platforms>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<BaseOutputPath></BaseOutputPath>
<BaseIntermediateOutputPath></BaseIntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<!--<Reference Include="..\ClassLibraryProj\bin\x64\Debug\netstandard2.0\ClassLibraryProj.dll" />-->
<ProjectReference Include="..\ClassLibraryProj\ClassLibraryProj.csproj" />
</ItemGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcore')) ">
<DefineConstants>NET_CORE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('uap')) ">
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0 .18362.0</TargetPlatformMinVersion>
<DefineConstants>WINDOWS_UWP</DefineConstants>
<LanguageTargets>$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets</LanguageTargets>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Remove="obj\**" />
<None Remove="obj\**" />
</ItemGroup>
<ItemGroup>
...
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('uap')) ">
<Compile Include="UWP\**\*.cs" />
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.13</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netcore')) ">
<Compile Include="NetCore\**\*.cs" />
</ItemGroup>
</Project>
This issue is only while using.NET SDK Version 6.0.302. On a different machine with .NET SDK Version 5.0.410, build succeeds.
Related
I have a legacy program I'm trying to migrate from Net Framework 4.6.1 to .NET 6. In it, there's a shared library which needs to run on Linux as well as Windows, with some Windows-specific calls which I've successfully sequestered using #if NET6_0_WINDOWS. This was enough to get the Linux version up and running, but when I tried to add in the Windows WPF App, I got thousands of errors.
To bring the WPF app up to date, I ran the upgrade assistant (which is detailed here). Unfortunately, the app wouldn't compile without considerable effort.
I set my project files in the UI to explicitly target windows (using net6.0-windows as the TargetFramework) and my xaml files won't associate with the code (this is a common problem with LOTS of potential causes which I'm separately investigating using the thread here. For instance, I get errors on InitializeComponent where the compiler can't find it, as well as the errors mentioned in the thread.
To make things even stranger, when I run the app (after a lot of #if NET6_0_WINDOWS tweaking), I can't set breakpoints in the code in the #if'd blocks... I may be going down a rabbit trail, but why would that symbol be undefined?
In case it's relevant, the project file for the WPF app that's running looks like the following:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<OutputType>WinExe</OutputType>
<RootNamespace>WPFApp</RootNamespace>
<ApplicationIcon>SoftingIcon.ico</ApplicationIcon>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<OutputPath>..\bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>..\bin\Release\</OutputPath>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<OutputPath>..\bin\Release\</OutputPath>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup>
<NoWin32Manifest>true</NoWin32Manifest>
</PropertyGroup>
<ItemGroup>
<Reference Update="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Update="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Update="UIAutomationProvider">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\EditModel\EditModel.csproj" />
<ProjectReference Include="..\..\common\Tools\Tools.csproj" />
<ProjectReference Include="..\Help\HelpInterface\HelpInterface.csproj" />
<ProjectReference Include="..\ViewPaneLibrary\ViewPaneLibrary.csproj" />
<ProjectReference Include="..\InterfaceControls\InterfaceControls.csproj" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
</ItemGroup>
</Project>
The preprocessor symbol only includes the .Net version, not the OS (also be careful, there is no underscore between NET and 6).
A full list of the symbols can be found here:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives
However, you can define it yourself in MSBuild.
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0-windows'">
<DefineConstants>$(DefineConstants);NET6_0_WINDOWS</DefineConstants>
</PropertyGroup>
I have a NuGet package library project that is compiling for .NET Core and .NET Framework. It is also using the new public signing.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Build">
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Label="Signing">
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../Key.snk</AssemblyOriginatorKeyFile>
<PublicSign>true</PublicSign>
</PropertyGroup>
</Project>
I have an xUnit test project using which is also cross compiling to .NET Core and .NET Framework.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Build">
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\..\Source\Foo\Foo.csproj" />
</ItemGroup>
</Project>
When I run the tests in this project, the .NET Core test run succeeds but the .NET Framework test run fails with:
System.IO.FileLoadException : Could not load file or assembly 'Foo, Version=0.0.1.0, Culture=neutral, PublicKeyToken=fc5550082a9c642c' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key. (Exception from HRESULT: 0x80131045)
How can I get them both to work?
Use
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">True</PublicSign>
Reference
#SNMP Library
I turned OFF the TreatWarningsAsErrors, as i kept getting errors when publishing while self-contained is set to true. Now VS2017 publishes successfully, but the command line dotnet publish still reports the same errors. How can fix this?
Example of the errors i receive:
error NU1605: Detected package downgrade: System.Runtime.InteropServices from 4.3.0 to 4.1.0. Reference the package directly from the project so select a different version.
VS2017 Publish settings that actually works:
cmd line that doesn't work:
dotnet publish "c:\myproject.csproj" -f netcoreapp2.1 -c "Debug" -o "c:\users\me\dekstop\publish" --self-contained true -r win-x64
EDIT added csproj contents*
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
<Platforms>x64;x86</Platforms>
</PropertyGroup>
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\GlobalInfo\GlobalAssemblyInfo.cs">
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Configuration\CrossPlatformConfiguration.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Registrations\SetupModule.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="Autofac">
<HintPath>..\..\packages\autofac\4.9.2\lib\netstandard2.0\Autofac.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\..\packages\log4net\2.0.8\lib\netstandard1.3\log4net.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\proj1.csproj" />
<ProjectReference Include="..\..\proj2.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="app.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\_Keys\Private\MyXkey.snk</AssemblyOriginatorKeyFile>
<AssemblyName>Test.Setup</AssemblyName>
<RootNamespace>Test.Setup</RootNamespace>
<DelaySign>false</DelaySign>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<OutputPath>..\..\Bin\x86\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutputPath>..\..\Bin\x64\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutputPath>..\..\Bin\x64\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<OutputPath>..\..\Bin\x86\Release\</OutputPath>
</PropertyGroup>
What is happening differently here that allows VS2017 to publish the executable?
ProgrammerMan led me to the solution, which was to add
<NoWarn>$(NoWarn);NU1605</NoWarn>
to the csproj of each project in the solution.
Not an answer, but some more information that may eventually help towards a 'real' solution...
I believe you will find the same NU1605 errors in VS2017, but the difference is they are treated as warnings so the publish completes successfully.
After publishing you can see the warnings in the Output window - View > Output and then Show output from: Build.
I find the errors/warning are linked to the target runtime (-r) and anything
other than 'Portable' (or blank) will cause them.
I have updated to .NET Core 2.2.107 and still get them.
I also get the same with my .NET Standard 2.0 project.
I have also muted them by adding the same NoWarn suggestion.
I'm making a NuGet package and my csproj looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard1.6;net461;net47</TargetFrameworks>
...
<PackageId>Package2</PackageId>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Package1\Package1.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net461' OR '$(TargetFramework)'=='net47'">
<Reference Include="System.Net.Http" />
</ItemGroup>
</Project>
The project it's referencing looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard1.6;net461;net47</TargetFrameworks>
<PackageId>Package1</PackageId>
...
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<NoWarn>1701;1702; CS1591</NoWarn>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.6' OR '$(TargetFramework)'=='net461'">
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net461' OR '$(TargetFramework)'=='net47'">
<Reference Include="System.Net.Http" />
</ItemGroup>
</Project>
And inside the Package2 project it has the following line:
webRequestHandler.ClientCertificates.Add(certificate);
But it isn't building in net461 or net47, saying:
'HttpClientHandler' does not contain a definition for
'ClientCertificates' and no accessible extension method
'ClientCertificates' accepting a first argument of type
'HttpClientHandler' could be found (are you missing a using
directive or an assembly reference?)
Package2(net461),
Package2(net47)
But the only thing I've changed is removed this from the csproj for package2:
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.6' OR '$(TargetFramework)'=='net461' OR '$(TargetFramework)'=='net47'">
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
</ItemGroup>
Can anyone help me understand how to fix it? I don't really want to bring in that whole NuGet package just to fix this one dependency I think I'm just missing an assembly but as far as I know it should be in System.Net.Http which I should already be referencing (and so should the other project it's already dependent on).
Looks like this property is available from version 4.7.1:
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.clientcertificates?view=netframework-4.7.1
Note that if you select an older .NET version, you'll see a message like this:
The requested page is not available for .NET Framework 4.7.
For me the solution was to download the newest version of "System.Net.Http".
You can find it through the NuGet package manager.
At the time of writing v4.3.4 is the newest version and it contains the ClientCertificates methode.
I've swapped out the assembly reference for the NuGet package:
<ItemGroup Condition="'$(TargetFramework)'=='net47' OR '$(TargetFramework)'=='net461'">
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
pretty sure this is the wrong thing to do™ as the assembly reference in .NET Framework should be sufficient and I'm probably going to suffer many conflicting reference issues anywhere I install my package, but this is the best I can come up with right now.
I'm on Ubuntu and I have two .NET Core 2.0 projects (Project Oranges.csproj and Apples.csproj). Oranges only contains references to NuGet packages, while Apples contains a reference to Oranges.
Running dotnet build -f netcoreapp2.0 Oranges.csproj succeeds! Oranges.dll now exists at /Oranges/bin/Debug/netcoreapp2.0/Oranges.dll.
Running dotnet build -f netcoreapp2.0 Apples.csproj fails with: error CS0009: Metadata file '/Oranges/bin/Debug/netcoreapp2.0/Oranges.dll' could not be opened -- PE image doesn't contain managed metadata
How can I go about referencing Oranges, which builds without issue, in Apples without issue?
Oranges.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TargetFrameworks>netcoreapp2.0;net451;</TargetFrameworks>
<RootNamespace>Oranges</RootNamespace>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\GeneratedKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcore2.0'">
<DefineConstants>NETCORE2_0</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net451'">
<DefineConstants>NET4_5_1</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="packages.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
</ItemGroup>
</Project>
Apples.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TargetFrameworks>netcoreapp2.0;net451;</TargetFrameworks>
<RootNamespace>Apples</RootNamespace>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>..\..\GeneratedKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<None Remove="packages.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
<PackageReference Include="System.Composition" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oranges\Oranges.csproj" />
</ItemGroup>
</Project>
After deleting the bin and obj folders from the project directory and rebuilding, a different error was being displayed.
CSC : error CS7027: Error signing output with public key from file 'GeneratedKey.snk' -- Assembly signing not supported. [.../Oranges/Oranges.csproj]
After some research I stumbled across a solution.
Assembly Signing Not Supported
Adding the line below to the .csproj file for each assembly that required signing resolved the issue.
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
For now it seems like if you need to sign netcore assemblies, it should be done on Windows.