我知道如何在PowerShell 5中构建具有不安全代码的库(以及更少),但我在PowerShell 6中无法做到这一点。事实上,PowerShell 6基于.NET Core,这就是为什么Add-Type
cmdlet避风港的原因't -CompilerParameters
。
我应该使用第三方库来解决我的问题吗?有没有办法在没有第三方库的情况下构建不安全的代码,如果它是真的那么如何?
答案 0 :(得分:0)
在专门讨论PowerShell的一个IRC频道中,一个名叫Grigori Zakharov的人提出了一个没有第三方库的解决方案,看起来像这样。
$src = @'
using System;
public static class Test {
public static unsafe void MyMethod(...) {
...; // some logic
}
}
'@
# set of C# compilation parameters
$lst = New-Object "Collections.Generic.List[Microsoft.CodeAnalysis.SyntaxTree]"
$lst.Add([Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree]::ParseText($src))
[Microsoft.CodeAnalysis.MetadataReference[]]$ref = @(
[Microsoft.CodeAnalysis.MetadataReference]::CreateFromFile(
[Object].Assembly.Location
)
)
$opt = New-Object Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(
[Microsoft.CodeAnalysis.OutputKind]::DynamicallyLinkedLibrary
)
[Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions].GetProperty(
'AllowUnsafe' # because we're using unsafe code
).SetValue($opt, $true)
# let's rock!
$cmp = [Microsoft.CodeAnalysis.CSharp.CSharpCompilation]::Create(
[IO.Path]::GetRandomfileName(), $lst, $ref, $opt
)
try {
$ms = New-Object IO.MemoryStream
if (!($err = $cmp.Emit($ms)).Success) { throw $err }
[void]$ms.Seek(0, [IO.SeekOrigin]::Begin)
$asm = [Reflection.Assembly]::Load($ms.ToArray())
}
catch { $_ }
finally {
if ($ms) { $ms.Dispose() }
}
[Test]::MyMethod(...)
所以,我猜这个问题已经解决了。