Windows PowerShell
Jump to navigation
Jump to search
Contents
PowerShell prebuild and postbuild script for Visual Studio projects
Tested with VS2015.
How
- Add a new file
buildevents.ps1
at the top level of the project. - Copy the text below into the new file and save.
- In the project properties, change the Pre-build and Post-build commands to the commands suggested at the comments at the top of the file.
- Modify the script in the "TODO"-marked areas to add pre-build commands, post-build commands, and commands common to all runs.
buildevents.ps1
# For Prebuild command, use:
# powershell -ExecutionPolicy ByPass "&'$(ProjectDir)buildevents.ps1'" -Function Prebuild -ConfigurationName '$(ConfigurationName)' -OutDir '$(OutDir)' -DevEnvDir '$(DevEnvDir)' -PlatformName '$(PlatformName)' -ProjectDir '$(ProjectDir)' -ProjectPath '$(ProjectPath)' -ProjectName '$(ProjectName)' -ProjectFileName '$(ProjectFileName)' -ProjectExt '$(ProjectExt)' -SolutionDir '$(SolutionDir)' -SolutionPath '$(SolutionPath)' -SolutionName '$(SolutionName)' -SolutionFileName '$(SolutionFileName)' -SolutionExt '$(SolutionExt)' -TargetDir '$(TargetDir)' -TargetPath '$(TargetPath)' -TargetName '$(TargetName)' -TargetFileName '$(TargetFileName)' -TargetExt '$(TargetExt)'
# For Postbuild command, use:
# powershell -ExecutionPolicy ByPass "&'$(ProjectDir)buildevents.ps1'" -Function Postbuild -ConfigurationName '$(ConfigurationName)' -OutDir '$(OutDir)' -DevEnvDir '$(DevEnvDir)' -PlatformName '$(PlatformName)' -ProjectDir '$(ProjectDir)' -ProjectPath '$(ProjectPath)' -ProjectName '$(ProjectName)' -ProjectFileName '$(ProjectFileName)' -ProjectExt '$(ProjectExt)' -SolutionDir '$(SolutionDir)' -SolutionPath '$(SolutionPath)' -SolutionName '$(SolutionName)' -SolutionFileName '$(SolutionFileName)' -SolutionExt '$(SolutionExt)' -TargetDir '$(TargetDir)' -TargetPath '$(TargetPath)' -TargetName '$(TargetName)' -TargetFileName '$(TargetFileName)' -TargetExt '$(TargetExt)'
param (
[string]$ConfigurationName, # The name of the current project configuration, for example, "Debug".
[string]$OutDir, # Path to the output file directory, relative to the project directory. This resolves to the value for the Output Directory property. It includes the trailing backslash '\'.
[string]$DevEnvDir, # The installation directory of Visual Studio (defined with drive and path); includes the trailing backslash '\'.
[string]$PlatformName, # The name of the currently targeted platform. For example, "AnyCPU".
[string]$ProjectDir, # The directory of the project (defined with drive and path); includes the trailing backslash '\'.
[string]$ProjectPath, # The absolute path name of the project (defined with drive, path, base name, and file extension).
[string]$ProjectName, # The base name of the project.
[string]$ProjectFileName, # The file name of the project (defined with base name and file extension).
[string]$ProjectExt, # The file extension of the project. It includes the '.' before the file extension.
[string]$SolutionDir, # The directory of the solution (defined with drive and path); includes the trailing backslash '\'.
[string]$SolutionPath, # The absolute path name of the solution (defined with drive, path, base name, and file extension).
[string]$SolutionName, # The base name of the solution.
[string]$SolutionFileName, # The file name of the solution (defined with base name and file extension).
[string]$SolutionExt, # The file extension of the solution. It includes the '.' before the file extension.
[string]$TargetDir, # The directory of the primary output file for the build (defined with drive and path). It includes the trailing backslash '\'.
[string]$TargetPath, # The absolute path name of the primary output file for the build (defined with drive, path, base name, and file extension).
[string]$TargetName, # The base name of the primary output file for the build.
[string]$TargetFileName, # The file name of the primary output file for the build (defined as base name and file extension).
[string]$TargetExt, # The file extension of the primary output file for the build. It includes the '.' before the file extension.
[string]$Function # Name of the function to run
)
# TODO Add common code here
function Prebuild ()
{
# TODO Add code here
}
function Postbuild ()
{
# TODO Add code here
}
# ------------------------------
# AVOID EDITING BELOW THIS POINT
# ------------------------------
function Run-BuildEventFunction($buildEventFunctionName)
{
echo "--- Build event '$buildEventFunctionName' started ---"
Try
{
& $buildEventFunctionName
echo "--- Build event '$buildEventFunctionName' completed normally ---"
}
Catch
{
echo "--- Build event '$buildEventFunctionName' failed with exception ---"
throw
}
}
# Call the event indicated by $Function
Run-BuildEventFunction $Function
Advanced: The script to generate buildevents.ps1
$scriptNameInProjectDir = "buildevents.ps1"
# This table is from https://msdn.microsoft.com/en-us/library/42x5kfw4%28v=vs.140%29.aspx
# Copy table and paste into Excel, then copy from Excel into text editor.
# (Copying straight from browser into the text editor doesn't give the tab-separated values needed here.)
$macroList = @'
$(ConfigurationName) The name of the current project configuration, for example, "Debug".
$(OutDir) Path to the output file directory, relative to the project directory. This resolves to the value for the Output Directory property. It includes the trailing backslash '\'.
$(DevEnvDir) The installation directory of Visual Studio (defined with drive and path); includes the trailing backslash '\'.
$(PlatformName) The name of the currently targeted platform. For example, "AnyCPU".
$(ProjectDir) The directory of the project (defined with drive and path); includes the trailing backslash '\'.
$(ProjectPath) The absolute path name of the project (defined with drive, path, base name, and file extension).
$(ProjectName) The base name of the project.
$(ProjectFileName) The file name of the project (defined with base name and file extension).
$(ProjectExt) The file extension of the project. It includes the '.' before the file extension.
$(SolutionDir) The directory of the solution (defined with drive and path); includes the trailing backslash '\'.
$(SolutionPath) The absolute path name of the solution (defined with drive, path, base name, and file extension).
$(SolutionName) The base name of the solution.
$(SolutionFileName) The file name of the solution (defined with base name and file extension).
$(SolutionExt) The file extension of the solution. It includes the '.' before the file extension.
$(TargetDir) The directory of the primary output file for the build (defined with drive and path). It includes the trailing backslash '\'.
$(TargetPath) The absolute path name of the primary output file for the build (defined with drive, path, base name, and file extension).
$(TargetName) The base name of the primary output file for the build.
$(TargetFileName) The file name of the primary output file for the build (defined as base name and file extension).
$(TargetExt) The file extension of the primary output file for the build. It includes the '.' before the file extension.
'@
function Get-BuildEventCommand ($buildEventFunctionName, $macroData)
{
$commandStart = "powershell -ExecutionPolicy ByPass `"`&'`$(ProjectDir)$scriptNameInProjectDir'`""
$macroNames = $macroData | foreach-object { $_.Name }
$macrosAsArgs = $macroNames | foreach-object { "-$_ '`$($_)'" }
#$commandMacroArgs = [string]::Join(" ", $macrosAsArgs)
echo "$commandStart -Function $buildEventFunctionName $macrosAsArgs"
}
function Get-BuildEventCommandComment ($buildEventFunctionName, $macroData)
{
echo "# For $buildEventFunctionName command, use:"
echo "# $(Get-BuildEventCommand $buildEventFunctionName $macroData)"
echo ""
}
function Get-ParamList ($macroData)
{
echo "param ("
foreach($macro in $macroData) {
echo " [string]`$$($macro.Name), # $($macro.Description)"
}
echo ""
echo " [string]`$Function # Name of the function to run"
echo ")"
echo ""
}
function Get-FunctionTemplate ($buildEventFunctionName)
{
echo "function $buildEventFunctionName ()"
echo "{"
echo " # TODO Add code here"
echo "}"
echo ""
}
function Parse-MacroLine ($line)
{
$line = "$line"
if ($line -match "^\$\((.+?)\)\t(.*?)$") {
$result = @{
Name = "$($matches[1])"
Description = "$($matches[2])"
}
$result
}
else {
$null
}
}
$macroLines = $([Regex]::Split($macroList,"\r\n|\r|\n")) | where { $_ -ne $null -and $_.Trim() -ne "" }
$macroData = $macroLines | foreach-object { Parse-MacroLine $_ } | where { $_ -ne $null }
$buildEventFunctionNames = "Prebuild", "Postbuild"
foreach($buildEventFunctionName in $buildEventFunctionNames) {
Get-BuildEventCommandComment $buildEventFunctionName $macroData
}
Get-ParamList $macroData
echo "# TODO Add common code here"
echo ""
foreach($buildEventFunctionName in $buildEventFunctionNames) {
Get-FunctionTemplate $buildEventFunctionName
}
echo @'
# ------------------------------
# AVOID EDITING BELOW THIS POINT
# ------------------------------
function Run-BuildEventFunction($buildEventFunctionName)
{
echo "--- Build event '$buildEventFunctionName' started ---"
Try
{
& $buildEventFunctionName
echo "--- Build event '$buildEventFunctionName' completed normally ---"
}
Catch
{
echo "--- Build event '$buildEventFunctionName' failed with exception ---"
throw
}
}
# Call the event indicated by $Function
Run-BuildEventFunction $Function
'@
PSModulePath
PowerShell's search path for the Import-Module command is in the PSModulePath
env var:
echo $env:PSModulePath
By default on one system it seems to be
- a user modules dir at
My Documents\WindowsPowerShell\Modules
- a global modules dir at
system32\WindowsPowerShell\v1.0\Modules\
PowerShell Community Extensions (pscx)
Get it from http://pscx.codeplex.com/. The directory structure in the ZIP file needs to be such that the path to Pscx.psm1
is
Modules/Pscx/Pscx.psm1
where Modules is one of the directories in $env:PSModulePath
.