Chris M
Chris M

Reputation: 113

msbuild: Check if Import was successful

I installed the MSBuild Community tasks to have the "Zip" task available. Everything works fine with the following code:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

On machines where the Community Tasks aren't installed yet, Visual Studio (Enterprise 2017) entirely refuses to load the .csproj file containting the above Import statement.

Since the zip-related part is not an important step in the build process, I tried to make the .csproj also load on machines where the Community tasks are not yet installed, have msbuild issue a warning and build the zip-related targets using a condition. So I tried:

<PropertyGroup>
 <MSBuildCommunityTargets>$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets</MSBuildCommunityTargets>
</PropertyGroup>     
<Import Project="$(MSBuildCommunityTargets)" Condition="Exists($(MSBuildCommunityTargets))" />

Here the Community Tasks targets file cannot be found. The expanded $(MSBuildExtensionsPath) path points to an MSBuild folder below the VS installation folder while the Community Tasks install into an MSBuild folder directly below "Program Files (x86)". I suspect the Import statement does some compatibility search magic when expanding the $(MSBuildExtensionsPath) variable while this magic is not applied in simple property variable expansions.

Is there any proper way to check the presence of some installed third-party MSBuild tasks/targets?

Thank you.

Upvotes: 1

Views: 1239

Answers (2)

Leo Liu
Leo Liu

Reputation: 76700

Is there any proper way to check the presence of some installed third-party MSBuild tasks/targets?

Your Visual Studio version must be 2017. That because the expanded $(MSBuildExtensionsPath) path points to an MSBuild installation folder. The default value for Visual Studio 2015 and before is: C:\Program Files (x86)\MSBuild,

However, it was changed to C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild for Visual Studio 2017. And the installation path of MSBuild.Community.Tasks.msi is still C:\Program Files (x86)\MSBuild. So when you use $(MSBuildExtensionsPath) to specify the path of Community Tasks in Visual Studio 2017, you will get the error "the Community Tasks targets file cannot be found".

To resolve this issue, we could not use the variable $(MSBuildExtensionsPath) in Visual Studio 2017 before the author updates this MSI file. As a workaround, you could use the absolute path:

<PropertyGroup>
 <MSBuildCommunityTargets>C:\Program Files (x86)\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets</MSBuildCommunityTargets>
</PropertyGroup>     
<Import Project="$(MSBuildCommunityTargets)" Condition="Exists($(MSBuildCommunityTargets))" />

Or use $(MSBuildProgramFiles32) instead of $(MSBuildExtensionsPath):

<PropertyGroup>
     <MSBuildCommunityTargets>$(MSBuildProgramFiles32)\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets</MSBuildCommunityTargets>
</PropertyGroup>  

Alternatively, you can install the Community Tasks by NuGet package. Because The MSBuild Community Tasks library is also available on nuget.org via package name MSBuildTasks. To install MSBuildTasks, run the following command in the Package Manager Console:

Install-Package MSBuildTasks

After install this package, you can find below import in the project file:

<Import Project="..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets" Condition="Exists('..\packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets')" />

In this case, you do not need to modify the project file any more, and it will not be bound by the variable $(MSBuildExtensionsPath). This is what we recommend.

Upvotes: 1

Hamid Shahid
Hamid Shahid

Reputation: 4616

Is there any proper way to check the presence of some installed third-party MSBuild tasks/targets?

Can't you use the condition? Has worked for me over the years

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')" />

Upvotes: 0

Related Questions