Skip to content

Instantly share code, notes, and snippets.

@JamesWoolfenden
Last active November 19, 2018 09:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesWoolfenden/6391122545455b33d153 to your computer and use it in GitHub Desktop.
Save JamesWoolfenden/6391122545455b33d153 to your computer and use it in GitHub Desktop.
Powershell build functions, direct call to msbuild API.
[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][System.Reflection.Assembly]::Load('Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][System.Reflection.Assembly]::Load('mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
function make()
{
<#
.SYNOPSIS
Builds all files according to a naming strategy found in the given or current path
.PARAMETER path
A string path to build, optional if not given makes current path.
.PARAMETER target
What build target for the project you want executing defaults to build.
.PARAMETER passedparam
An optional object of the type Microsoft.Build.Execution.BuildParameters determines how the project is built.
.OUTPUTS
.EXAMPLE
make
.EXAMPLE
make -path C:\code\yourappcode -target clean
.NOTES
#>
param(
[string]$path,
[string]$target="Build",
[Microsoft.Build.Execution.BuildParameters]$PassedParams)
$sw = [Diagnostics.Stopwatch]::StartNew()
$path=@{$true=(gl).path;$false=$path}[$path -eq ""]
[string[]]$include=@("*.csproj","*.vbproj")
$files=get-childitem -path $path -include $include -Recurse
# were following a naming convention for deployable components
$filters=@("client","utility","service",".app.","addin","database.update")
$found=@()
foreach($filter in $filters)
{
foreach($file in $files)
{
If ($file.Name -like "*$filter*")
{
$found+=$file
}
}
}
Write-debug "$found"
$found=$found|select -Unique
if ($found.count -gt 0)
{
foreach($foundfile in $found)
{
write-debug "build -file $foundfile -PassedParams $PassedParams -root $path"
build -file $foundfile -PassedParams $PassedParams -root $path
}
}
Else
{
Write-debug "Nothing to build found" -ForegroundColor Yellow
}
$sw.Stop()
Write-host "Total Time Elapsed $($sw.Elapsed.ToString())" -ForegroundColor Green
}
function build()
{
<#
.SYNOPSIS
Builds a project using msbuild API
.PARAMETER File
A string containing the project file.
.PARAMETER target
What build target for the project you want executing defaults to build.
.PARAMETER passedparam
An optional object of the type Microsoft.Build.Execution.BuildParameters determines how the project is built.
.OUTPUTS
.EXAMPLE
build -file C:\code\Website\app.csproj -target build
.EXAMPLE
build -file C:\code\Website\app.csproj -target clean
.NOTES
#>
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$File,
[string]$target="Build",
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$root,
[Microsoft.Build.Execution.BuildParameters]$PassedParams)
$logger = new-Object Microsoft.Build.BuildEngine.ConsoleLogger
$manager = new-Object Microsoft.Build.Execution.BuildManager
$arraylog = New-Object collections.generic.list[Microsoft.Build.Framework.ILogger]
$arraylog.Add($logger)
#$projectInstance = new-object Microsoft.Build.Execution.ProjectInstance("$File")
$BaseName=split-path $file -Parent
write-debug "PassedParam: $PassedParam"
if ($PassedParam -eq $null)
{
$params = new-object Microsoft.Build.Execution.BuildParameters
$params.DetailedSummary=$false
$params.DefaultToolsVersion=4.0
$params.MaxNodeCount=8
$params.BuildThreadPriority="Highest"
$params.Loggers=$arraylog
$globals = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
$globals.Add("Configuration","Debug")
$globals.Add("Platform","Any CPU")
$globals.Add("OutputPath","$root\output\$($(gi $file).Basename)")
$params.GlobalProperties=$globals
Write-debug "Using default parameters" -ForegroundColor Yellow
}
else
{
$params=$PassedParams
}
$targets=@("$target")
$request=new-object Microsoft.Build.Execution.BuildRequestData($file, $globals, "4.0", $targets, $null)
$result = $manager.Build($params, $request)
$buildResult=$result.ResultsByTarget["$target"]
$buildResultItems = $buildResult.Items;
}
@JamesWoolfenden
Copy link
Author

Just to get the ball rolling. Hoping to extent this from now on, especially if anyone find it useful.

@NiharikaSarabu
Copy link

Hello James,
Above code part is much helpful to me, but the only problem i see is when i try to assign the $arraylog to the $params.Loggers =$arraylog. Seeing the below error:
Exception setting "Loggers": "Cannot convert the "System.Collections.Generic.List1[Microsoft.Build.Framework.ILogger]" value of type "System.Collections.Generic.List1[[Microsoft.Build.Framework.ILogger, Microsoft.Build.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]]" to type
"System.Collections.Generic.IEnumerable`1[Microsoft.Build.Framework.ILogger]"."

   Could you please help me in converting the list $arraylog to ienumerable to proceed further.

Regards,
Niharika.

@vncoelho
Copy link

Can I Use it to compile a .sln project?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment