How do I embed StyleCop in the solution? - msbuild

I try to integrate StyleCop in a Visual Studio solution. Installing StyleCop on each machine of each developer is something I would prefer to avoid. The suggestion I've seen several times (example) is to include the binaries of StyleCop within the project, storing them in version control.
I did that. It works on my machine, but fails on a different machine where StyleCop is not installed. After uninstalling StyleCop on my machine, it doesn't work there either.
The error message is the following:
Severity Code Description Project File Line
Error The "StyleCopTask" task could not be loaded from the assembly C:\Program Files (x86)\MSBuild..\StyleCop 4.7\StyleCop.dll. Could not load file or assembly 'file:///C:\Program Files (x86)\StyleCop 4.7\StyleCop.dll' or one of its dependencies. The system cannot find the file specified. 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. Demo
This is what I included in every .csproj file:
<Import Project="$(SolutionDir)\externs\Microsoft.StyleCop\StyleCop.targets" />
The directory C:\demo\externs\Microsoft.StyleCop contains:
The copy of all the files from C:\Program Files (x86)\StyleCop 4.7,
The copy of C:\Program Files (x86)\MSBuild\StyleCop\v4.7\StyleCop.Targets.
What's wrong?

It appears that StyleCop.Targets contains an absolute path:
<UsingTask
AssemblyFile="$(MSBuildExtensionsPath)\..\StyleCop 4.7\StyleCop.dll"
TaskName="StyleCopTask"/>
In order to be able to use StyleCop on machines where the application is not installed, change this path to something similar to:
<UsingTask
AssemblyFile="$(SolutionDir)\externs\Microsoft.StyleCop\StyleCop.dll"
TaskName="StyleCopTask"/>

Related

Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=15.0.0.0

I am using VS2017, MSBuild version 15.0. I have been installing taichi(https://github.com/yuanming-hu/taichi) .I have been facing lots of errors and trying to solve each step by step and now I am stuck with the following error. I have MSbuid 15.0 but it is looking for version 4.0 .
Build FAILED.
"C:\Users\5000\Documents\spgrid_topo_opt-master\taichi-master\build\taichi.sln" (default target) (1) ->
"C:\Users\5000\Documents\spgrid_topo_opt-master\taichi-master\build\ZERO_CHECK.vcxproj" (default target) (2) ->
(SetTelemetryEnvironmentVariables target) ->
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\IDE\VC\VCTargets\Microsoft.Cpp.DesignTi
me.targets(491,5): error MSB4062: The "SetEnv" task could not be loaded from the assembly C:\Program Files (x86)
\Microsoft Visual Studio\2017\BuildTools\Common7\IDE\VC\VCTargets\Microsoft.Build.CppTasks.Common.dll. Could not
load file or assembly 'Microsoft.Build.Utilities.Core, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f
7f11d50a3a' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask>
declaration is correct, that the assembly and all its dependencies are available, and that the task contains a p
ublic class that implements Microsoft.Build.Framework.ITask. [C:\Users\5000\Documents\spgrid_topo_opt-master\tai
chi-master\build\ZERO_CHECK.vcxproj]
0 Warning(s)
1 Error(s)
1.Please open Developer Command Prompt for VS2017(come with build tools) and type the build command like: msbuild ZERO_CHECK.vcxproj
2.Check if it makes any difference,if same issue persists open vs installer and update the build tools to latest version. Then build the C++ project to check if it helps
I configured the similar environment like yours. And use the SetEnv task in .vcxproj file. But all works well when building the project.
So if all above can't work to resolve the issue: There is possibility that you call msbuild programmatically in code. If so, maybe you can get some help from this issue:
Try binding redirection, thanks to Nicolas.
Also, you can check this thread.
Any update feel free to contact me:)
Edit your PATH environment variable to ensure the first path to a directory containing msbuild.exe is the one included with Visual Studio 2017. This may be one of the following paths, depending on the edition you have and whether you installed it to the default location.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\

.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.Community.Tasks issue with vs2017

