The 'Publish' target is not supported without specifying a target framework - msbuild

Using Visual Studio 2017, I created an ASP.NET Core site using .NET Framework.
(I do not have a project.json, I have a VS2017 project with .cproj)
My target is x64 Windows 2008R2. The beginning of my .cproj looks like follow:
<Project Sdk="Microsoft.NET.Sdk.Web" ToolsVersion="15.0">
<PropertyGroup>
<TargetFrameworks>net462</TargetFrameworks>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\Release</OutputPath>
<Optimize>True</Optimize>
</PropertyGroup>
...
However, and while I am targetting .NET 4.6.2 only, when I try to publish I am getting this error
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Sdks\Microsoft.NET.Sdk\buildCrossTargeting\Microsoft.NET.Sdk.targets(31,5): Error : The 'Publish' target is not supported without specifying a target framework. The current project targets multiple frameworks, please specify the framework for the published application.
While looking for solutions online, I encountered people having the same problem but they actually have many targets, however, in my case I am not sure why I am even getting it.
Any ideas?

There was a change in the .csproj template (https://github.com/dotnet/sdk/issues/251).
Instead of <TargetFrameworks> you need to use <TargetFramework>:
<PropertyGroup>
<TargetFramework>net462</TargetFramework>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>

Related

WiX installer: problems with C# project in Sdk format "The default XML namespace of the project must be the MSBuild XML namespace."

I have a solution with several projects targeting .NET Framework 4.7.2 and including WiX installer.
Everything works and builds fine.
In order to convert projects to .net standard/.net 6 I first convert one of the projects (extremely simple class library) to a modern Sdk format. At this moment the project file looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RootNamespace>MyProject</RootNamespace>
<AssemblyName>MyProject</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="LegalNotice.rtf" />
</ItemGroup>
The library and all dependent projects build ok, but when building WiX installer it gives me the following error:
heat.exe(0,0): error HEAT5305: Failed to load project ...\MyProject.csproj: The default XML namespace of the project must be the MSBuild XML namespace. If the project is authored in the MSBuild 2003 format, please add xmlns="http://schemas.microsoft.com/developer/msbuild/2003" to the element. If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format.
Ok, I add xmlns="http://schemas.microsoft.com/developer/msbuild/2003" to the project. All projects build ok, except WiX installer which nog gives this error:
heat.exe(0,0): error HEAT5307: Build failed.
Just to try I add ToolsVersion="15.0", the project file now looks like this:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RootNamespace>MyProject</RootNamespace>
<AssemblyName>MyProject</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="LegalNotice.rtf" />
</ItemGroup>
No luck. Like before, everything builds ok, except of WiX installer, which fails with the same 5307 error.
WiX version installed: 3.11.2 (the latest stable).
Any suggestions what could be the problem?
WiX v3.11 doesn't support SDK-style projects. WiX v4 will support SDK-style projects. Supporting SDK-style projects is actually, one of the biggest if not the biggest feature in WiX v4.

Build hybrid .Net Standard and .NetFramework solution in MSBuild

Pardon the long post. I am trying to give as much info as possible.
I moved some classes from .Net Framework library into a new .Net Standard library in order to reference them from both existing .Net Framework projects and new .Net Core projects. After adding the new .net standard project to the solution that contains the other .Net Framework projects, the existing build definition (XAML) fails to build the .net standard project. It builds fine if i pass /t:restore,build as MSBuild parameters, but this breaks the build for existing .net framework projects in the solution. Visual Studio
is able to build the hybrid solution fine. I need to build it in this hybrid solution because the downstream project does the packaging and pushing to our nuget repository (OctopusDeploy).
To overcome this, I have tried to use default targets and initial targets but could not get it to go through.
See the example project below:
<Project InitialTargets="restore" DefaultTargets="publish" Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<RootNamespace>MyCompany.Common</RootNamespace>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>MyCompany.CommonStandard</AssemblyName>
</PropertyGroup>
</Project>
With the above project file, I get this error.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\NuGet\NuGet.targets (240): There is a circular dependency in the target dependency graph involving target "_FilterRestoreGraphProjectInputItems"
Other things I have tried:
<Project DefaultTargets="restore;build;publish" Sdk="Microsoft.NET.Sdk">
OR
<Project DefaultTargets="restore;publish" Sdk="Microsoft.NET.Sdk">
Error: Bunch of errors stating almost everything is undefined. (vbc: Type 'System.String' is not defined.) Note: passing the same as msbuild targets like /t:restore,build,publish works.
<Project Targets="restore,build,publish" Sdk="Microsoft.NET.Sdk">
OR
<Project DefaultTargets="publish" Sdk="Microsoft.NET.Sdk">
OR
<Project DefaultTargets="publish" Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<BuildDependsOn>
Restore;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
Error: \obj\project.assets.json' not found. Run a NuGet package restore to generate this file.
<Project InitialTargets="restore" Targets="build,publish" Sdk="Microsoft.NET.Sdk">
OR
<Project InitialTargets="restore" Targets="publish" Sdk="Microsoft.NET.Sdk">
Error: There is a circular dependency in the target dependency graph involving target "_FilterRestoreGraphProjectInputItems".
Thanks for reading. I would really appreciate any guidance in resolving this.
It turned out that my build definitions were pointing to an older version of MSBuild that did not recognize the sdk format. After changing that to MSBuild15 and using the restore,build targets, I was able to get these to work.

Visual Studio for mac project.json

When I use Visual Studio for Mac to create a web project with .Net core 1.1, there is no project.json in my project. Is there any mistake when I create
this project?
Project.json was never released in production. It was replaced by a new, vastly simplified MSBuild project format before .NET Core was released. The new format works a lot like the project.json format - it supports globbing, package references and compiles all *.cs* files found in a folder. You don't need to define dependent packages in the project file any more, you can specify *one* root package and all dependencies will be added when you executedotnet restore`
.NET Core allows you to add commandlets that appear as commands to the .NET CLI. dotnet watch executes the dotnet-watch executable. dotnet ef searches for and executes the dotnet-ef executable.
You have to add an option to the MSBuild project that installs the tool in the first place with the <DotNetCliToolReference> element. After that, dotnet restore will install the tool just like any other package.
This is described in .NET Core Command Line Tools for EF Core.
The MSBuild project file should look like this :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
</Project>
This file is enough to build your project and execute ef commands from the command line, since all *.cs files will be compiled by default
project.json is deprecated and was never supported outside preview .NET Core tooling in VS 2015. The new tooling uses csproj files and can be used in VS 2017 and VS for Mac (and others like VSCode, Rider, …).

Mulitargeting C# project files with Mono and MonoDevelop

I have a collection of csproj files that all refer to the same set of source files, but have slightly different target data making it so I need to keep the project files separate. E.g. there are WinPhone, XBox, Desktop, MonoTouch variants of the same project.
For things that really are duplicated, like the list of .cs files to compile, I'd like to consolidate the list into a single file so I don't keep having to make sure that all variations are kept in sync. I originally tried doing this by removing the sources from the .csprojs and putting them into a .targets file that got imported by all the csprojs, but that made the source files disappear from both VS and MonoDevelop.
My second attempt was by making the Desktop csproj file the primary one, and letting all the variations import that csproj with some conditional logic. This keeps the source files editable from the main csproj and they build into all flavors. Now Visual Studio understands what I was trying to do but MonoDevelop can't build it. In the MonoDevelop solution the iOS version of the core DLL is grayed out and says "(not built in active configuration)"
I've also tried xbuilding the csproj and solution, which seems to get past the problems that MonoDevelop has but hiccups on other things related to resolving monotouch assemblies. I had thought MonoDevelop used xbuild, but maybe not?
Since this works in the Windows msbuild it seems like it's either a bug or a not supported feature in Mono. Or maybe there's a better way to tackle the whole scenario... Thought I'd ask here.
For specifics,
My Core.iOS.csproj file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Build"
ToolsVersion="4.0" >
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{AE37B15F-F4BE-48DE-9F20-F00A601EC89E}</ProjectGuid>
<ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AssemblyName>Core.iOS</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="monotouch" />
</ItemGroup>
<Import Project=".\Core.csproj" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
And my Core.csproj file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Build"
ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Core</RootNamespace>
</PropertyGroup>
<!-- Using AssemblyName's presence to check for whether this is imported. -->
<PropertyGroup Condition=" '$(AssemblyName)' == '' ">
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{FC495BD8-11B1-46B0-A9DE-F245A0CBEE94}</ProjectGuid>
<AssemblyName>Core</AssemblyName>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<!-- properties similar to Debug -->
</PropertyGroup>
<ItemGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<Import Condition=" '$(AssemblyName)' == 'Core' " Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Compile Include="[...]" />
<Compile Include="[...]" />
</Project>
And, like I said, a variation of this seems to be working correctly when using VS Express for WinPhone and XBox360 projects. Is this something that should work? Is there a better way to do this?
Thanks,
Short answer:
This won't work because although MonoDevelop uses the MSBuild file format, it doesn't use the real MSBuild/xbuild engine for all project types yet. I'd suggest using links instead of an include.
Full background:
MonoDevelop has an old internal build engine that's derived from the SharpDevelop 1.0 build engine, i.e it predates the existence of MSBuild. We're in the process of migrating to MSBuild, but this has taken several stages, and is not yet complete.
A few years ago, MonoDevelop switched its project file format to a Visual Studio compatible subset of MSBuild. This was done by serializing/deserializing known MSBuild properties and items into MD's internal project model, but doing the build using the old build engine. This meant that any MSBuild projects that only used features accessible from the Visual Studio UI worked fine. However, it did not support the more advanced MSBuild features that are only accessible by hand-editing the MSBuild XML.
Later MD gained experimental support for using the xbuild/MSBuild build engine, but at the time xbuild was not mature, and it did not have MSBuild targets for all project types. It remained experimental, and build code for new project types (MonoTouch, etc) was written using the MD internal build engine.
Mono for Android needed to be supported in Visual Studio, so had to have MSBuild targets. Instead of writing and maintaining build code for two build engines, we finished up xbuild and MonoDevelop's MSBuild engine integration so it could be used for Mono for Android projects. However, we could not enable the xbuild build engine by default in MD, since many other project types did not yet have xbuild targets. Instead, we allowed project addins to force the use of the xbuild engine on a per-project-type basis.
This is essentially the current state - the xbuild engine is used for Mono for Android projects, and newer project types such as iPhone Binding projects and PLP projects, and is recommended for new project types. But older project types such as MonoTouch, MonoMac, ASP.NET etc have not yet been migrated at the time of writing.

Specifying assembly version of all projects within a web deployment wdproj script

I have a .wdproj Web Deployment Project created with VS2010 that contains references to other class libraries, like this:
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ProjectReference Include="..\Path\Proj1.csproj">
<Project>{GUID-HERE}</Project>
<Name>Proj1</Name>
</ProjectReference>
<ProjectReference Include="..\Path\Proj2.csproj">
<Project>{GUID-HERE}</Project>
<Name>Proj2</Name>
</ProjectReference>
There are lots of these. I want to be able to run msbuild /t:Rebuild /p:Configuration=Release and have all the assemblies of all the included projects compiled at a specified version. Nothing fancy just static like 2.5.6.0 and specified once in the wdproj file. I dont want to open 30 files manually.
I have looked at MSBuild Community Task and MSBuildExtension Pack and can not get anything to work. The build runs ok without errors.
Anyone have an example of how this can be done?
This is an attempt with MSBuild Extensions (adapted from the sample included) that doesn't work:
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.VersionNumber.targets"/>
<Target Name="Build">
<MSBuild.ExtensionPack.Framework.AssemblyInfo
ComVisible="true"
AssemblyInfoFiles="VersionInfo.cs"
AssemblyFileMajorVersion="2"
AssemblyFileMinorVersion="5"
AssemblyFileBuildNumber="6"
AssemblyFileRevision="0"
/>
</Target>
MSBuild is definately looking at the MSBuild.ExtensionPack.Framework.AssemblyInfo element because if the attribute names are incorrect the build will fail. This builds ok but none of the versions on the referenced assemblies are changed. The version numbers on the ASP.NET page assemblies from the website are all 0.0.0.0.
Are you maybe missing to specify the CodeLanguage and OutputFile attributes?
I think the AssemblyInfo task is intended to generate (replace) a source file prior to compiling.