Copy task not working in MSBuild 4 - .net-4.0

<Copy SourceFiles="#(sourceFiles)" DestinationFolder="$(destinationFolder)\"/>
This used to work fine for me in MSBuild 3.5. But since I've been trying to migrate to 4.0, MSBuild throws me this error.
The "Microsoft.Sdc.Tasks.Folder.Copy" task could not be loaded from the assembly Microsoft.Sdc.Tasks.dll. 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've tried putting the UsingTask, but still in vain. Any ideas?

The reason is simple,
You install http://sdctasks.codeplex.com/ in .NET 2.0 GAC. So MSBuild 2.0 or 3.5 can load it successfully.
.NET 4 uses a different GAC, so MSBuild 4 cannot find what you install in .NET 2 GAC.
Therefore, you see an error message.
My advice,
Switch to MSBuild Community Pack as suggested by http://sdctasks.codeplex.com/.
Instead of adding an MSBuild extension assembly into GAC, you should put it into your dependency folder (such as lib), and add it to source control.
When modifying your project file (such as csproj), make sure that in <UsingTask> you use the assembly path to your dependency folder.
My open source project #SNMP uses Gendarme MSBuild extension, and I have been using the above trick for a long time,
https://github.com/lextm/sharpsnmplib/blob/master/SharpSnmpLib/SharpSnmpLib.csproj

Related

How can I get GitVersion /UpdateAssemblyInfo to work with ASP.NET Core 2.0 project

We have been using a Bamboo build server for a while now and we have GitVersion installed so it can be selected as a task in the Build plan. We typically use the /UpdateAssembleInfo argument when we run the task. For .NET Framework projects, this would update the assemblyinfo file in the source with the bamboo versioning settings so the .NET assemblies had the same version info as our Bamboo builds and subsequent Bamboo deployment, allowing us to know the version of the deployed project in the field by examining the assembly file properties. This was all working quite well.
However, we are now building and deploying .NET Core 2.0 solutions and are finding that GitVersion /UpdateAssemblyInfo is not working.
I searched for a fix for .NET Core but was only able to find solutions that involved using the project.json file, which is no longer used with .NET Core 2.0 ( it changed to the *.csproj file).
I looked at http://gitversion.readthedocs.io/en/latest/usage/command-line/ and I tried running
gitversion.exe /UpdateAssemblyInfo MyProjectName.AssemblyInfo.cs /EnsureAssemblyInfo
where MyProjectName represents the actual project name suffix for the assemblyinfo.cs file in the .NET Core 2.0 ..\\obj\release\netcoreapp2.0 folder. But it did not update that file.
I have to assume that there has to be a solution for using GitVersion with Bamboo and.NET Core 2.0 but I am having a hard time finding one.
Any ideas?
The latest version of GitVersion provides /updateprojectfiles switch to update version info in the Sdk-style .csproj/.vbproj/.fsproj recursively.
From GitVersion/Usage/CommandLine/Arguments:
/updateprojectfiles
Will recursively search for all project files
(.csproj/.vbproj/.fsproj) files in the git repo and update them
Note: This is only compatible with the newer Sdk projects
It produces the needed attributes even if they are not present in the project files, resulting in following properties:
<Project>
<PropertyGroup>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<InformationalVersion>1.0.0-versionNumber.N+Branch.branchName.Sha.commitId</InformationalVersion>
<Version>1.0.0-versionNumberNNNN</Version>
</PropertyGroup>
As a workaround, you may consider specifying the assembly info as project properties in .csproj
<PropertyGroup>
<Version>1.2.3.4</Version>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
...
</PropertyGroup>
and then setting values during dotnet build. In addition to its options, the dotnet build command accepts MSBuild options like /property
/property:name=value
/p:name=value
Set or override the specified project-level properties, where name is the property name and value is the property value. Specify each property separately, or use a semicolon or comma to separate multiple properties.
So your build command will be something like
dotnet build /p:Version=1.2.3.4;AssemblyVersion=1.2.3.4

