Skip to content

Instantly share code, notes, and snippets.

@altrive
Last active December 24, 2015 07:49
Show Gist options
  • Select an option

  • Save altrive/6765957 to your computer and use it in GitHub Desktop.

Select an option

Save altrive/6765957 to your computer and use it in GitHub Desktop.
Sample code to to import C# type definition to avoid type name conflict.when Add-Type called multiple times.
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Main
{
Add-TypeDefinition
$sw = [Diagnostics.Stopwatch]::StartNew()
$task1 = [PSContext]::StartNew({ Get-Process; sleep 2;})
$task2 = [PSContext]::StartNew({ Get-Process; sleep 4;})
$task3 = [PSContext]::StartNew({ Get-Process; sleep 6;})
[Threading.Tasks.Task]::WaitAll($task1, $task2,$task3)
$elapsed = $sw.Elapsed
Write-Host ("Elapsed {0} [ms]" -f $elapsed.TotalMilliseconds)
}
#Add class definition with unique type name(To avoid type name confliction, AppDomain can't unload type)
function Add-TypeDefinition
{
[string] $code = @'
using System.Management.Automation;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
public static class PSContext
{
public static Task<PSDataCollection<PSObject>> StartNew(ScriptBlock sb)
{
var powershell =PowerShell.Create().AddScript(sb.ToString());
var task = Task.Factory.FromAsync(powershell.BeginInvoke (), (r) => powershell.EndInvoke(r));
return task;
}
}
'@
#Guid suffix to create unique class name
$uniqueSuffix = "_{0}" -f [Guid]::NewGuid().ToString().Replace("-", "_")
#Replace class name to unique name
$regex = [regex] "(?<=public\s+(static\s)?class\s+)\w*"
$code = $regex.Replace($code, [String]::Format("{0}{1}", "$&", $uniqueSuffix))
#Add replaced code definition
Add-Type -ReferencedAssemblies "Microsoft.CSharp" -TypeDefinition $code #-IgnoreWarnings
#Add original class name alias
foreach ($match in $regex.Matches($code)){
$className = $match.Value.Replace($uniqueSuffix, "")
#Write-Verbose ("Replace class name '{0}' to '{1}'" -f $className, $match.Value) -Verbose
[PSObject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add($className, $match.Value)
}
}
. Main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment