MSBuild Task and Roslyn - msbuild

We have written our own MSBuild Task and want to use Roslyn within this task.
We are referencing
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Tasks.Core
Microsoft.Build.Utilities.Core
each with version v14.0 to be as low as possible.
If we now install Microsoft.CodeAnalysis via Nuget (We tried Latest 2.8.2, or even 1.3.2), and are using a Type, we get a ReflectionTypeLoadException with an inner loaderexception of type FileNotFoundException ("System.Collections.Immutable, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
I assume this is because the msbuild.exe is running within the msbuild path, and is not probing our path for the dependencies, but the question would be how we should solve this situation?
Thanks for any hint!

Related

MSB4062 error when running msbuild with grunt

I'm geting following error with msbuild run with grunt. From command line msbuild transform config runs fine. Have tried to install all the microsoft dependencies.
Any ideas what coule be the problem and is there some way to force grunt task to use visual studio build tools. To me it seems like grunt tries to use frame work build tools.
error MSB4062: The "TransformXml" task could not be loaded from the assembly C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBu
ild\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll. Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Th
e 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.
Best Regards
Arto Hänikäinen

Nuget dependencies loading except for ConfigCat in GitHub Actions

For some reason GitHub Actions is not pulling in one Nuget package ConfigCat.Client but works fine for the remaining 20 packages. This is one solution with many projects. It works fine in VS Build as well as local msbuild command. I have another simple solution in GitHub Actions that works fine as well. I'm using a win-2019 server runner with .NET SDK 5.0. I get:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2203,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "ConfigCat.Client, Version=6.5.2.0, Culture=neutral, PublicKeyToken=d28b16a067d7bbe2, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
I'm running this (restore & build):
msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
msbuild $env:Solution_Path /p:Platform="Any CPU" /p:Configuration=Release /p:UapAppxPackageBuildMode=SideloadOnly /p:AppxBundle=Always /p:PackageCertificateKeyFile=$certificatePath /p:PackageCertificatePassword=${{ secrets.Pfx_Key }}
Errors from log file (could it be related to processorArchitecture=MSIL?)
2022-08-28T03:05:23.6891561Z Primary reference "ConfigCat.Client, Version=6.5.1.0, Culture=neutral, PublicKeyToken=d28b16a067d7bbe2, processorArchitecture=MSIL".
2022-08-28T03:05:23.6894672Z C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2203,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "ConfigCat.Client, Version=6.5.1.0, Culture=neutral, PublicKeyToken=d28b16a067d7bbe2, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. [D:\a\DataProduction\DataProduction\BigLebowski\Services\FeatureFlagService\FeatureFlagService.csproj]
2022-08-28T03:05:23.6896617Z For SearchPath "{HintPathFromItem}".
2022-08-28T03:05:23.6897448Z Considered "D:\a\DataProduction\DataProduction\BigLebowski\packages\ConfigCat.Client.6.5.1\lib\net45\ConfigCat.Client.dll", but it didn't exist.
I've also tried changing the Platform to x64 with the same results.
Any insight or pointers is greatly appreciated.
Thanks to Péter Csajtai for solving the problem. The project was using packages.config and not restoring the nuget package as a result. Adding the parameter /p:RestorePackagesConfig=true to the restore resolved the issue. See also this question.

.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.

Issues with MsBuild, SpecificVersion, and VSTS

The scenario is as follows:
We have a set of common .net libraries:
CommonLib.Main
CommonLib.Specialized
We have a CI build that builds both of these libraries, and places them into our NuGet repo. Both are available as individual NuGet packages - a user may want to load just Main, or they can pull the Specialized package, which will include Main.
Specialized references Main as a Nuget package.
I'm currently making some upgrades to these packages.
First, I upgraded Main. I updated the version of Main in AssemblyInfo from 1.1.0. to 2.0.0.
MsBuild will include the build number in the "*" location.
The CI Build ran, and a version of Main called "CommonLib.Main, version=2.0.0.345" was published to our NuGet repo. On the Nuget repo, the version is listed as "2.0.0", as I would expect.
Next, I upgraded CommonLib.Specialized, and I updated the NuGet reference to CommonLib.Main, version=2.0.0.
I checked in these changes, and the CI build ran again.
So now, the CI build has create a new version of Main, with version 2.0.0.346, and placed it on the NuGet repo.
Here's the problem:
Now, when we run our CI build again, the build of CommonLib.Specialized fails, because in the .csproj, it looks like this:
<Reference Include="CommonLib.Main, Version=2.0.0.345, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\CommonLiib.Main-2.0.0\lib\net461\CommonLib.Main</HintPath>
</Reference>
But, in packages.config, it has
<package id="CommonLib.Main" version="2.0.0" targetFramework="net461" />
Which pulls down CommonLib.Main, Version=2.0.0.346.
Our build fails here:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64\Microsoft.Common.CurrentVersion.targets(1964,5): warning MSB3245: Could not resolve this reference. Could not locate the assembly "CommonLib.Main, Version=2.0.0.345, Culture=neutral, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
For SearchPath "{HintPathFromItem}".
Considered "..\packages\CommonLib.Main-2.0.0\lib\net461\CommonLib.Main.dll",
but its name "CommonLib.Main, Version=2.0.0.**346**, Culture=neutral, PublicKeyToken=null"
didn't match the expected name "CommonLib.Main, Version=2.0.0.**345**, Culture=neutral, processorArchitecture=MSIL".
I think I could fix this by setting SpecificVersion to false in the project, but that seems rather crude. Is there a better way to resolve this issue? I feel like I shouldn't have to refresh the NuGet references after every build.

Copy task not working in MSBuild 4

<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