JetBrains Rider - The task factory "CodeTaskFactory" could not be loaded from the assembly

I am trying to build a former Windows project in JetBrains Rider on a Mac. I am getting the following build error:
NuGet.targets(100, 9): [MSB4175] The task factory "CodeTaskFactory"
could not be loaded from the assembly
"/Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/msbuild/15.0/bin/Microsoft.Build.Tasks.v4.0.dll".
Method 'Microsoft.Build.Utilities.TaskLoggingHelper..ctor' not found.
Can anyone help?
This happens because custom msbuild code or NuGet packages you use are using a pre-MSBuild 15 way of referencing MSBuild's CodeTaskFactory.
Check all of your project / build files for occurrences of UsingTask elements referencing Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll or Microsoft.Build.Tasks.v4.0.dll (or similar dll reference) and change the dll to Microsoft.Build.Tasks.Core.dll.
If the problematic code comes from a NuGet package, see if an update to the package is available or contact its authors.

.net core msbuild nuget with additional assemblies

This sample shows a .NET Core project which can be packaged into a nuget package just using dotnet pack, and when restored in another project, it integrates in the msbuild pipeline. One of the great things about this sample is it creates a nuget package that integrates with msbuild on linux, mac and Windows. However, the custom build code doesn't have dependencies on any other assemblies.
How can I adapt this sample to use code that uses a dependency?
Here are my failed attempts:
Attempt 1
I added a package reference to Newtonsoft.Json and changed the code to do some JSON serialisation. However, in the project that uses the build nuget, when I do a dotnet publish, I get the following error:
error MSB4018: The "Zip" task failed unexpectedly. [C:\git\MSBuild-Features-With-Nate-McMaster\Video-2\1-NuGet\Web.csproj]
error MSB4018: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified. [C:\git\MSBuild-Features-With-Nate-McMaster\Video-2\1-NuGet\Web.csproj]
Additionally, if my project didn't already have a dependency on JSON.NET, adding the build nuget would unnecessarily add it.
Attempt 2
I used nuget.exe spec to create a .nuspec file. At the end of the file, I added:
<files>
<file src="bin\Release\**" target="build" />
<file src="build\**" target="build" />
</files>
However, both "dotnet pack" and "msbuild /t:pack" ignore the file, and nuget.exe pack fails with the error Unable to find 'bin\Release\0-WriteATask\bin\Release\'. Make sure the project has been built..
If I try nuget.exe pack Zipper.nuspec or msbuild /t:pack /p:NuspecFiles=Zipper.nuspec, they both fail with the message Value cannot be null or an empty string..
Attempt 3
I edited the nuspec to remove all of the placeholders that are normally calculated from the project (any string starting and ending with a $). Then, doing a nuget.exe pack Zipper.nuspec created a nupkg file, and the net46 folder contains Newtsonsoft.Json.dll, but the netstandard1.3 folder does not.
The way MSBuild loads a task assembly can make it tricky to load additional assemblies that you may depend on.
Typically, the easiest way to solve this is to ship a copy of your dependencies inside your NuGet package. But your dependencies alongside your task assembly file in the package. There may be some additional complications that require you to use AssemblyLoadContext or the AppDomain.AssemblyResolve event.
You can do this without a nuspec file by forcing MSBuild to copy your assemblies into the local build output, and then copying them into your package. Set CopyLocalLockFileAssemblies=true, and add the items to _PackageFiles
Here's an example of how to do that: https://github.com/madskristensen/BundlerMinifier/blob/3333b5c38289a247391966443370ee6f4a29bf26/src/BundlerMinifier/BundlerMinifier.csproj#L35-L47
Hopefully, this will be addressed in the future, https://github.com/Microsoft/msbuild/issues/1312, and the task assembly resolution will use the NuGet cache.
Try it with the 9.0.1 version of Newtonsoft.Json, it worked for me, all these dll load problems went away, and it still targets .NET Standard. Although I did copy all the dependencies next to the task dll, but with the 10.x version even that didn't help.

MSBuild Using Wrong Version of Assembly to Compile RDLC File

