Difference between revisions of "Windows PowerShell"
Jump to navigation
Jump to search
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
− | ==PowerShell prebuild and postbuild | + | ==PowerShell prebuild and postbuild script for Visual Studio projects== |
Tested with VS2015. | Tested with VS2015. | ||
Line 5: | Line 5: | ||
===How=== | ===How=== | ||
− | * | + | * Add a new file <code>buildevents.ps1</code> 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==== | |
+ | |||
+ | <syntaxhighlight lang=powershell> | ||
+ | # 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 | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ====Advanced: The script to generate buildevents.ps1==== | ||
+ | |||
+ | <syntaxhighlight lang=powershell> | ||
+ | |||
+ | $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 | |
− | + | '@ | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Latest revision as of 13:09, 11 February 2016
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
.