Add-Type - Added a way to reference assemblies by type name (#65866)

* Add-Type - Added a way to reference assemblies by type name

* Also add architecture symbols during compile time

* Fix stray output values
This commit is contained in:
Jordan Borean 2019-12-17 09:06:54 +10:00 committed by GitHub
parent 83ad1231b8
commit ae6fc265c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 11 deletions

View file

@ -0,0 +1,3 @@
minor_changes:
- PowerShell Add-Type - Add an easier way to reference extra types when compiling C# code on PowerShell Core
- PowerShell Add-Type - Added the ``X86`` and ``AMD64`` preprocessor symbols for conditional compiling

View file

@ -20,12 +20,11 @@ using System.Web.Script.Serialization;
// loaded in PSCore, ignore CS1702 so the code will ignore this warning // loaded in PSCore, ignore CS1702 so the code will ignore this warning
//NoWarn -Name CS1702 -CLR Core //NoWarn -Name CS1702 -CLR Core
//AssemblyReference -Name Newtonsoft.Json.dll -CLR Core //AssemblyReference -Type Newtonsoft.Json.JsonConvert -CLR Core
//AssemblyReference -Name System.ComponentModel.Primitives.dll -CLR Core //AssemblyReference -Type System.Diagnostics.EventLog -CLR Core
//AssemblyReference -Name System.Diagnostics.EventLog.dll -CLR Core //AssemblyReference -Type System.Security.AccessControl.NativeObjectSecurity -CLR Core
//AssemblyReference -Name System.IO.FileSystem.AccessControl.dll -CLR Core //AssemblyReference -Type System.Security.AccessControl.DirectorySecurity -CLR Core
//AssemblyReference -Name System.Security.Principal.Windows.dll -CLR Core //AssemblyReference -Type System.Security.Principal.IdentityReference -CLR Core
//AssemblyReference -Name System.Security.AccessControl.dll -CLR Core
//AssemblyReference -Name System.Web.Extensions.dll -CLR Framework //AssemblyReference -Name System.Web.Extensions.dll -CLR Framework

View file

@ -38,6 +38,33 @@ Function Add-CSharpType {
[String[]] A list of symbols to be defined during compile time. These are [String[]] A list of symbols to be defined during compile time. These are
added to the existing symbols, 'CORECLR', 'WINDOWS', 'UNIX' that are set added to the existing symbols, 'CORECLR', 'WINDOWS', 'UNIX' that are set
conditionalls in this cmdlet. conditionalls in this cmdlet.
.NOTES
The following features were added to control the compiling options from the
code itself.
* Predefined compiler SYMBOLS
* CORECLR - Added when running on PowerShell Core.
* WINDOWS - Added when running on Windows.
* UNIX - Added when running on non-Windows.
* X86 - Added when running on a 32-bit process (Ansible 2.10+)
* AMD64 - Added when running on a 64-bit process (Ansible 2.10+)
* Ignore compiler warnings inline with the following comment inline
//NoWarn -Name <rule code> [-CLR Core|Framework]
* Specify custom assembly references inline
//AssemblyReference -Name Dll.Location.dll [-CLR Core|Framework]
# Added in Ansible 2.10
//AssemblyReference -Type System.Type.Name [-CLR Core|Framework]
* Create automatic type accelerators to simplify long namespace names (Ansible 2.9+)
//TypeAccelerator -Name <AcceleratorName> -TypeName <Name of compiled type>
#> #>
param( param(
[Parameter(Mandatory=$true)][AllowEmptyCollection()][String[]]$References, [Parameter(Mandatory=$true)][AllowEmptyCollection()][String[]]$References,
@ -56,6 +83,13 @@ Function Add-CSharpType {
# the Is* variables are defined on PSCore, if absent we assume an # the Is* variables are defined on PSCore, if absent we assume an
# older version of PowerShell under .NET Framework and Windows # older version of PowerShell under .NET Framework and Windows
$defined_symbols = [System.Collections.ArrayList]$CompileSymbols $defined_symbols = [System.Collections.ArrayList]$CompileSymbols
if ([System.IntPtr]::Size -eq 4) {
$defined_symbols.Add('X86') > $null
} else {
$defined_symbols.Add('AMD64') > $null
}
$is_coreclr = Get-Variable -Name IsCoreCLR -ErrorAction SilentlyContinue $is_coreclr = Get-Variable -Name IsCoreCLR -ErrorAction SilentlyContinue
if ($null -ne $is_coreclr) { if ($null -ne $is_coreclr) {
if ($is_coreclr.Value) { if ($is_coreclr.Value) {
@ -77,7 +111,7 @@ Function Add-CSharpType {
$type_accelerators = [System.Collections.Generic.List`1[Hashtable]]@() $type_accelerators = [System.Collections.Generic.List`1[Hashtable]]@()
# pattern used to find referenced assemblies in the code # pattern used to find referenced assemblies in the code
$assembly_pattern = [Regex]"//\s*AssemblyReference\s+-Name\s+(?<Name>[\w.]*)(\s+-CLR\s+(?<CLR>Core|Framework))?" $assembly_pattern = [Regex]"//\s*AssemblyReference\s+-(?<Parameter>(Name)|(Type))\s+(?<Name>[\w.]*)(\s+-CLR\s+(?<CLR>Core|Framework))?"
$no_warn_pattern = [Regex]"//\s*NoWarn\s+-Name\s+(?<Name>[\w\d]*)(\s+-CLR\s+(?<CLR>Core|Framework))?" $no_warn_pattern = [Regex]"//\s*NoWarn\s+-Name\s+(?<Name>[\w\d]*)(\s+-CLR\s+(?<CLR>Core|Framework))?"
$type_pattern = [Regex]"//\s*TypeAccelerator\s+-Name\s+(?<Name>[\w.]*)\s+-TypeName\s+(?<TypeName>[\w.]*)" $type_pattern = [Regex]"//\s*TypeAccelerator\s+-Name\s+(?<Name>[\w.]*)\s+-TypeName\s+(?<TypeName>[\w.]*)"
@ -116,9 +150,15 @@ Function Add-CSharpType {
if ($clr -and $clr -ne "Core") { if ($clr -and $clr -ne "Core") {
continue continue
} }
$assembly_path = $match.Groups["Name"]
if (-not ([System.IO.Path]::IsPathRooted($assembly_path))) { $parameter_type = $match.Groups["Parameter"].Value
$assembly_path = Join-Path -Path $lib_assembly_location -ChildPath $assembly_path $assembly_path = $match.Groups["Name"].Value
if ($parameter_type -eq "Type") {
$assembly_path = ([Type]$assembly_path).Assembly.Location
} else {
if (-not ([System.IO.Path]::IsPathRooted($assembly_path))) {
$assembly_path = Join-Path -Path $lib_assembly_location -ChildPath $assembly_path
}
} }
$assemblies.Add([Microsoft.CodeAnalysis.MetadataReference]::CreateFromFile($assembly_path)) > $null $assemblies.Add([Microsoft.CodeAnalysis.MetadataReference]::CreateFromFile($assembly_path)) > $null
} }
@ -256,7 +296,13 @@ Function Add-CSharpType {
if ($clr -and $clr -ne "Framework") { if ($clr -and $clr -ne "Framework") {
continue continue
} }
$assemblies.Add($match.Groups["Name"].Value) > $null
$parameter_type = $match.Groups["Parameter"].Value
$assembly_path = $match.Groups["Name"].Value
if ($parameter_type -eq "Type") {
$assembly_path = ([Type]$assembly_path).Assembly.Location
}
$assemblies.Add($assembly_path) > $null
} }
$warn_matches = $no_warn_pattern.Matches($reference) $warn_matches = $no_warn_pattern.Matches($reference)
foreach ($match in $warn_matches) { foreach ($match in $warn_matches) {
@ -321,3 +367,4 @@ Function Add-CSharpType {
} }
Export-ModuleMember -Function Add-CSharpType Export-ModuleMember -Function Add-CSharpType

View file

@ -272,5 +272,28 @@ try {
} }
Assert-Equals -actual $failed -expected $true Assert-Equals -actual $failed -expected $true
$arch_class = @'
using System;
namespace Namespace11
{
public class Class11
{
public static int GetIntPtrSize()
{
#if X86
return 4;
#elif AMD64
return 8;
#else
return 0;
#endif
}
}
}
'@
Add-CSharpType -Reference $arch_class
Assert-Equals -actual ([Namespace11.Class11]::GetIntPtrSize()) -expected ([System.IntPtr]::Size)
$result.res = "success" $result.res = "success"
Exit-Json -obj $result Exit-Json -obj $result