I am using the reportviewer control from VS 2010 to create client side reports (rdlc). Everything is working fine on my development machine, and when I manually compile (via VS2010) and manually deploy to a test machine that doesn't have development tools installed.
In order to get the test machine to work (without installing VS2010 or ReportViewer.exe), I had to add references in my project to Microsoft.ReportViewer.Winforms, Microsoft.ReportViewer.Common and Microsoft.ReportViewer.ProcessingModel and have them all "Copy Local".
I have the rdlc files configured for Build Action => embedded resources. This is the default setting when adding a new rdlc to the project. I am open to configuring this otherwise if this would resolve this problem (no idea if its related).
The problem: since adding the rdlc files, the solution no longer builds on the build server. I have installed ReportViewer.exe on the build server, and have verified that the required assemblies exist in the GAC. The .Net 4 framework is NOT installed on the build server--I don't think this is required because the solution targets the 3.5 runtime.
I believe the root of the problem is the following from the build log:
Target "RunRdlCompiler": Building
target "RunRdlCompiler" completely.
Output file
"obj\Release\RdlCompile.compiled" does
not exist. Using "RdlCompile" task
from assembly
"Microsoft.ReportViewer.Common,
Version=9.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a". Task
"RdlCompile":
Report\RDLC\GreenReport.rdlc (0,0):
error rsInvalidReportDefinition: The
report definition is not valid.
Details: The report definition has an
invalid target namespace
'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition'
which cannot be upgraded.
From what I can tell, Microsoft.ReportViewer.Common version 10.0.0.0 is what should be used to "compile" the rdlc, but MSBuild appears to be using 9.0.0.0. I believe if I could force it to use the right version (which IS installed in the GAC), the solution would compile.
This is because your Microsoft.Common.Targets file is pointing to the 9.0 version of the assembly.
If you look in [sysdir]\Microsoft.NET\Framework\v3.5 you will find Microsoft.Common.targets, which is driving a lot of what MSBuild does. This verion of the common targets file points to [Program Files]\MSBuild\Microsoft\VisualStudio\v9.0\ReportingServices\Microsoft.ReportingServices.targets forcing MSBuild to run with the 9.0 version.
When you installed .NET 4.0, you got a new common targets file in the v4.0.x directory, this new one now points to [Program Files]\MSBuild\Microsoft\VisualStudio\v10.0\ReportingServices\Microsoft.ReportingServices.targets which points to the 10.0 version of the ReportViewer assemblies.
The 10.0 ReportViewer is compiled against .NET 3.5 and intended to work in both 3.5 and 4.0. You could very likely get rid of the .NET 4.0 framework, and alter your 3.5 common targets file to point to the new ReportingServices target file, and it should work. In theory anyway, I've never actually tried it. You may be best off just sticking with 4.0, as that's what we intended when we designed the MSBuild support for the new viewer.
Just install Microsoft Report Viewer 2010 SP1.
I had a very similar issue. Just all of a sudden I could no longer build a VS2010 project that contained an .rdlc file. I wasn't converting any reports or using a report server, everything was local. I tried creating a brand new project and adding an empty new rdlc report and hit build and it wouldn't work. Just one day it stopped compiling and gave me the following error:
The report definition is not valid. Details: The report definition has an invalid target namespace 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition' which cannot be upgraded.
Turns out the issue was my "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\ReportingServices\Microsoft.ReportingServices.targets" file had somehow changed. The top of my file was:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.Common, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
And it should have been:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
I changed that one "Using Task" line in the file and everything builds again. REALLY frustrating and it ate up two days of my life. Hoping posting this comment may help someone else in a similar situation.
Jim Lafler
I have tried re-installing all and it didnt work. Then, I tried updating Microsoft.ReportingServices.targets as per Jim's post but even didnt work for me.
At the end, I just copied Microsoft.ReportingServices.targets from other machine (where it was running without error). And surprisingly, it is working.
The additional difference I noticed while comparing, to change PublicKeyToken along with Version.
This may be the case for me only but Jim's post was much useful.
SFUH
Turns out I did need the .Net 4.0 Framework, and more specifically the 4.x version of MSBuild, which uses the newer version of the Microsoft.ReportViewer.Common library.
So even if you are targeting the 3.5 framework, if you create the rdlc with VS2010 it will expect to be "compiled" using 4.0 tools.
I have the same problem: we using ReportViewer 2012 (version of assemblies starts with 11). Both on local machines and on build machine are installed ReportViewer 2012 package and VisualStudio 2013. On local machines compilation in VS succeeds, but on build machine during queued build MSBuild throws such error:
The report definition is not valid. Details: The report definition has an invalid target
namespace 'http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition'
which cannot be upgraded.
I tried to modify Microsoft.Common.targets from .NET 3.5 folder in way, that is described in this post, but no effect. Then I opened Microsoft.Common.targets from .NET 4.0 folder, and found there such strings:
<!-- VS10 without SP1 and without VS11 will not have VisualStudioVersion set, so do
that here -->
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)'
==''">10.0</VisualStudioVersion>
</PropertyGroup>
Then I realized that problem may be in incorrect value of variable $(VisualStudioVersion), so I added to build definition in section "Process" this MSBuild parameter:
/p:VisualStudioVersion=12.0
And it worked! Build completed successfully.
Hope this will help someone.
Pasting file paths doesn't seem to be going through... how about this:
Was:
TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.Common, Version=8.0.0.0...
And is now:
TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=10.0.0.0...
James
The NetFx40_LegacySecurityPolicy was enabled in my devenv.exe.config, and when I commented this line out, the project built successfully.
We had enabled the legacy security policy on our team to enable our team to work with DevExpress 7.2 controls from within Visual Studio 2010, but in this case, it shows that the approach we took is not always the best.
I lost 2 full days of development due to a similar issue. On building my project it would succeed, but on rebuild it failed with no errors. On investigating the verbose build log in the Output window it directed me towards a problem with the rdlcompile function (so reporting services local report embedding issue). After trying every thing I finally manage to resolve the issue, but disabling my virus scanner. The Antivirus was somehow interfering with my rebuild and caused the rebuild to fail.
After disabling virus scan, rebuild works 100%
I have same problem on my Visual Studio 2013.
The dll version of reporting service on my project is Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
When i checked my ReportingServices targets
C:\Program Files\MSBuild\Microsoft\VisualStudio\v12.0\ReportingServices\Microsoft.ReportingServices.targets
I found the task version is 11.0.0.0
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
When i changed the task version to 10.0.0.0 corresponding to dll version on my proejct.
<UsingTask TaskName="Microsoft.Reporting.RdlCompile" AssemblyName="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
It' worked.
I just removed this file from my file system. The reports are simply ambedded no need to be compiled.
c:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\V11.0\ReportingServices\Microsoft.ReportingServices.targets
this worked fine for me and for my build server.

Custom MSBuild task with dependencies

I have written an MSBuild task that makes use of third-party assemblies.
When I use the task in my project, MSBuild complains that it can't load the third-party assemblies (not surprisingly).
Where should I place the third-party assemblies so that they are available to MSBuild. I tried adding project references to them without success.
I'm not sure if I expressed my problem very well, but now I've found the solution.
In my .proj file, I reference my custom task with the following syntax...
<UsingTask AssemblyFile="..\lib\MyCompany.MSBuild\MyCompany.MSBuild.dll" TaskName="CreateDatabase" />
My CreateDatabase task relies on various 3rd-party assemblies. However, some of these are only referenced via reflection, so weren't included by default in the folder "..\lib\MyCompany.MSBuild".
I had been trying to get the task to work by placing the required assemblies in the same directory as the .proj file invoking the task.
However, what I should have been doing was putting the assemblies in the referenced task directory "..\lib\MyCompany.MSBuild\".
Simple!
You could add them to the GAC (Global Assemby Cache). This only works if it is strongly named.
You could also make sure that you have marked them with copy local = true when you added the reference in the project.