Folks I've a set of services first created in 2012, which - down the years - have seamlessly built with Vs2010, Vs2013 & Vs2015.
When I try to build with Vs2017 I get
The MSBuild.Community.Tasks.Attrib task could not be loaded from the assembly
The assembly lives under the C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\MSBuildCommunityTasks folder, however there is no MSBuildCommunityTasks folder under the \2017\Professional\MSBuild folder.
Here's the full error
C:\working\MySolution\build\Build.proj" (default target) (1) ->
(SetAssemblyVersion target) ->
C:\working\MySolution\build\Build.proj(100,5): error MSB4062: The "MSBuild.Community.Tasks.Attrib" task could not be loaded from the assembly C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll.
Could not load file or assembly 'file:///C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll' or one of its dependencies.
The system cannot find the file specified. 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.
What changed between Vs2015 and Vs2017?
What do I need to do to fix this?
Explicitly setting the MSBuildCommunityTasksPath property gets past the problem.
I do this at the top of my build.proj file.
(For historic reasons we keep the community build tasks in our repo, which is why it's set to a location under trunk)
<MSBuildCommunityTasksPath>$(trunk)\Ref\Build\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
The extensions are most likely installed in 'C:\Program Files (x86)\MSBuild'. So I currently set the variable explicitly in my proj as a workaround.
<MSBuildExtensionsPath>C:\Program Files (x86)\MSBuild</MSBuildExtensionsPath>
Installing .Net Framework 3.5 development tools in VS2017 individual components section fixed my build.

How to create WiX.targets file

I'm working on an existing WiX project. The project imports a wix target file.
<Import Project="$(MSBuildExtensionsPath)\MyCompany\MyTargetFile.targets" />
Unfortunately, I cannot seem to find this file anywhere. How was it created in the first place?
As you may know, WiX project files are Visual Studio project files, are MSBuild project files. Target files are MSBuild project files but only contain MSBuild targets that might be used in building projects.
$(MSBuildExtensionsPath) is a common place to put targets files. From the name of your target file and the fact that is it is located under $(MSBuildExtensionsPath), I'd say, you are looking for one that was written by MyCompany and planned to be used by several projects. You might find it on another machine at MyCompany—perhaps on a build server.
Some useful links:
MSBuild
MSBuild Targets
How to: Use the Same Target in Multiple Project Files

How to use MSBuild.ExtensionPack

I have to run two targets in parallel to profile iisexpress.exe using OpenCover.
The link below relates to the information about the issue I am having.
https://github.com/sawilde/opencover/issues/92#issuecomment-5143204
This suggested to me to use Msbuild.ExtensionPack from CodePlex.
I have downloaded the source code of MSBuild Extensions.
I compiled it. I copied the MSBuild.ExtensionPack.tasks tasks file in to folder BuildBinaries.
I added the below lines in my projects files.
I was trying to run the ExecMultipleTasks target. But getting the below error.
error MSB4036: The "MSBuild.ExtensionPack.Framework.Parallel" task was not found. Check the following:
1.) The name of the task in the project file is the same as the name of the task class.
2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface.
3.) The task is correctly declared with in the project file, or in the *.tasks files located in the "C:\Windows\Microsoft.NET\Framework\v4.0.30319" directory.
Could you please let me know how to fix this issue?
Thanks,
Venkat.
which version of visual studio your application is using ?, if its 32 bit of VS then install 32 bit Extension Pack (MSBuild.Extension.Pack.4.0.12.0.zip\4.0.12.0\x86) else go for 64 bit.
If you open up the file C:\Program Files (x86)\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks ill think you find that the path to the dll for the task MSBuild.ExtensionPack.Framework.Parallel is not correct.
<UsingTask AssemblyFile="$(ExtensionTasksPath)MSBuild.ExtensionPack.dll" TaskName="MSBuild.ExtensionPack.Framework.Parallel"/>
I imagine the variable $(ExtensionTasksPath) does not locate your build path for your version. Either copy the files into that path or change/hardcode the new path.