在PowerShell 6中构建不安全的代码

时间:2018-01-04 10:43:06

标签: powershell

我知道如何在PowerShell 5中构建具有不安全代码的库(以及更少),但我在PowerShell 6中无法做到这一点。事实上,PowerShell 6基于.NET Core,这就是为什么Add-Type cmdlet避风港的原因't -CompilerParameters

我应该使用第三方库来解决我的问题吗?有没有办法在没有第三方库的情况下构建不安全的代码,如果它是真的那么如何?

1 个答案:

答案 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(...)

所以,我猜这个问题已经解决了。