1

A similar question was asked a few years ago, but I'm wondering if anything has changed in the interim or if folks have new ideas how to do this.

I've imported MSBuildTasks (MSBuild Community Tasks) as a Nuget package into a project within my solution. I can define a property for the path to the .targets file as follows:

<PropertyGroup>
    <MSBuildTasks>$(SolutionDir)Packages\MSBuildTasks.1.5.0.235\tools\MSBuild.Community.Tasks.Targets</MSBuildTasks>
</PropertyGroup>

... and then import it using:

<Import Project="$(MSBuildTasks)"/>

Of course, I may choose to update the package at a later date in which case the folder name changes, so I'd prefer to avoid hard-coding the version number. One way I thought of to avoid this was to have a powershell script look for the latest version:

function Find-PackagePath
{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)]$packagesPath,
        [Parameter(Position=1,Mandatory=1)]$packageName
    )

    return (Get-ChildItem ($packagesPath + "\" + $packageName + "*")).FullName | Sort-Object $_ | select -Last 1 
}

... and inject that as a command-line property for MSBuild:

msbuild $solutionFile "/p:Configuration=$buildConfiguration;Platform=$buildPlatform;MSBuildTasks=$MSBuildTasks";

I can confirm with a message that the injected path is indeed transmitted to my target:

<Target Name="_ReportMSBuildTasksPath" BeforeTargets="_ComputeSemanticVersion">
    <Message Text="MSBUILDTASKS = $(MSBuildTasks)"/>
</Target>

... but if I try to import using the same import statement above, I get the following error message:

The value "" of the "Project" attribute in element <Import> is invalid.  Parameter "path" cannot have zero length.

This is where I run out of ideas. How can I avoid hard-coding the version number in the tools path?

Community
  • 1
  • 1
ket
  • 728
  • 7
  • 22
  • I can understand the reasoning, but you have to ask yourself: is a version change really so often/common, that it is worth having the extra complexity? If you put the `MSBuildTasks` property into a common file, say `Paths.props`, which resides at a well known location in your source tree, then import that file into any other project file where you need the path. At least you then have to update only one place. – Christian.K Apr 21 '17 at 16:01
  • It sort of depends on how much additional complexity we're looking at. I'm using a bunch of other tools alongside MSBuildTasks (although thankfully they don't require imports!), the latest versions of which are all automatically detected by that script and fed as command-line args. Maintaining MSBuildTasks manually by itself isn't such a big deal, but I'd like to bring it into the fold, again assuming the effort isn't monumental. Having additional tools to solve problems of this sort will probably hold more value for the future than the specific problem I'm looking to solve here. – ket Apr 21 '17 at 16:16
  • Fair enough. Personally, in my project files, I have to maintain about 3 to 4 such paths (OpenCover, etc.) from NuGet packages. I use the approach outlined above. YMMV, of course ;-) – Christian.K Apr 21 '17 at 16:19

1 Answers1

0

I found it strange that you need to manually import something. MSBuildTasks NuGet package includes build\MSBuildTasks.targets. And Visual Studio should automatically add import of this file into your .csproj file.

And this import path is maintained by NuGet Package Manager in the Visual Studio.

So, you should just be able to use the tasks you need without importing anything manually.

If it does not work, then please check that .csproj file really includes autogenerated import to proper .targets file mentioned above.

Igor Labutin
  • 1,406
  • 10
  • 10
  • I'm actually building a custom .targets file that I hope to install via a nuget package; that target will be consumed by other projects, and it needs to be able to import the MSBuildTasks target. The nuspec file will specify MSBuildTasks as a dependency, which I believe means I'll get either the specified version or a newer version on install. So the import path will be specified, but I'm not sure I can guarantee it will always be the specific version I have installed. – ket Apr 25 '17 at 21:47