visual-studiomsbuildmsbuild-taskmsbuildcommunitytasks

MSBuild: How to access a property value set by a Target during the Post Build event in Visual Studio


I have a PostBuild event which invokes a batch file and I need to pass in a particular parameter into the batch file. This parameter is populated through another task which is invoked through a Target configured to run before the PostBuildEvent.

I can see that it gets successfully displayed when displayed using the element as part of the section.

But $(TargetFrameworkToolsFolderPath) under the PostBuildEvent has an "" value. Is there a way to access this custom property in the post build event?

Example:

<UsingTask TaskName="GetTargetFrameworkToolsFolderName" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
   <ParameterGroup>
     <SDKFolderPath ParameterType="System.String" Required="true" />
     <TargetFrameworkVersionStr ParameterType="System.String" Required="true" />
     <TargetFrameworkToolsFolder ParameterType="System.String" Output="true" />
   </ParameterGroup>
   <Task>
     <Code Type="Fragment" Language="cs">
        TargetFrameworkToolsFolder = SDKFolderPath + "\\" + "bin\\NETFX " + TargetFrameworkVersionStr.Substring(1) + " Tools\\";
     </Code>
   </Task>
</UsingTask>

<Target Name="FindTargetFrameworkToolsFolderPath" BeforeTargets="PostBuildEvent">
   <GetFrameworkSdkPath>
     <Output TaskParameter="Path" PropertyName="SdkPath" />
   </GetFrameworkSdkPath>
   <GetTargetFrameworkToolsFolderName SDKFolderPath="$(SdkPath)" TargetFrameworkVersionStr="$(TargetFrameworkVersion)">
     <Output PropertyName="TargetFrameworkToolsFolderPath" TaskParameter="TargetFrameworkToolsFolder"/>
   </GetTargetFrameworkToolsFolderName>
   <Message Text="$(TargetFrameworkToolsFolderPath)" Importance="normal" /> --> Displayed correctly here
</Target>

<PropertyGroup>
   <PostBuildEvent>
      call $(ProjectDir)AfterBuildCommands.bat $(TargetFrameworkToolsFolderPath) --> The TargetFrameworkToolsFolderPath property value here seems to be empty.
   </PostBuildEvent>
</PropertyGroup>

Solution

  • But $(TargetFrameworkToolsFolderPath) under the PostBuildEvent has an "" value. Is there a way to access this custom property in the post build event?

    In fact, <PostBuildEvent> is a property and MSBuild reads all the properties first and then executes all targets.

    If you put these below outside the target which defines the property TargetFrameworkToolsFolderPath, these below will always execute first, as expected, the values of TargetFrameworkToolsFolderPath will be empty.

    To avoid it, you should put the PostBuildEvent and TargetFrameworkToolsFolderPath properties in the same target and make sure the target is executed early enough, such as, run after PrepareForBuild target.

    <PropertyGroup>
       <PostBuildEvent>
          call $(ProjectDir)AfterBuildCommands.bat $(TargetFrameworkToolsFolderPath) --> The TargetFrameworkToolsFolderPath property value here seems to be empty.
       </PostBuildEvent>
    </PropertyGroup>
    

    Solution

    Try this below:

     <UsingTask TaskName="GetTargetFrameworkToolsFolderName" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
        <ParameterGroup>
          <SDKFolderPath ParameterType="System.String" Required="true" />
          <TargetFrameworkVersionStr ParameterType="System.String" Required="true" />
          <TargetFrameworkToolsFolder ParameterType="System.String" Output="true" />
        </ParameterGroup>
        <Task>
          <Code Type="Fragment" Language="cs">
            TargetFrameworkToolsFolder = SDKFolderPath + "\\" + "bin\\NETFX " + TargetFrameworkVersionStr.Substring(1) + " Tools\\";
          </Code>
        </Task>
      </UsingTask>
      <Target Name="MyFindTargetFrameworkToolsFolderPath" AfterTargets="PrepareForBuild">
        <GetFrameworkSdkPath>
          <Output TaskParameter="Path" PropertyName="SdkPath" />
        </GetFrameworkSdkPath>
        <GetTargetFrameworkToolsFolderName SDKFolderPath="$(SdkPath)" TargetFrameworkVersionStr="$(TargetFrameworkVersion)">
          <Output PropertyName="TargetFrameworkToolsFolderPath" TaskParameter="TargetFrameworkToolsFolder" />   
        </GetTargetFrameworkToolsFolderName>
    
        <PropertyGroup>
          <PostBuildEvent> call $(ProjectDir)AfterBuildCommands.bat $(TargetFrameworkToolsFolderPath) --> The TargetFrameworkToolsFolderPath property value here seems to be empty.</PostBuildEvent>
        </PropertyGroup>
        <Message Text="$(TargetFrameworkToolsFolderPath)" Importance="normal" />   
    
      </Target>
    

    Hope it could help you.