Difference between revisions of "Windows PowerShell"

From HalfgeekKB
Jump to navigation Jump to search
 
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
==PowerShell prebuild and postbuild script for Visual Studio projects==
 +
 +
Tested with VS2015.
 +
 +
===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>
 +
 
==PSModulePath==
 
==PSModulePath==
  

Latest revision as of 13:09, 11 February 2016

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.

(end)