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

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.

Related

Integrating ConfuserEx in MsBuild

I am trying to integrate ConfuserEx version 1.6 in MsBuild. It suppose to obfuscate the files automatically but it's not working for me. I have added Confuser.MsBuild v1.6 nuget package to the project.
Can somebody help me if I am missing any step.
After adding the Confuser.MsBuild nuget to your project the following lines should be added automatically to your *.csproj file:
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Confuser.MSBuild.1.6.0\build\Confuser.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Confuser.MSBuild.1.6.0\build\Confuser.MSBuild.targets'))" />
</Target>
<Import Project="..\packages\Confuser.MSBuild.1.6.0\build\Confuser.MSBuild.targets" Condition="Exists('..\packages\Confuser.MSBuild.1.6.0\build\Confuser.MSBuild.targets')" />
Now you are able to include the obfuscation to the build process. This is also done in the *.csproj file with a minimal entry like:
<PropertyGroup>
<Obfuscate>true</Obfuscate>
<ConfuserReplaceOutput>true</ConfuserReplaceOutput>
</PropertyGroup>
Fore more and detailed information and options check out the ConfuserEx wiki.

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.

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

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>

How to change Assembly Version Number using AssemblyInfoTask?

I am trying to automate the process for setting the Version for all DLL's, after spending some time I came to know the AssemblyInfo Task with which it can most likely be achieved.
So I went ahead and installed it, specifically version 1.0.51130.0.
After Installing, I manually added the Import Tag (by unloading the each project) of AssemblyInfoTask in .cspoj files (the solution has more than 35 proj files).
<Import Project="$(MSBuildExtensionsPath)\Microsoft\AssemblyInfoTask\Microsoft.VersionNumber.Targets"/>
Next I modified the Microsoft.VersionNUmber.Target file which will be installed in path: C:\Program Files\MSBuild\Microsoft\AssemblyInfoTask, and I modified the following section:
<!-- Properties for controlling the Assembly Version -->
<PropertyGroup>
<AssemblyMajorVersion>4</AssemblyMajorVersion>
<AssemblyMinorVersion>0</AssemblyMinorVersion>
<AssemblyBuildNumber></AssemblyBuildNumber>
<AssemblyRevision></AssemblyRevision>
<AssemblyBuildNumberType>DateString</AssemblyBuildNumberType>
<AssemblyBuildNumberFormat>01MMdd</AssemblyBuildNumberFormat>
<AssemblyRevisionType>AutoIncrement</AssemblyRevisionType>
<AssemblyRevisionFormat>00</AssemblyRevisionFormat>
</PropertyGroup>
<!-- Properties for controlling the Assembly File Version -->
<PropertyGroup>
<AssemblyFileMajorVersion>4</AssemblyFileMajorVersion>
<AssemblyFileMinorVersion>0</AssemblyFileMinorVersion>
<AssemblyFileBuildNumber></AssemblyFileBuildNumber>
<AssemblyFileRevision></AssemblyFileRevision>
<AssemblyFileBuildNumberType>DateString</AssemblyFileBuildNumberType>
<AssemblyFileBuildNumberFormat>01MMdd</AssemblyFileBuildNumberFormat>
<AssemblyFileRevisionType>AutoIncrement</AssemblyFileRevisionType>
<AssemblyFileRevisionFormat>00</AssemblyFileRevisionFormat>
</PropertyGroup>
Next I set the assemblyInfo.cs file's version to 1.0.0.0 in every project. Finally I saved and close it, reopened solution, and built. It works like a champ!
Now what want is to customize the Version to 4.0.1053.1 where 10 is the part of year indicator which is 2010 and 53 denotes the week number, at last 1 denotes revision number.
How to achieve this using the AssemblyInfo Task? I came across several posts that a new version of AssemblyInfo Task is available in Build Extension Pack.
I have installed the MSBuild Extension Pack December 2010 and its version is MSBuild Extension Pack 4.0.2.0 Installer
First.. use a globalassemblyinfo.cs that is linked from each project.
Add its as linked file to each project.
This means you update one file, not 30+ assemblyinfo files...then:
use MSBuild.Community.Tasks....
Then call
<AssemblyInfo CodeLanguage="CS"
OutputFile="$(VersionFile)"
AssemblyCompany="Company"
AssemblyProduct="Product"
AssemblyCopyright="Copyright © Company 2011"
ComVisible="false"
AssemblyVersion="$(BUILD_NUMBER)"
AssemblyFileVersion="$(BUILD_NUMBER)" />
Assuming you have something like:
<Import Project=".\tasks\MSBuild.Community.Tasks.Targets"/>
I do this in Jenkins by having a package build that is parameterised using the List Subversion Tags parameter type. The Subversion tag must follow the version number format (major.minor.revision.build), e.g. tags/2.0.0.1. The tag name is then assigned to a Jenkins parameter, e.g. $VERSION becomes 2.0.0.1
I use the WriteLinesToFile msbuild task to write out the assembly attribute to a second file alongside the PropertyInfo.cs called VersionInfo.cs. As checked in to source control, this just contains a default version number:
// Do not change this. The version is set on package builds only by setting the AsmVersion MSBuild property
[assembly: System.Reflection.AssemblyVersion("0.0.0.0")]
The package build on the build server passes in the version via the AsmVersion parameter:
/p:AsmVersion=$VERSION
The .csproj file is modified to have a BeforeBuild target (Visual Studio creates a commented out one for you):
<Target Name="BeforeBuild">
<WriteLinesToFile
Condition=" '$(AsmVersion)' != '' " File="Properties\VersionInfo.cs"
Overwrite="True"
Lines="[assembly: System.Reflection.AssemblyVersion("$(AsmVersion)")] // Generated by build" />
</Target>
When building in Visual Studio, or without passing in the AsmVersion, your assembly will have a default version of 0.0.0.0. When building in the package build, you will get your desired build number.
As #bruceboughton proposed, you can easily generate a version assembly file during compilation without using MSBuild.Community.Tasks library:
<PropertyGroup>
<Version>0.0.0</Version>
<InformationalVersion>0.0.0-dev~commithash</InformationalVersion>
<VersionFileName>$(BaseIntermediateOutputPath)Version.cs</VersionFileName>
</PropertyGroup>
<Target Name="GenerateVersionFile" BeforeTargets="BeforeBuild">
<WriteLinesToFile
File="$(VersionFileName)"
Overwrite="True"
Lines="
[assembly: System.Reflection.AssemblyVersion("$(Version)")]
[assembly: System.Reflection.AssemblyFileVersion("$(Version)")]
[assembly: System.Reflection.AssemblyInformationalVersion("$(InformationalVersion)")]" />
<ItemGroup>
<Compile Include="$(VersionFileName)" />
</ItemGroup>
</Target>
Remove definitions of the parameters you specify in the generated file from Properties\AssemblyInfo.cs file.
After that you can specify version by adding a parameter to the msbuild:
msbuild /property:Version=1.2.3 /property:InformationalVersion=1.2.3-dev~commithash .\SolutionFile.sln
Update for .NET Core style .csproj files: If you've come upon this question after having transitioned to the new .csproj format used by .NET Core, you can just set the Version property (no need to to bother with MSBuild tasks).
How I finally got this to work MSBuild version 12 (VS 2013).
Used Nuget to get MSBuildTasks Community package
Edited my .csproj file and added a path to the import the package:
<Import Project="..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets" Condition="Exists('..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.target')"/>
Figured out the Regex to change just the Revision number in the AssemblyInfo.cs file:
(?<=AssemblyFileVersion\("[0-9]\.[0-9]\.[0-9]\.)(\*)
which is not XML compatible, so has to be changed to:
(?<=AssemblyFileVersion\("[0-9]\.[0-9]\.[0-9]\.)(\*)
Uncommented the <Target Name="BeforeBuild"> section and added the following:
<Target Name="BeforeBuild">
<FileUpdate Files="properties\AssemblyInfo.cs"
Regex="(?<=AssemblyFileVersion\("[0-9]\.[0-9]\.[0-9]\.)(\*)"
ReplacementText="$(Revision)" />
</Target>
When running MSBuild added the "Revision" property to the command line e.g.
msbuild.exe myProject.csproj /t:Build /p:Configuration=Release;Revision=12345

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.