0

In .csproj file is set:

<PropertyGroup>     
  <Company>Acme</Company>
  <Product>NextBigThing</Product> 
</PropertyGroup>

I would like use variables in following Post-Build-Event:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
  <Exec Command="xcopy <source> %AppData%\<Company>\<Product>\" />
</Target>

How to use Company and Product variable as part of path in Post-Build-Event?

3 Answers 3

1

My solution using PowerShell 7

You need to create a PowerShell script inside of project folder, for this example is "PostBuild.ps1". This script will be called in PostbuildEvents property.

For MsBuild properties
https://learn.microsoft.com/es-es/visualstudio/ide/how-to-specify-build-events-csharp?view=vs-2022

Download Powershell
https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.3


First Solution Reading the Project'XML and retrieving the properties.

Your project files

project

Your project XML

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <Company>Acme</Company>
        <Product>NextBigThing</Product>
    </PropertyGroup>

    <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="pwsh -NoLogo -ExecutionPolicy Bypass -Command &quot;./PostBuild.ps1 -ProjectFileName $(ProjectFileName)&quot;" />
    </Target>

</Project>

project xml

Your project properties - Visual studio

The command to call "PostBuild.ps1" is

pwsh -NoLogo -ExecutionPolicy Bypass -Command "./PostBuild.ps1 -ProjectFileName $(ProjectFileName)"

properties

PostBuild.ps1 - Code

[CmdletBinding()]
param (
    [Parameter()]
    [string]
    $ProjectFileName
)

Write-Host "█ ProjectFileName from parameters: $ProjectFileName"

$basePath = "//Project/PropertyGroup"
$companyLabel = "Company"
$productLabel = "Product"

if (!(Test-Path $ProjectFileName -PathType Leaf) -or (!"$ProjectFileName".EndsWith(".csproj"))) {
    throw "Invalid file `"$ProjectFileName`"."
}

[System.Xml.XmlDocument] $doc = [System.Xml.XmlDocument]::new()
$doc.PreserveWhitespace = $true
$doc.Load($ProjectFilename)
$company = $doc.DocumentElement.SelectSingleNode("$basePath/$companyLabel").InnerText
$product = $doc.DocumentElement.SelectSingleNode("$basePath/$productLabel").InnerText

Write-Host "█ command: xcopy ""$PSScriptRoot"" ""%AppData%\$company\$product\"""

Output

1>------ Rebuild All started: Project: VariablesInPostBuildEvents, Configuration: Debug Any CPU ------
Restored C:\Users\Megam\Desktop\so an\VariablesInPostBuildEvents\VariablesInPostBuildEvents.csproj (in 3 ms).
1>VariablesInPostBuildEvents -> C:\Users\Megam\Desktop\so an\VariablesInPostBuildEvents\bin\Debug\net7.0\VariablesInPostBuildEvents.dll
1>█ ProjectFileName from parameters: VariablesInPostBuildEvents.csproj
1>█ command: xcopy "C:\Users\Megam\Desktop\so an\VariablesInPostBuildEvents" "%AppData%\Acme\NextBigThing\"
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
========== Elapsed 00:01.628 ==========

out


Second Solution Company and Product are MSBuild known properties. It can be included in command.

Same file structure

Command in PostBuildEvents

pwsh -NoLogo -ExecutionPolicy Bypass -Command "./PostBuild.ps1 -Company $(Company) -Product $(Product)"

PostBuild.ps1

[CmdletBinding()]
param (
    [Parameter()]
    [string]
    $Company,

    [Parameter()]
    [string]
    $Product
)

Write-Host "█ Company: $Company"
Write-Host "█ Company: $Product"
Write-Host "█ command: xcopy ""$PSScriptRoot"" ""%AppData%\$company\$product\"""

Output

Rebuild started...
1>------ Rebuild All started: Project: VariablesInPostBuildEvents, Configuration: Debug Any CPU ------
Restored C:\Users\Megam\Desktop\so an\VariablesInPostBuildEvents\VariablesInPostBuildEvents.csproj (in 2 ms).
1>VariablesInPostBuildEvents -> C:\Users\Megam\Desktop\so an\VariablesInPostBuildEvents\bin\Debug\net7.0\VariablesInPostBuildEvents.dll
1>█ Company: Acme
1>█ Company: NextBigThing
1>█ command: xcopy "C:\Users\Megam\Desktop\so an\VariablesInPostBuildEvents" "%AppData%\Acme\NextBigThing\"
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
========== Elapsed 00:02.728 ==========

output

Sign up to request clarification or add additional context in comments.

1 Comment

It's a good answer but the solution got problematic when passing variables that may contains spaces or escape characters. For example to pass the solution directory as a parameter I had to single quote it like the following: -Command "./PostBuild.ps1 -SolutionDir '$(SolutionDir)'"
0

Just use $(<VariableName>) like

  <Exec Command="xcopy ... \$(Company)\$(Product)\ ..." />

based on https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-properties?view=vs-2022

Comments

0

Here is the solution:

<PropertyGroup>
    <Company>Acme</Company>
    <Product>NextBigThing</Product>
</PropertyGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="xcopy.exe SOME_FILE_PATH %AppData%\$(Company)\$(Product)\ /Y" />
</Target>

You need to add \ after $(Product) so Windows know that is a folder and /Y to override already existing files.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.