Upgraded the Invoke-MSBuild to version 2.5.1
This commit is contained in:
parent
2be3f5f1d0
commit
c5df8d5875
|
@ -12,7 +12,10 @@
|
||||||
RootModule = 'Invoke-MsBuild.psm1'
|
RootModule = 'Invoke-MsBuild.psm1'
|
||||||
|
|
||||||
# Version number of this module.
|
# Version number of this module.
|
||||||
ModuleVersion = '2.2.0'
|
ModuleVersion = '2.5.1'
|
||||||
|
|
||||||
|
# Supported PSEditions
|
||||||
|
# CompatiblePSEditions = @()
|
||||||
|
|
||||||
# ID used to uniquely identify this module
|
# ID used to uniquely identify this module
|
||||||
GUID = '8ca20938-b92a-42a1-bf65-f644e16a8d9e'
|
GUID = '8ca20938-b92a-42a1-bf65-f644e16a8d9e'
|
||||||
|
@ -38,10 +41,10 @@ PowerShellVersion = '2.0'
|
||||||
# Minimum version of the Windows PowerShell host required by this module
|
# Minimum version of the Windows PowerShell host required by this module
|
||||||
# PowerShellHostVersion = ''
|
# PowerShellHostVersion = ''
|
||||||
|
|
||||||
# Minimum version of Microsoft .NET Framework required by this module
|
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||||
# DotNetFrameworkVersion = ''
|
# DotNetFrameworkVersion = ''
|
||||||
|
|
||||||
# Minimum version of the common language runtime (CLR) required by this module
|
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
|
||||||
# CLRVersion = ''
|
# CLRVersion = ''
|
||||||
|
|
||||||
# Processor architecture (None, X86, Amd64) required by this module
|
# Processor architecture (None, X86, Amd64) required by this module
|
||||||
|
@ -65,17 +68,17 @@ PowerShellVersion = '2.0'
|
||||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||||
# NestedModules = @()
|
# NestedModules = @()
|
||||||
|
|
||||||
# Functions to export from this module
|
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
|
||||||
FunctionsToExport = '*'
|
FunctionsToExport = @('Invoke-MsBuild')
|
||||||
|
|
||||||
# Cmdlets to export from this module
|
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
|
||||||
CmdletsToExport = '*'
|
CmdletsToExport = @()
|
||||||
|
|
||||||
# Variables to export from this module
|
# Variables to export from this module
|
||||||
VariablesToExport = '*'
|
VariablesToExport = @()
|
||||||
|
|
||||||
# Aliases to export from this module
|
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
|
||||||
AliasesToExport = '*'
|
AliasesToExport = @()
|
||||||
|
|
||||||
# DSC resources to export from this module
|
# DSC resources to export from this module
|
||||||
# DscResourcesToExport = @()
|
# DscResourcesToExport = @()
|
||||||
|
@ -104,38 +107,7 @@ PrivateData = @{
|
||||||
# IconUri = ''
|
# IconUri = ''
|
||||||
|
|
||||||
# ReleaseNotes of this module
|
# ReleaseNotes of this module
|
||||||
ReleaseNotes = '- Added LogVerbosityLevel parameter to adjust the verbosity MsBuild uses to write to the log file.
|
ReleaseNotes = '- Fix to find the "Program Files" location correctly on 32 bit windows without throwing an error.'
|
||||||
- Fixed bug that prevented us from finding msbuild.exe on some machines.
|
|
||||||
|
|
||||||
----------
|
|
||||||
Invoke-MsBuild v2 has the following breaking changes from v1:
|
|
||||||
- A hash table with several properties is returned instead of a simple $true/$false/$null value.
|
|
||||||
- The GetLogPath switch is gone and replaced with the WhatIf switch.
|
|
||||||
|
|
||||||
New features in v2 include:
|
|
||||||
- A build log file containing only build errors is created alongside the regular build log file.
|
|
||||||
- The errors build log file can be auto-launched on build failure.
|
|
||||||
- New switch has been added to show the build output in the calling scripts console window (does not work with some 3rd party consoles due to Start-Process cmdlet bug).
|
|
||||||
- A hash table containing the following properties is now returned:
|
|
||||||
|
|
||||||
+ BuildSucceeded = $true if the build passed, $false if the build failed, and $null if we are not sure.
|
|
||||||
+ BuildLogFilePath = The path to the builds log file.
|
|
||||||
+ BuildErrorsLogFilePath = The path to the builds error log file.
|
|
||||||
+ ItemToBuildFilePath = The item that MsBuild is ran against.
|
|
||||||
+ CommandUsedToBuild = The full command that is used to invoke MsBuild. This can be useful for inspecting what parameters are passed to MsBuild.exe.
|
|
||||||
+ Message = A message describing any problems that were encoutered by Invoke-MsBuild. This is typically an empty string unless something went wrong.
|
|
||||||
+ MsBuildProcess = The process that was used to execute MsBuild.exe.
|
|
||||||
|
|
||||||
Changes to make when updating from v1 to v2:
|
|
||||||
- To capture/display the build success result, you must change:
|
|
||||||
Invoke-MsBuild ...
|
|
||||||
to:
|
|
||||||
(Invoke-MsBuild ...).BuildSucceeded
|
|
||||||
|
|
||||||
- To get the path where the log file will be created, you must change:
|
|
||||||
Invoke-MsBuild ... -GetLogPath
|
|
||||||
to:
|
|
||||||
(Invoke-MsBuild ... -WhatIf).BuildLogFilePath'
|
|
||||||
|
|
||||||
} # End of PSData hashtable
|
} # End of PSData hashtable
|
||||||
|
|
||||||
|
|
|
@ -5,185 +5,205 @@ function Invoke-MsBuild
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Builds the given Visual Studio solution or project file using MsBuild.
|
Builds the given Visual Studio solution or project file using MsBuild.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Executes the MsBuild.exe tool against the specified Visual Studio solution or project file.
|
Executes the MsBuild.exe tool against the specified Visual Studio solution or project file.
|
||||||
Returns a hash table with properties for determining if the build succeeded or not, as well as other information (see the OUTPUTS section for list of properties).
|
Returns a hash table with properties for determining if the build succeeded or not, as well as other information (see the OUTPUTS section for list of properties).
|
||||||
If using the PathThru switch, the process running MsBuild is returned instead.
|
If using the PathThru switch, the process running MsBuild is returned instead.
|
||||||
|
|
||||||
.PARAMETER Path
|
.PARAMETER Path
|
||||||
The path of the Visual Studio solution or project to build (e.g. a .sln or .csproj file).
|
The path of the Visual Studio solution or project to build (e.g. a .sln or .csproj file).
|
||||||
|
|
||||||
.PARAMETER MsBuildParameters
|
.PARAMETER MsBuildParameters
|
||||||
Additional parameters to pass to the MsBuild command-line tool. This can be any valid MsBuild command-line parameters except for the path of
|
Additional parameters to pass to the MsBuild command-line tool. This can be any valid MsBuild command-line parameters except for the path of
|
||||||
the solution/project to build.
|
the solution/project to build.
|
||||||
|
|
||||||
See http://msdn.microsoft.com/en-ca/library/vstudio/ms164311.aspx for valid MsBuild command-line parameters.
|
See http://msdn.microsoft.com/en-ca/library/vstudio/ms164311.aspx for valid MsBuild command-line parameters.
|
||||||
|
|
||||||
.PARAMETER Use32BitMsBuild
|
.PARAMETER Use32BitMsBuild
|
||||||
If this switch is provided, the 32-bit version of MsBuild.exe will be used instead of the 64-bit version when both are available.
|
If this switch is provided, the 32-bit version of MsBuild.exe will be used instead of the 64-bit version when both are available.
|
||||||
|
|
||||||
.PARAMETER BuildLogDirectoryPath
|
.PARAMETER BuildLogDirectoryPath
|
||||||
The directory path to write the build log files to.
|
The directory path to write the build log files to.
|
||||||
Defaults to putting the log files in the users temp directory (e.g. C:\Users\[User Name]\AppData\Local\Temp).
|
Defaults to putting the log files in the users temp directory (e.g. C:\Users\[User Name]\AppData\Local\Temp).
|
||||||
Use the keyword "PathDirectory" to put the log files in the same directory as the .sln or project file being built.
|
Use the keyword "PathDirectory" to put the log files in the same directory as the .sln or project file being built.
|
||||||
Two log files are generated: one with the complete build log, and one that contains only errors from the build.
|
Two log files are generated: one with the complete build log, and one that contains only errors from the build.
|
||||||
|
|
||||||
|
.PARAMETER LogVerbosity
|
||||||
|
If set, this will set the verbosity of the build log. Possible values are: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].
|
||||||
|
|
||||||
.PARAMETER AutoLaunchBuildLogOnFailure
|
.PARAMETER AutoLaunchBuildLogOnFailure
|
||||||
If set, this switch will cause the build log to automatically be launched into the default viewer if the build fails.
|
If set, this switch will cause the build log to automatically be launched into the default viewer if the build fails.
|
||||||
This log file contains all of the build output.
|
This log file contains all of the build output.
|
||||||
NOTE: This switch cannot be used with the PassThru switch.
|
NOTE: This switch cannot be used with the PassThru switch.
|
||||||
|
|
||||||
.PARAMETER AutoLaunchBuildErrorsLogOnFailure
|
.PARAMETER AutoLaunchBuildErrorsLogOnFailure
|
||||||
If set, this switch will cause the build errors log to automatically be launched into the default viewer if the build fails.
|
If set, this switch will cause the build errors log to automatically be launched into the default viewer if the build fails.
|
||||||
This log file only contains errors from the build output.
|
This log file only contains errors from the build output.
|
||||||
NOTE: This switch cannot be used with the PassThru switch.
|
NOTE: This switch cannot be used with the PassThru switch.
|
||||||
|
|
||||||
.PARAMETER KeepBuildLogOnSuccessfulBuilds
|
.PARAMETER KeepBuildLogOnSuccessfulBuilds
|
||||||
If set, this switch will cause the MsBuild log file to not be deleted on successful builds; normally it is only kept around on failed builds.
|
If set, this switch will cause the MsBuild log file to not be deleted on successful builds; normally it is only kept around on failed builds.
|
||||||
NOTE: This switch cannot be used with the PassThru switch.
|
NOTE: This switch cannot be used with the PassThru switch.
|
||||||
|
|
||||||
.PARAMETER ShowBuildOutputInNewWindow
|
.PARAMETER ShowBuildOutputInNewWindow
|
||||||
If set, this switch will cause a command prompt window to be shown in order to view the progress of the build.
|
If set, this switch will cause a command prompt window to be shown in order to view the progress of the build.
|
||||||
By default the build output is not shown in any window.
|
By default the build output is not shown in any window.
|
||||||
NOTE: This switch cannot be used with the ShowBuildOutputInCurrentWindow switch.
|
NOTE: This switch cannot be used with the ShowBuildOutputInCurrentWindow switch.
|
||||||
|
|
||||||
.PARAMETER ShowBuildOutputInCurrentWindow
|
.PARAMETER ShowBuildOutputInCurrentWindow
|
||||||
If set, this switch will cause the build process to be started in the existing console window, instead of creating a new one.
|
If set, this switch will cause the build process to be started in the existing console window, instead of creating a new one.
|
||||||
By default the build output is not shown in any window.
|
By default the build output is not shown in any window.
|
||||||
NOTE: This switch will override the ShowBuildOutputInNewWindow switch.
|
NOTE: This switch will override the ShowBuildOutputInNewWindow switch.
|
||||||
NOTE: There is a problem with the -NoNewWindow parameter of the Start-Process cmdlet; this is used for the ShowBuildOutputInCurrentWindow switch.
|
NOTE: There is a problem with the -NoNewWindow parameter of the Start-Process cmdlet; this is used for the ShowBuildOutputInCurrentWindow switch.
|
||||||
The bug is that in some PowerShell consoles, the build output is not directed back to the console calling this function, so nothing is displayed.
|
The bug is that in some PowerShell consoles, the build output is not directed back to the console calling this function, so nothing is displayed.
|
||||||
To avoid the build process from appearing to hang, PromptForInputBeforeClosing only has an effect with ShowBuildOutputInCurrentWindow when running
|
To avoid the build process from appearing to hang, PromptForInputBeforeClosing only has an effect with ShowBuildOutputInCurrentWindow when running
|
||||||
in the default "ConsoleHost" PowerShell console window, as we know it works properly with that console (it does not in other consoles like ISE, PowerGUI, etc.).
|
in the default "ConsoleHost" PowerShell console window, as we know it works properly with that console (it does not in other consoles like ISE, PowerGUI, etc.).
|
||||||
|
|
||||||
.PARAMETER PromptForInputBeforeClosing
|
.PARAMETER PromptForInputBeforeClosing
|
||||||
If set, this switch will prompt the user for input after the build completes, and will not continue until the user presses a key.
|
If set, this switch will prompt the user for input after the build completes, and will not continue until the user presses a key.
|
||||||
NOTE: This switch only has an effect when used with the ShowBuildOutputInNewWindow and ShowBuildOutputInCurrentWindow switches (otherwise build output is not displayed).
|
NOTE: This switch only has an effect when used with the ShowBuildOutputInNewWindow and ShowBuildOutputInCurrentWindow switches (otherwise build output is not displayed).
|
||||||
NOTE: This switch cannot be used with the PassThru switch.
|
NOTE: This switch cannot be used with the PassThru switch.
|
||||||
NOTE: The user will need to provide input before execution will return back to the calling script (so do not use this switch for automated builds).
|
NOTE: The user will need to provide input before execution will return back to the calling script (so do not use this switch for automated builds).
|
||||||
NOTE: To avoid the build process from appearing to hang, PromptForInputBeforeClosing only has an effect with ShowBuildOutputInCurrentWindow when running
|
NOTE: To avoid the build process from appearing to hang, PromptForInputBeforeClosing only has an effect with ShowBuildOutputInCurrentWindow when running
|
||||||
in the default "ConsoleHost" PowerShell console window, as we know it works properly with that console (it does not in other consoles like ISE, PowerGUI, etc.).
|
in the default "ConsoleHost" PowerShell console window, as we know it works properly with that console (it does not in other consoles like ISE, PowerGUI, etc.).
|
||||||
|
|
||||||
|
.PARAMETER MsBuildFilePath
|
||||||
|
By default this script will locate and use the latest version of MsBuild.exe on the machine.
|
||||||
|
If you have MsBuild.exe in a non-standard location, or want to force the use of an older MsBuild.exe version, you may pass in the file path of the MsBuild.exe to use.
|
||||||
|
|
||||||
|
.PARAMETER VisualStudioDeveloperCommandPromptFilePath
|
||||||
|
By default this script will locate and use the latest version of the Visual Studio Developer Command Prompt to run MsBuild.
|
||||||
|
If you installed Visual Studio in a non-standard location, or want to force the use of an older Visual Studio Command Prompt version, you may pass in the file path to
|
||||||
|
the Visual Studio Command Prompt to use. The filename is typically VsDevCmd.bat.
|
||||||
|
|
||||||
.PARAMETER PassThru
|
.PARAMETER PassThru
|
||||||
If set, this switch will cause the calling script not to wait until the build (launched in another process) completes before continuing execution.
|
If set, this switch will cause the calling script not to wait until the build (launched in another process) completes before continuing execution.
|
||||||
Instead the build will be started in a new process and that process will immediately be returned, allowing the calling script to continue
|
Instead the build will be started in a new process and that process will immediately be returned, allowing the calling script to continue
|
||||||
execution while the build is performed, and also to inspect the process to see when it completes.
|
execution while the build is performed, and also to inspect the process to see when it completes.
|
||||||
NOTE: This switch cannot be used with the AutoLaunchBuildLogOnFailure, AutoLaunchBuildErrorsLogOnFailure, KeepBuildLogOnSuccessfulBuilds, or PromptForInputBeforeClosing switches.
|
NOTE: This switch cannot be used with the AutoLaunchBuildLogOnFailure, AutoLaunchBuildErrorsLogOnFailure, KeepBuildLogOnSuccessfulBuilds, or PromptForInputBeforeClosing switches.
|
||||||
|
|
||||||
.PARAMETER LogVerbosity
|
|
||||||
If set, this will set the verbosity of the build log. Possible values are: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic].
|
|
||||||
|
|
||||||
.PARAMETER WhatIf
|
.PARAMETER WhatIf
|
||||||
If set, the build will not actually be performed.
|
If set, the build will not actually be performed.
|
||||||
Instead it will just return the result object containing the file paths that would be created if the build is performed with the same parameters.
|
Instead it will just return the result hash table containing the file paths that would be created if the build is performed with the same parameters.
|
||||||
|
|
||||||
.OUTPUTS
|
.OUTPUTS
|
||||||
|
|
||||||
When the -PassThru switch is provided, the process being used to run MsBuild.exe is returned.
|
When the -PassThru switch is provided, the process being used to run MsBuild.exe is returned.
|
||||||
When the -PassThru switch is not provided, a hash table with the following properties is returned:
|
When the -PassThru switch is not provided, a hash table with the following properties is returned:
|
||||||
|
|
||||||
BuildSucceeded = $true if the build passed, $false if the build failed, and $null if we are not sure.
|
BuildSucceeded = $true if the build passed, $false if the build failed, and $null if we are not sure.
|
||||||
BuildLogFilePath = The path to the build's log file.
|
BuildLogFilePath = The path to the build's log file.
|
||||||
BuildErrorsLogFilePath = The path to the build's error log file.
|
BuildErrorsLogFilePath = The path to the build's error log file.
|
||||||
ItemToBuildFilePath = The item that MsBuild is ran against.
|
ItemToBuildFilePath = The item that MsBuild ran against.
|
||||||
CommandUsedToBuild = The full command that is used to invoke MsBuild. This can be useful for inspecting what parameters are passed to MsBuild.exe.
|
CommandUsedToBuild = The full command that was used to invoke MsBuild. This can be useful for inspecting what parameters are passed to MsBuild.exe.
|
||||||
Message = A message describing any problems that were encoutered by Invoke-MsBuild. This is typically an empty string unless something went wrong.
|
Message = A message describing any problems that were encoutered by Invoke-MsBuild. This is typically an empty string unless something went wrong.
|
||||||
MsBuildProcess = The process that was used to execute MsBuild.exe.
|
MsBuildProcess = The process that was used to execute MsBuild.exe.
|
||||||
|
BuildDuration = The amount of time the build took to complete, represented as a TimeSpan.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
$buildResult = Invoke-MsBuild -Path "C:\Some Folder\MySolution.sln"
|
$buildResult = Invoke-MsBuild -Path "C:\Some Folder\MySolution.sln"
|
||||||
|
|
||||||
if ($buildResult.BuildSucceeded -eq $true)
|
if ($buildResult.BuildSucceeded -eq $true)
|
||||||
{ Write-Host "Build completed successfully." }
|
{
|
||||||
else if (!$buildResult.BuildSucceeded -eq $false)
|
Write-Output ("Build completed successfully in {0:N1} seconds." -f $buildResult.BuildDuration.TotalSeconds)
|
||||||
{ Write-Host "Build failed. Check the build log file $($buildResult.BuildLogFilePath) for errors." }
|
}
|
||||||
else if ($buildResult.BuildSucceeded -eq $null)
|
elseif ($buildResult.BuildSucceeded -eq $false)
|
||||||
{ Write-Host "Unsure if build passed or failed: $($buildResult.Message)" }
|
{
|
||||||
|
Write-Output ("Build failed after {0:N1} seconds. Check the build log file '$($buildResult.BuildLogFilePath)' for errors." -f $buildResult.BuildDuration.TotalSeconds)
|
||||||
|
}
|
||||||
|
elseif ($buildResult.BuildSucceeded -eq $null)
|
||||||
|
{
|
||||||
|
Write-Output "Unsure if build passed or failed: $($buildResult.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
Perform the default MsBuild actions on the Visual Studio solution to build the projects in it, and returns a hash table containing the results.
|
Perform the default MsBuild actions on the Visual Studio solution to build the projects in it, and returns a hash table containing the results.
|
||||||
The PowerShell script will halt execution until MsBuild completes.
|
The PowerShell script will halt execution until MsBuild completes.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
$process = Invoke-MsBuild -Path "C:\Some Folder\MySolution.sln" -PassThru
|
$process = Invoke-MsBuild -Path "C:\Some Folder\MySolution.sln" -PassThru
|
||||||
|
|
||||||
while (!$process.HasExited)
|
while (!$process.HasExited)
|
||||||
{
|
{
|
||||||
Write-Host "Solution is still buildling..."
|
Write-Host "Solution is still buildling..."
|
||||||
Start-Sleep -Seconds 1
|
Start-Sleep -Seconds 1
|
||||||
}
|
}
|
||||||
|
|
||||||
Perform the default MsBuild actions on the Visual Studio solution to build the projects in it.
|
Perform the default MsBuild actions on the Visual Studio solution to build the projects in it.
|
||||||
The PowerShell script will not halt execution; instead it will return the process running MsBuild.exe back to the caller while the build is performed.
|
The PowerShell script will not halt execution; instead it will return the process running MsBuild.exe back to the caller while the build is performed.
|
||||||
You can check the process's HasExited property to check if the build has completed yet or not.
|
You can check the process's HasExited property to check if the build has completed yet or not.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
if ((Invoke-MsBuild -Path $pathToSolution).BuildSucceeded -eq $true)
|
if ((Invoke-MsBuild -Path $pathToSolution).BuildSucceeded -eq $true)
|
||||||
{
|
{
|
||||||
Write-Host "Build completed successfully."
|
Write-Output "Build completed successfully."
|
||||||
}
|
}
|
||||||
|
|
||||||
Perfom the build against the file specified at $pathToSolution and checks it for success in a single line.
|
Perfom the build against the file specified at $pathToSolution and checks it for success in a single line.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -MsBuildParameters "/target:Clean;Build" -ShowBuildOutputInNewWindow
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -MsBuildParameters "/target:Clean;Build" -ShowBuildOutputInNewWindow
|
||||||
|
|
||||||
Cleans then Builds the given C# project.
|
Cleans then Builds the given C# project.
|
||||||
A window displaying the output from MsBuild will be shown so the user can view the progress of the build.
|
A window displaying the output from MsBuild will be shown so the user can view the progress of the build without it polluting their current terminal window.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -ShowBuildOutputInCurrentWindow
|
||||||
|
|
||||||
|
Builds the given C# project and displays the output from MsBuild in the current terminal window.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\MySolution.sln" -Params "/target:Clean;Build /property:Configuration=Release;Platform=x64;BuildInParallel=true /verbosity:Detailed /maxcpucount"
|
Invoke-MsBuild -Path "C:\MySolution.sln" -Params "/target:Clean;Build /property:Configuration=Release;Platform=x64;BuildInParallel=true /verbosity:Detailed /maxcpucount"
|
||||||
|
|
||||||
Cleans then Builds the given solution, specifying to build the project in parallel in the Release configuration for the x64 platform.
|
Cleans then Builds the given solution, specifying to build the project in parallel in the Release configuration for the x64 platform.
|
||||||
Here the shorter "Params" alias is used instead of the full "MsBuildParameters" parameter name.
|
Here the shorter "Params" alias is used instead of the full "MsBuildParameters" parameter name.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -ShowBuildOutputInNewWindow -PromptForInputBeforeClosing -AutoLaunchBuildLogOnFailure
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -ShowBuildOutputInNewWindow -PromptForInputBeforeClosing -AutoLaunchBuildLogOnFailure
|
||||||
|
|
||||||
Builds the given C# project.
|
Builds the given C# project.
|
||||||
A window displaying the output from MsBuild will be shown so the user can view the progress of the build, and it will not close until the user
|
A window displaying the output from MsBuild will be shown so the user can view the progress of the build, and it will not close until the user
|
||||||
gives the window some input after the build completes. This function will also not return until the user gives the window some input, halting the powershell script execution.
|
gives the window some input after the build completes. This function will also not return until the user gives the window some input, halting the powershell script execution.
|
||||||
If the build fails, the build log will automatically be opened in the default text viewer.
|
If the build fails, the build log will automatically be opened in the default text viewer.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -BuildLogDirectoryPath "C:\BuildLogs" -KeepBuildLogOnSuccessfulBuilds -AutoLaunchBuildErrorsLogOnFailure
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -BuildLogDirectoryPath "C:\BuildLogs" -KeepBuildLogOnSuccessfulBuilds -AutoLaunchBuildErrorsLogOnFailure
|
||||||
|
|
||||||
Builds the given C# project.
|
Builds the given C# project.
|
||||||
The build log will be saved in "C:\BuildLogs", and they will not be automatically deleted even if the build succeeds.
|
The build log will be saved in "C:\BuildLogs", and they will not be automatically deleted even if the build succeeds.
|
||||||
If the build fails, the build errors log will automatically be opened in the default text viewer.
|
If the build fails, the build errors log will automatically be opened in the default text viewer.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -BuildLogDirectoryPath PathDirectory
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -BuildLogDirectoryPath PathDirectory
|
||||||
|
|
||||||
Builds the given C# project.
|
Builds the given C# project.
|
||||||
The keyword 'PathDirectory' is used, so the build log will be saved in "C:\Some Folder\", which is the same directory as the project being built (i.e. directory specified in the Path).
|
The keyword 'PathDirectory' is used, so the build log will be saved in "C:\Some Folder\", which is the same directory as the project being built (i.e. directory specified in the Path).
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Database\Database.dbproj" -P "/t:Deploy /p:TargetDatabase=MyDatabase /p:TargetConnectionString=`"Data Source=DatabaseServerName`;Integrated Security=True`;Pooling=False`" /p:DeployToDatabase=True"
|
Invoke-MsBuild -Path "C:\Database\Database.dbproj" -P "/t:Deploy /p:TargetDatabase=MyDatabase /p:TargetConnectionString=`"Data Source=DatabaseServerName`;Integrated Security=True`;Pooling=False`" /p:DeployToDatabase=True"
|
||||||
|
|
||||||
Deploy the Visual Studio Database Project to the database "MyDatabase".
|
Deploy the Visual Studio Database Project to the database "MyDatabase".
|
||||||
Here the shorter "P" alias is used instead of the full "MsBuildParameters" parameter name.
|
Here the shorter "P" alias is used instead of the full "MsBuildParameters" parameter name.
|
||||||
The shorter alias' of the MsBuild parameters are also used; "/t" instead of "/target", and "/p" instead of "/property".
|
The shorter alias' of the MsBuild parameters are also used; "/t" instead of "/target", and "/p" instead of "/property".
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -WhatIf
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" -WhatIf
|
||||||
|
|
||||||
Returns the result object containing the same property values that would be created if the build was ran with the same parameters.
|
Returns the result hash table containing the same property values that would be created if the build was ran with the same parameters.
|
||||||
The BuildSucceeded property will be $null since no build will actually be invoked.
|
The BuildSucceeded property will be $null since no build will actually be invoked.
|
||||||
This will display all of the returned object's properties and their values.
|
This will display all of the returned hash table's properties and their values.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" > $null
|
Invoke-MsBuild -Path "C:\Some Folder\MyProject.csproj" > $null
|
||||||
|
|
||||||
Builds the given C# project, discarding the result object and not displaying its properties.
|
Builds the given C# project, discarding the result hash table and not displaying its properties.
|
||||||
|
|
||||||
.LINK
|
.LINK
|
||||||
Project home: https://github.com/deadlydog/Invoke-MsBuild
|
Project home: https://github.com/deadlydog/Invoke-MsBuild
|
||||||
|
|
||||||
.NOTES
|
.NOTES
|
||||||
Name: Invoke-MsBuild
|
Name: Invoke-MsBuild
|
||||||
Author: Daniel Schroeder (originally based on the module at http://geekswithblogs.net/dwdii/archive/2011/05/27/part-2-automating-a-visual-studio-build-with-powershell.aspx)
|
Author: Daniel Schroeder (originally based on the module at http://geekswithblogs.net/dwdii/archive/2011/05/27/part-2-automating-a-visual-studio-build-with-powershell.aspx)
|
||||||
Version: 2.2.0
|
Version: 2.5.1
|
||||||
#>
|
#>
|
||||||
[CmdletBinding(DefaultParameterSetName="Wait")]
|
[CmdletBinding(DefaultParameterSetName="Wait")]
|
||||||
param
|
param
|
||||||
|
@ -204,9 +224,9 @@ function Invoke-MsBuild
|
||||||
[Alias("LogDirectory","L")]
|
[Alias("LogDirectory","L")]
|
||||||
[string] $BuildLogDirectoryPath = $env:Temp,
|
[string] $BuildLogDirectoryPath = $env:Temp,
|
||||||
|
|
||||||
[parameter(Mandatory=$false)]
|
[parameter(Mandatory=$false)]
|
||||||
[ValidateSet('q','quiet','m','minimal','n','normal','d','detailed','diag','diagnostic')]
|
[ValidateSet('q','quiet','m','minimal','n','normal','d','detailed','diag','diagnostic')]
|
||||||
[string] $LogVerbosityLevel = 'normal',
|
[string] $LogVerbosityLevel = 'normal',
|
||||||
|
|
||||||
[parameter(Mandatory=$false,ParameterSetName="Wait")]
|
[parameter(Mandatory=$false,ParameterSetName="Wait")]
|
||||||
[ValidateNotNullOrEmpty()]
|
[ValidateNotNullOrEmpty()]
|
||||||
|
@ -230,6 +250,14 @@ function Invoke-MsBuild
|
||||||
[parameter(Mandatory=$false,ParameterSetName="Wait")]
|
[parameter(Mandatory=$false,ParameterSetName="Wait")]
|
||||||
[switch] $PromptForInputBeforeClosing,
|
[switch] $PromptForInputBeforeClosing,
|
||||||
|
|
||||||
|
[parameter(Mandatory=$false)]
|
||||||
|
[ValidateScript({Test-Path $_})]
|
||||||
|
[string] $MsBuildFilePath,
|
||||||
|
|
||||||
|
[parameter(Mandatory=$false)]
|
||||||
|
[ValidateScript({Test-Path $_})]
|
||||||
|
[string] $VisualStudioDeveloperCommandPromptFilePath,
|
||||||
|
|
||||||
[parameter(Mandatory=$false,ParameterSetName="PassThru")]
|
[parameter(Mandatory=$false,ParameterSetName="PassThru")]
|
||||||
[switch] $PassThru,
|
[switch] $PassThru,
|
||||||
|
|
||||||
|
@ -245,33 +273,33 @@ function Invoke-MsBuild
|
||||||
# This must come after a script's/function's param section.
|
# This must come after a script's/function's param section.
|
||||||
# Forces a function to be the first non-comment code to appear in a PowerShell Script/Module.
|
# Forces a function to be the first non-comment code to appear in a PowerShell Script/Module.
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
|
|
||||||
# Ignore cultural differences. This is so that when reading version numbers it does not change the '.' to ',' when the OS's language/culture is not English.
|
|
||||||
[CultureInfo]::CurrentCulture = [CultureInfo]::InvariantCulture
|
|
||||||
|
|
||||||
# Default the ParameterSet variables that may not have been set depending on which parameter set is being used. This is required for PowerShell v2.0 compatibility.
|
# Ignore cultural differences. This is so that when reading version numbers it does not change the '.' to ',' when the OS's language/culture is not English.
|
||||||
if (!(Test-Path Variable:Private:AutoLaunchBuildLogOnFailure)) { $AutoLaunchBuildLogOnFailure = $false }
|
[System.Threading.Thread]::CurrentThread.CurrentCulture = [CultureInfo]::InvariantCulture
|
||||||
|
|
||||||
|
# Default the ParameterSet variables that may not have been set depending on which parameter set is being used. This is required for PowerShell v2.0 compatibility.
|
||||||
|
if (!(Test-Path Variable:Private:AutoLaunchBuildLogOnFailure)) { $AutoLaunchBuildLogOnFailure = $false }
|
||||||
if (!(Test-Path Variable:Private:AutoLaunchBuildLogOnFailure)) { $AutoLaunchBuildErrorsLogOnFailure = $false }
|
if (!(Test-Path Variable:Private:AutoLaunchBuildLogOnFailure)) { $AutoLaunchBuildErrorsLogOnFailure = $false }
|
||||||
if (!(Test-Path Variable:Private:KeepBuildLogOnSuccessfulBuilds)) { $KeepBuildLogOnSuccessfulBuilds = $false }
|
if (!(Test-Path Variable:Private:KeepBuildLogOnSuccessfulBuilds)) { $KeepBuildLogOnSuccessfulBuilds = $false }
|
||||||
if (!(Test-Path Variable:Private:PromptForInputBeforeClosing)) { $PromptForInputBeforeClosing = $false }
|
if (!(Test-Path Variable:Private:PromptForInputBeforeClosing)) { $PromptForInputBeforeClosing = $false }
|
||||||
if (!(Test-Path Variable:Private:PassThru)) { $PassThru = $false }
|
if (!(Test-Path Variable:Private:PassThru)) { $PassThru = $false }
|
||||||
|
|
||||||
# If the keyword was supplied, place the log in the same folder as the solution/project being built.
|
# If the keyword was supplied, place the log in the same folder as the solution/project being built.
|
||||||
if ($BuildLogDirectoryPath.Equals("PathDirectory", [System.StringComparison]::InvariantCultureIgnoreCase))
|
if ($BuildLogDirectoryPath.Equals("PathDirectory", [System.StringComparison]::InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
$BuildLogDirectoryPath = [System.IO.Path]::GetDirectoryName($Path)
|
$BuildLogDirectoryPath = [System.IO.Path]::GetDirectoryName($Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Always get the full path to the Log files directory.
|
# Always get the full path to the Log files directory.
|
||||||
$BuildLogDirectoryPath = [System.IO.Path]::GetFullPath($BuildLogDirectoryPath)
|
$BuildLogDirectoryPath = [System.IO.Path]::GetFullPath($BuildLogDirectoryPath)
|
||||||
|
|
||||||
# Local Variables.
|
# Local Variables.
|
||||||
$solutionFileName = (Get-ItemProperty -Path $Path).Name
|
$solutionFileName = (Get-ItemProperty -Path $Path).Name
|
||||||
$buildLogFilePath = (Join-Path -Path $BuildLogDirectoryPath -ChildPath $solutionFileName) + ".msbuild.log"
|
$buildLogFilePath = (Join-Path -Path $BuildLogDirectoryPath -ChildPath $solutionFileName) + ".msbuild.log"
|
||||||
$buildErrorsLogFilePath = (Join-Path -Path $BuildLogDirectoryPath -ChildPath $solutionFileName) + ".msbulid.errors.log"
|
$buildErrorsLogFilePath = (Join-Path -Path $BuildLogDirectoryPath -ChildPath $solutionFileName) + ".msbulid.errors.log"
|
||||||
$windowStyleOfNewWindow = if ($ShowBuildOutputInNewWindow) { "Normal" } else { "Hidden" }
|
$windowStyleOfNewWindow = if ($ShowBuildOutputInNewWindow) { "Normal" } else { "Hidden" }
|
||||||
|
|
||||||
# Build our object that will be returned.
|
# Build our hash table that will be returned.
|
||||||
$result = @{}
|
$result = @{}
|
||||||
$result.BuildSucceeded = $null
|
$result.BuildSucceeded = $null
|
||||||
$result.BuildLogFilePath = $buildLogFilePath
|
$result.BuildLogFilePath = $buildLogFilePath
|
||||||
|
@ -280,20 +308,21 @@ function Invoke-MsBuild
|
||||||
$result.CommandUsedToBuild = [string]::Empty
|
$result.CommandUsedToBuild = [string]::Empty
|
||||||
$result.Message = [string]::Empty
|
$result.Message = [string]::Empty
|
||||||
$result.MsBuildProcess = $null
|
$result.MsBuildProcess = $null
|
||||||
|
$result.BuildDuration = [TimeSpan]::Zero
|
||||||
|
|
||||||
# Try and build the solution.
|
# Try and build the solution.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
# Get the verbosity to use for the MsBuild log file.
|
# Get the verbosity to use for the MsBuild log file.
|
||||||
$verbosityLevel = switch ($LogVerbosityLevel) {
|
$verbosityLevel = switch ($LogVerbosityLevel) {
|
||||||
{ ($_ -eq "q") -or ($_ -eq "quiet") -or `
|
{ ($_ -eq "q") -or ($_ -eq "quiet") -or `
|
||||||
($_ -eq "m") -or ($_ -eq "minimal") -or `
|
($_ -eq "m") -or ($_ -eq "minimal") -or `
|
||||||
($_ -eq "n") -or ($_ -eq "normal") -or `
|
($_ -eq "n") -or ($_ -eq "normal") -or `
|
||||||
($_ -eq "d") -or ($_ -eq "detailed") -or `
|
($_ -eq "d") -or ($_ -eq "detailed") -or `
|
||||||
($_ -eq "diag") -or ($_ -eq "diagnostic") } { ";verbosity=$_" ;break }
|
($_ -eq "diag") -or ($_ -eq "diagnostic") } { ";verbosity=$_" ;break }
|
||||||
default { "" }
|
default { "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build the arguments to pass to MsBuild.
|
# Build the arguments to pass to MsBuild.
|
||||||
$buildArguments = """$Path"" $MsBuildParameters /fileLoggerParameters:LogFile=""$buildLogFilePath""$verbosityLevel /fileLoggerParameters1:LogFile=""$buildErrorsLogFilePath"";errorsonly"
|
$buildArguments = """$Path"" $MsBuildParameters /fileLoggerParameters:LogFile=""$buildLogFilePath""$verbosityLevel /fileLoggerParameters1:LogFile=""$buildErrorsLogFilePath"";errorsonly"
|
||||||
|
|
||||||
|
@ -304,13 +333,26 @@ function Invoke-MsBuild
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the path to the MsBuild executable.
|
# Get the path to the MsBuild executable.
|
||||||
$msBuildPath = Get-MsBuildPath -Use32BitMsBuild:$Use32BitMsBuild
|
$msBuildPath = $MsBuildFilePath
|
||||||
|
[bool] $msBuildPathWasNotProvided = [string]::IsNullOrEmpty($msBuildPath)
|
||||||
|
if ($msBuildPathWasNotProvided)
|
||||||
|
{
|
||||||
|
$msBuildPath = Get-LatestMsBuildPath -Use32BitMsBuild:$Use32BitMsBuild
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the path to the Visual Studio Developer Command Prompt file.
|
||||||
|
$vsCommandPromptPath = $VisualStudioDeveloperCommandPromptFilePath
|
||||||
|
[bool] $vsCommandPromptPathWasNotProvided = [string]::IsNullOrEmpty($vsCommandPromptPath)
|
||||||
|
if ($vsCommandPromptPathWasNotProvided)
|
||||||
|
{
|
||||||
|
$vsCommandPromptPath = Get-LatestVisualStudioCommandPromptPath
|
||||||
|
}
|
||||||
|
|
||||||
# If a VS Command Prompt was found, call MsBuild from that since it sets environmental variables that may be needed to build some projects types (e.g. XNA).
|
# If a VS Command Prompt was found, call MsBuild from that since it sets environmental variables that may be needed to build some projects types (e.g. XNA).
|
||||||
$vsCommandPromptPath = Get-VisualStudioCommandPromptPath
|
[bool] $vsCommandPromptPathWasFound = ![string]::IsNullOrEmpty($vsCommandPromptPath)
|
||||||
if ($vsCommandPromptPath -ne $null)
|
if ($vsCommandPromptPathWasFound)
|
||||||
{
|
{
|
||||||
$cmdArgumentsToRunMsBuild = "/k "" ""$vsCommandPromptPath"" & msbuild "
|
$cmdArgumentsToRunMsBuild = "/k "" ""$vsCommandPromptPath"" & ""$msBuildPath"" "
|
||||||
}
|
}
|
||||||
# Else the VS Command Prompt was not found, so just build using MsBuild directly.
|
# Else the VS Command Prompt was not found, so just build using MsBuild directly.
|
||||||
else
|
else
|
||||||
|
@ -320,10 +362,10 @@ function Invoke-MsBuild
|
||||||
|
|
||||||
# Append the MsBuild arguments to pass into cmd.exe in order to do the build.
|
# Append the MsBuild arguments to pass into cmd.exe in order to do the build.
|
||||||
$cmdArgumentsToRunMsBuild += "$buildArguments "
|
$cmdArgumentsToRunMsBuild += "$buildArguments "
|
||||||
|
|
||||||
# If necessary, add a pause to wait for input before exiting the cmd.exe window.
|
# If necessary, add a pause to wait for input before exiting the cmd.exe window.
|
||||||
# No pausing allowed when using PassThru or not showing the build output.
|
# No pausing allowed when using PassThru or not showing the build output.
|
||||||
# The -NoNewWindow parameter of Start-Process does not behave correctly in the ISE and other PowerShell hosts (doesn't display any build output),
|
# The -NoNewWindow parameter of Start-Process does not behave correctly in the ISE and other PowerShell hosts (doesn't display any build output),
|
||||||
# so only allow it if in the default PowerShell host, since we know that one works.
|
# so only allow it if in the default PowerShell host, since we know that one works.
|
||||||
$pauseForInput = [string]::Empty
|
$pauseForInput = [string]::Empty
|
||||||
if ($PromptForInputBeforeClosing -and !$PassThru `
|
if ($PromptForInputBeforeClosing -and !$PassThru `
|
||||||
|
@ -333,7 +375,7 @@ function Invoke-MsBuild
|
||||||
|
|
||||||
# Record the exact command used to perform the build to make it easier to troubleshoot issues with builds.
|
# Record the exact command used to perform the build to make it easier to troubleshoot issues with builds.
|
||||||
$result.CommandUsedToBuild = "cmd.exe $cmdArgumentsToRunMsBuild"
|
$result.CommandUsedToBuild = "cmd.exe $cmdArgumentsToRunMsBuild"
|
||||||
|
|
||||||
# If we don't actually want to perform a build, return .
|
# If we don't actually want to perform a build, return .
|
||||||
if ($WhatIf)
|
if ($WhatIf)
|
||||||
{
|
{
|
||||||
|
@ -341,9 +383,9 @@ function Invoke-MsBuild
|
||||||
$result.Message = "The '-WhatIf' switch was specified, so a build was not invoked."
|
$result.Message = "The '-WhatIf' switch was specified, so a build was not invoked."
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Debug "Starting new cmd.exe process with arguments ""$cmdArgumentsToRunMsBuild""."
|
Write-Debug "Starting new cmd.exe process with arguments ""$cmdArgumentsToRunMsBuild""."
|
||||||
|
|
||||||
# Perform the build.
|
# Perform the build.
|
||||||
if ($PassThru)
|
if ($PassThru)
|
||||||
{
|
{
|
||||||
|
@ -358,16 +400,20 @@ function Invoke-MsBuild
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($ShowBuildOutputInCurrentWindow)
|
$performBuildScriptBlock =
|
||||||
{
|
{
|
||||||
$result.MsBuildProcess = Start-Process cmd.exe -ArgumentList $cmdArgumentsToRunMsBuild -NoNewWindow -PassThru
|
if ($ShowBuildOutputInCurrentWindow)
|
||||||
}
|
{
|
||||||
else
|
$result.MsBuildProcess = Start-Process cmd.exe -ArgumentList $cmdArgumentsToRunMsBuild -NoNewWindow -Wait -PassThru
|
||||||
{
|
}
|
||||||
$result.MsBuildProcess = Start-Process cmd.exe -ArgumentList $cmdArgumentsToRunMsBuild -WindowStyle $windowStyleOfNewWindow -PassThru
|
else
|
||||||
|
{
|
||||||
|
$result.MsBuildProcess = Start-Process cmd.exe -ArgumentList $cmdArgumentsToRunMsBuild -WindowStyle $windowStyleOfNewWindow -Wait -PassThru
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Wait-Process -InputObject $result.MsBuildProcess
|
# Perform the build and record how long it takes.
|
||||||
|
$result.BuildDuration = (Measure-Command -Expression $performBuildScriptBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# If the build crashed, return that the build didn't succeed.
|
# If the build crashed, return that the build didn't succeed.
|
||||||
|
@ -376,20 +422,20 @@ function Invoke-MsBuild
|
||||||
$errorMessage = $_
|
$errorMessage = $_
|
||||||
$result.Message = "Unexpected error occurred while building ""$Path"": $errorMessage"
|
$result.Message = "Unexpected error occurred while building ""$Path"": $errorMessage"
|
||||||
$result.BuildSucceeded = $false
|
$result.BuildSucceeded = $false
|
||||||
|
|
||||||
Write-Error ($result.Message)
|
Write-Error ($result.Message)
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
# If we can't find the build's log file in order to inspect it, write a warning and return null.
|
# If we can't find the build's log file in order to inspect it, write a warning and return null.
|
||||||
if (!(Test-Path -Path $buildLogFilePath))
|
if (!(Test-Path -Path $buildLogFilePath))
|
||||||
{
|
{
|
||||||
$result.BuildSucceeded = $null
|
$result.BuildSucceeded = $null
|
||||||
$result.Message = "Cannot find the build log file at '$buildLogFilePath', so unable to determine if build succeeded or not."
|
$result.Message = "Cannot find the build log file at '$buildLogFilePath', so unable to determine if build succeeded or not."
|
||||||
|
|
||||||
Write-Warning ($result.Message)
|
Write-Warning ($result.Message)
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get if the build failed or not by looking at the log file.
|
# Get if the build failed or not by looking at the log file.
|
||||||
$buildSucceeded = (((Select-String -Path $buildLogFilePath -Pattern "Build FAILED." -SimpleMatch) -eq $null) -and $result.MsBuildProcess.ExitCode -eq 0)
|
$buildSucceeded = (((Select-String -Path $buildLogFilePath -Pattern "Build FAILED." -SimpleMatch) -eq $null) -and $result.MsBuildProcess.ExitCode -eq 0)
|
||||||
|
@ -398,7 +444,7 @@ function Invoke-MsBuild
|
||||||
if ($buildSucceeded)
|
if ($buildSucceeded)
|
||||||
{
|
{
|
||||||
$result.BuildSucceeded = $true
|
$result.BuildSucceeded = $true
|
||||||
|
|
||||||
# If we shouldn't keep the log files around, delete them.
|
# If we shouldn't keep the log files around, delete them.
|
||||||
if (!$KeepBuildLogOnSuccessfulBuilds)
|
if (!$KeepBuildLogOnSuccessfulBuilds)
|
||||||
{
|
{
|
||||||
|
@ -411,7 +457,7 @@ function Invoke-MsBuild
|
||||||
{
|
{
|
||||||
$result.BuildSucceeded = $false
|
$result.BuildSucceeded = $false
|
||||||
$result.Message = "FAILED to build ""$Path"". Please check the build log ""$buildLogFilePath"" for details."
|
$result.Message = "FAILED to build ""$Path"". Please check the build log ""$buildLogFilePath"" for details."
|
||||||
|
|
||||||
# Write the error message as a warning.
|
# Write the error message as a warning.
|
||||||
Write-Warning ($result.Message)
|
Write-Warning ($result.Message)
|
||||||
|
|
||||||
|
@ -434,68 +480,172 @@ function Invoke-MsBuild
|
||||||
function Open-BuildLogFileWithDefaultProgram([string]$FilePathToOpen, [ref]$Result)
|
function Open-BuildLogFileWithDefaultProgram([string]$FilePathToOpen, [ref]$Result)
|
||||||
{
|
{
|
||||||
if (Test-Path -Path $FilePathToOpen -PathType Leaf)
|
if (Test-Path -Path $FilePathToOpen -PathType Leaf)
|
||||||
{
|
{
|
||||||
Start-Process -verb "Open" $FilePathToOpen
|
Start-Process -verb "Open" $FilePathToOpen
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$message = "Could not auto-launch the build log because the expected file does not exist at '$FilePathToOpen'."
|
$message = "Could not auto-launch the build log because the expected file does not exist at '$FilePathToOpen'."
|
||||||
$Result.Message += [System.Environment]::NewLine + $message
|
$Result.Message += [System.Environment]::NewLine + $message
|
||||||
Write-Warning $message
|
Write-Warning $message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-VisualStudioCommandPromptPath
|
function Get-LatestVisualStudioCommandPromptPath
|
||||||
{
|
{
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Gets the file path to the latest Visual Studio Command Prompt. Returns $null if a path is not found.
|
Gets the file path to the latest Visual Studio Command Prompt. Returns $null if a path is not found.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Gets the file path to the latest Visual Studio Command Prompt. Returns $null if a path is not found.
|
Gets the file path to the latest Visual Studio Command Prompt. Returns $null if a path is not found.
|
||||||
#>
|
#>
|
||||||
|
[string] $vsCommandPromptPath = Get-VisualStudioCommandPromptPathForVisualStudio2017AndNewer
|
||||||
|
|
||||||
# We have to use the vswhere.exe tool to locate Visual Studio 2017
|
# If VS 2017 or newer VS Command Prompt was not found, check for older versions of VS Command Prompt.
|
||||||
$vsWhere = Join-Path $PSScriptRoot '..\..\Tools\vswhere.exe'
|
if ([string]::IsNullOrEmpty($vsCommandPromptPath))
|
||||||
$vs2017Instance = & $vsWhere -nologo -format value -property installationPath -latest -requires 'Microsoft.VisualStudio.Component.VC.CLI.Support'
|
{
|
||||||
$vs2017CommandPromptPath = $vs2017Instance + '\Common7\Tools\VsDevCmd.bat'
|
$vsCommandPromptPath = Get-VisualStudioCommandPromptPathForVisualStudio2015AndPrior
|
||||||
|
}
|
||||||
|
|
||||||
|
return $vsCommandPromptPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-VisualStudioCommandPromptPathForVisualStudio2017AndNewer
|
||||||
|
{
|
||||||
|
# Later we can probably make use of the VSSetup.PowerShell module to find the MsBuild.exe: https://github.com/Microsoft/vssetup.powershell
|
||||||
|
# Or perhaps the VsWhere.exe: https://github.com/Microsoft/vswhere
|
||||||
|
# But for now, to keep this script PowerShell 2.0 compatible and not rely on external executables, let's look for it ourselve in known locations.
|
||||||
|
# Example of known locations:
|
||||||
|
# "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
|
||||||
|
|
||||||
|
[string] $visualStudioDirectoryPath = Get-CommonVisualStudioDirectoryPath
|
||||||
|
[bool] $visualStudioDirectoryPathDoesNotExist = [string]::IsNullOrEmpty($visualStudioDirectoryPath)
|
||||||
|
if ($visualStudioDirectoryPathDoesNotExist)
|
||||||
|
{
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
# First search for the VS Command Prompt in the expected locations (faster).
|
||||||
|
$expectedVsCommandPromptPathWithWildcards = "$visualStudioDirectoryPath\*\*\Common7\Tools\VsDevCmd.bat"
|
||||||
|
$vsCommandPromptPathObjects = Get-Item -Path $expectedVsCommandPromptPathWithWildcards
|
||||||
|
|
||||||
|
[bool] $vsCommandPromptWasNotFound = ($vsCommandPromptPathObjects -eq $null) -or ($vsCommandPromptPathObjects.Length -eq 0)
|
||||||
|
if ($vsCommandPromptWasNotFound)
|
||||||
|
{
|
||||||
|
# Recurisvely search the entire Microsoft Visual Studio directory for the VS Command Prompt (slower, but will still work if MS changes folder structure).
|
||||||
|
Write-Verbose "The Visual Studio Command Prompt was not found at an expected location. Searching more locations, but this will be a little slow."
|
||||||
|
$vsCommandPromptPathObjects = Get-ChildItem -Path $visualStudioDirectoryPath -Recurse | Where-Object { $_.Name -ieq 'VsDevCmd.bat' }
|
||||||
|
}
|
||||||
|
|
||||||
|
$vsCommandPromptPathObjectsSortedWithNewestVersionsFirst = $vsCommandPromptPathObjects | Sort-Object -Property FullName -Descending
|
||||||
|
|
||||||
|
$newestVsCommandPromptPath = $vsCommandPromptPathObjectsSortedWithNewestVersionsFirst | Select-Object -ExpandProperty FullName -First 1
|
||||||
|
return $newestVsCommandPromptPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-VisualStudioCommandPromptPathForVisualStudio2015AndPrior
|
||||||
|
{
|
||||||
# Get some environmental paths.
|
# Get some environmental paths.
|
||||||
$vs2015CommandPromptPath = $env:VS140COMNTOOLS + 'VsDevCmd.bat'
|
$vs2015CommandPromptPath = $env:VS140COMNTOOLS + 'VsDevCmd.bat'
|
||||||
$vs2013CommandPromptPath = $env:VS120COMNTOOLS + 'VsDevCmd.bat'
|
$vs2013CommandPromptPath = $env:VS120COMNTOOLS + 'VsDevCmd.bat'
|
||||||
$vs2012CommandPromptPath = $env:VS110COMNTOOLS + 'VsDevCmd.bat'
|
$vs2012CommandPromptPath = $env:VS110COMNTOOLS + 'VsDevCmd.bat'
|
||||||
$vs2010CommandPromptPath = $env:VS100COMNTOOLS + 'vcvarsall.bat'
|
$vs2010CommandPromptPath = $env:VS100COMNTOOLS + 'vcvarsall.bat'
|
||||||
$vsCommandPromptPaths = @($vs2017CommandPromptPath, $vs2015CommandPromptPath, $vs2013CommandPromptPath, $vs2012CommandPromptPath, $vs2010CommandPromptPath)
|
$potentialVsCommandPromptPaths = @($vs2015CommandPromptPath, $vs2013CommandPromptPath, $vs2012CommandPromptPath, $vs2010CommandPromptPath)
|
||||||
|
|
||||||
# Store the VS Command Prompt to do the build in, if one exists.
|
# Store the VS Command Prompt to do the build in, if one exists.
|
||||||
$vsCommandPromptPath = $null
|
$newestVsCommandPromptPath = $null
|
||||||
foreach ($path in $vsCommandPromptPaths)
|
foreach ($path in $potentialVsCommandPromptPaths)
|
||||||
{
|
{
|
||||||
try
|
[bool] $pathExists = (![string]::IsNullOrEmpty($path)) -and (Test-Path -Path $path -PathType Leaf)
|
||||||
|
if ($pathExists)
|
||||||
{
|
{
|
||||||
if (Test-Path -Path $path)
|
$newestVsCommandPromptPath = $path
|
||||||
{
|
break
|
||||||
$vsCommandPromptPath = $path
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return the path to the VS Command Prompt if it was found.
|
# Return the path to the VS Command Prompt if it was found.
|
||||||
return $vsCommandPromptPath
|
return $newestVsCommandPromptPath
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-MsBuildPath([switch] $Use32BitMsBuild)
|
function Get-LatestMsBuildPath([switch] $Use32BitMsBuild)
|
||||||
{
|
{
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Gets the path to the latest version of MsBuild.exe. Throws an exception if MsBuild.exe is not found.
|
Gets the path to the latest version of MsBuild.exe. Throws an exception if MsBuild.exe is not found.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Gets the path to the latest version of MsBuild.exe. Throws an exception if MsBuild.exe is not found.
|
Gets the path to the latest version of MsBuild.exe. Throws an exception if MsBuild.exe is not found.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
|
[string] $msBuildPath = $null
|
||||||
|
$msBuildPath = Get-MsBuildPathForVisualStudio2017AndNewer -Use32BitMsBuild $Use32BitMsBuild
|
||||||
|
|
||||||
|
# If VS 2017 or newer MsBuild.exe was not found, check for older versions of MsBuild.
|
||||||
|
if ([string]::IsNullOrEmpty($msBuildPath))
|
||||||
|
{
|
||||||
|
$msBuildPath = Get-MsBuildPathForVisualStudio2015AndPrior -Use32BitMsBuild $Use32BitMsBuild
|
||||||
|
}
|
||||||
|
|
||||||
|
[bool] $msBuildPathWasNotFound = [string]::IsNullOrEmpty($msBuildPath)
|
||||||
|
if ($msBuildPathWasNotFound)
|
||||||
|
{
|
||||||
|
throw 'Could not determine where to find MsBuild.exe.'
|
||||||
|
}
|
||||||
|
|
||||||
|
[bool] $msBuildExistsAtThePathFound = (Test-Path $msBuildPath -PathType Leaf)
|
||||||
|
if(!$msBuildExistsAtThePathFound)
|
||||||
|
{
|
||||||
|
throw "MsBuild.exe does not exist at the expected path, '$msBuildPath'."
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msBuildPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-MsBuildPathForVisualStudio2017AndNewer([switch] $Use32BitMsBuild)
|
||||||
|
{
|
||||||
|
# Later we can probably make use of the VSSetup.PowerShell module to find the MsBuild.exe: https://github.com/Microsoft/vssetup.powershell
|
||||||
|
# Or perhaps the VsWhere.exe: https://github.com/Microsoft/vswhere
|
||||||
|
# But for now, to keep this script PowerShell 2.0 compatible and not rely on external executables, let's look for it ourselve in known locations.
|
||||||
|
# Example of known locations:
|
||||||
|
# "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe" - 32 bit
|
||||||
|
# "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64\MSBuild.exe" - 64 bit
|
||||||
|
|
||||||
|
[string] $visualStudioDirectoryPath = Get-CommonVisualStudioDirectoryPath
|
||||||
|
[bool] $visualStudioDirectoryPathDoesNotExist = [string]::IsNullOrEmpty($visualStudioDirectoryPath)
|
||||||
|
if ($visualStudioDirectoryPathDoesNotExist)
|
||||||
|
{
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
# First search for MsBuild in the expected 32 and 64 bit locations (faster).
|
||||||
|
$expected32bitPathWithWildcards = "$visualStudioDirectoryPath\*\*\MsBuild\*\Bin\MsBuild.exe"
|
||||||
|
$expected64bitPathWithWildcards = "$visualStudioDirectoryPath\*\*\MsBuild\*\Bin\amd64\MsBuild.exe"
|
||||||
|
$msBuildPathObjects = Get-Item -Path $expected32bitPathWithWildcards, $expected64bitPathWithWildcards
|
||||||
|
|
||||||
|
[bool] $msBuildWasNotFound = ($msBuildPathObjects -eq $null) -or ($msBuildPathObjects.Length -eq 0)
|
||||||
|
if ($msBuildWasNotFound)
|
||||||
|
{
|
||||||
|
# Recurisvely search the entire Microsoft Visual Studio directory for MsBuild (slower, but will still work if MS changes folder structure).
|
||||||
|
Write-Verbose "MsBuild.exe was not found at an expected location. Searching more locations, but this will be a little slow."
|
||||||
|
$msBuildPathObjects = Get-ChildItem -Path $visualStudioDirectoryPath -Recurse | Where-Object { $_.Name -ieq 'MsBuild.exe' }
|
||||||
|
}
|
||||||
|
|
||||||
|
$msBuildPathObjectsSortedWithNewestVersionsFirst = $msBuildPathObjects | Sort-Object -Property FullName -Descending
|
||||||
|
|
||||||
|
$newest32BitMsBuildPath = $msBuildPathObjectsSortedWithNewestVersionsFirst | Where-Object { $_.Directory.Name -ine 'amd64' } | Select-Object -ExpandProperty FullName -First 1
|
||||||
|
$newest64BitMsBuildPath = $msBuildPathObjectsSortedWithNewestVersionsFirst | Where-Object { $_.Directory.Name -ieq 'amd64' } | Select-Object -ExpandProperty FullName -First 1
|
||||||
|
|
||||||
|
if ($Use32BitMsBuild)
|
||||||
|
{
|
||||||
|
return $newest32BitMsBuildPath
|
||||||
|
}
|
||||||
|
return $newest64BitMsBuildPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-MsBuildPathForVisualStudio2015AndPrior([switch] $Use32BitMsBuild)
|
||||||
|
{
|
||||||
$registryPathToMsBuildToolsVersions = 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\'
|
$registryPathToMsBuildToolsVersions = 'HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\'
|
||||||
if ($Use32BitMsBuild)
|
if ($Use32BitMsBuild)
|
||||||
{
|
{
|
||||||
|
@ -514,22 +664,60 @@ function Get-MsBuildPath([switch] $Use32BitMsBuild)
|
||||||
$largestMsBuildToolsVersion = ($msBuildToolsVersions.GetEnumerator() | Sort-Object -Descending -Property Name | Select-Object -First 1).Value
|
$largestMsBuildToolsVersion = ($msBuildToolsVersions.GetEnumerator() | Sort-Object -Descending -Property Name | Select-Object -First 1).Value
|
||||||
$registryPathToMsBuildToolsLatestVersion = Join-Path -Path $registryPathToMsBuildToolsVersions -ChildPath ("{0:n1}" -f $largestMsBuildToolsVersion)
|
$registryPathToMsBuildToolsLatestVersion = Join-Path -Path $registryPathToMsBuildToolsVersions -ChildPath ("{0:n1}" -f $largestMsBuildToolsVersion)
|
||||||
$msBuildToolsVersionsKeyToUse = Get-Item -Path $registryPathToMsBuildToolsLatestVersion
|
$msBuildToolsVersionsKeyToUse = Get-Item -Path $registryPathToMsBuildToolsLatestVersion
|
||||||
$msBuildDirectoryPath = $msBuildToolsVersionsKeyToUse | Get-ItemProperty -Name 'MSBuildToolsPath' | Select -ExpandProperty 'MSBuildToolsPath'
|
$msBuildDirectoryPath = $msBuildToolsVersionsKeyToUse | Get-ItemProperty -Name 'MSBuildToolsPath' | Select-Object -ExpandProperty 'MSBuildToolsPath'
|
||||||
|
|
||||||
if(!$msBuildDirectoryPath)
|
if(!$msBuildDirectoryPath)
|
||||||
{
|
{
|
||||||
throw 'The registry on this system does not appear to contain the path to the MsBuild.exe directory.'
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the path to the MsBuild executable.
|
# Build the expected path to the MsBuild executable.
|
||||||
$msBuildPath = (Join-Path -Path $msBuildDirectoryPath -ChildPath 'msbuild.exe')
|
$msBuildPath = (Join-Path -Path $msBuildDirectoryPath -ChildPath 'MsBuild.exe')
|
||||||
|
|
||||||
if(!(Test-Path $msBuildPath -PathType Leaf))
|
|
||||||
{
|
|
||||||
throw "MsBuild.exe was not found on this system at the path specified in the registry, '$msBuildPath'."
|
|
||||||
}
|
|
||||||
|
|
||||||
return $msBuildPath
|
return $msBuildPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Get-CommonVisualStudioDirectoryPath
|
||||||
|
{
|
||||||
|
[string] $programFilesDirectory = $null
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$programFilesDirectory = Get-Item 'Env:\ProgramFiles(x86)' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{ }
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($programFilesDirectory))
|
||||||
|
{
|
||||||
|
$programFilesDirectory = 'C:\Program Files (x86)'
|
||||||
|
}
|
||||||
|
|
||||||
|
# If we're on a 32-bit machine, we need to go straight after the "Program Files" directory.
|
||||||
|
if (!(Test-Path -Path $programFilesDirectory -PathType Container))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$programFilesDirectory = Get-Item 'Env:\ProgramFiles' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
$programFilesDirectory = $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($programFilesDirectory))
|
||||||
|
{
|
||||||
|
$programFilesDirectory = 'C:\Program Files'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[string] $visualStudioDirectoryPath = Join-Path -Path $programFilesDirectory -ChildPath 'Microsoft Visual Studio'
|
||||||
|
|
||||||
|
[bool] $visualStudioDirectoryPathExists = (Test-Path -Path $visualStudioDirectoryPath -PathType Container)
|
||||||
|
if (!$visualStudioDirectoryPathExists)
|
||||||
|
{
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
return $visualStudioDirectoryPath
|
||||||
|
}
|
||||||
|
|
||||||
Export-ModuleMember -Function Invoke-MsBuild
|
Export-ModuleMember -Function Invoke-MsBuild
|
Loading…
Reference in New Issue