msbuildtfsbuildmsbuildcommunitytasks

Unable to get correct MSBuildCommunityTasksPath when using MSBUILDTASKS from NuGet in a before.Solution.sln.targets script run on TFS build server


I have been using MSBUILDTASKS (installed from NuGet) successfully in project-level targets files, run on TFS build server, for a long time. Now I am trying to use it in solution-level Before and After targets file (see here).

However, used this way, it seems unable to form the correct path to the MSBuild.Community.Tasks.dll as specified in the MSBuildCommunityTasksPath property in my targets file.

If I set it like this:

<MSBuildCommunityTasksPath>$(SolutionDir)\.build</MSBuildCommunityTasksPath>

then I get this error:

D:\Builds\Agents\17\DevelopmentSTP1\My.Product\src\before.My.Product.sln.targets (9): The imported project "D:\.build\MSBuild.Community.Tasks.Targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

The actual path on the build server to the DLL is: D:\Builds\Agents\17\DevelopmentSTP1\My.Product\src\.build , so it looked like $(SolutionDir) was returning a blank, however that made no sense as $(SolutionDir) is used elsewhere in the script successfully.

If I set it like this:

<MSBuildCommunityTasksPath>$(SolutionDir).build</MSBuildCommunityTasksPath> (i.e. without the backslash)

then I get this error:

D:\Builds\Agents\17\DevelopmentSTP1\My.Product\src\before.My.Product.sln.targets (18): The "MSBuild.Community.Tasks.Attrib" task could not be loaded from the assembly D:\Builds\Agents\17\DevelopmentSTP1\My.Product\src\.build\.build\MSBuild.Community.Tasks.dll. Could not load file or assembly 'file:///D:\Builds\Agents\17\DevelopmentSTP1\My.Product\src\.build\.build\MSBuild.Community.Tasks.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.

The path is almost right now, but note the doubling of the folder name: \.build\.build

I have tried a lot of tricks to try to get it to work, like adding ..\ to try to get it to step back a folder level, but nothing works so long as I retain the $(SolutionDir) variable. The only thing that works is to hard code the physical path in, i.e.

<MSBuildCommunityTasksPath>D:\Builds\Agents\17\DevelopmentSTP1\My.Product\src\.build</MSBuildCommunityTasksPath>

Any ideas how I can make it work without hard-coding a path?

Thanks


Solution

  • I finally found the answer thanks to user VonOgre on Github. He said:

    ... the metaproj emitted by msbuild for a solution imports the before..sln.targets prior to defining the $(SolutionDir) property ... The before-solution targets will not yet have $(SolutionDir) available when doing their own imports, resulting in blanks but the after-solution targets would .... You might consider utilizing $(MSBuildThisFileDirectory) or $(MSBuildProjectDirectory) instead of $(SolutionDir), since those are low-level MSBuild properties. Either one would work in this case since before/after..sln.targets files need to be siblings to the solution file.

    So the short answer is: don't use $(SolutionDir) in a before-solution targets file - use $(MSBuildThisFileDirectory) instead.

    See https://github.com/loresoft/msbuildtasks/issues/268