微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用范围重新创建PowerShell脚本块

如何解决使用范围重新创建PowerShell脚本块

我具有以下cmdlet来调用任意脚本块(通常调用exe)并处理返回代码。这里的目标是打印一个命令行,运行它,然后在失败时抛出一个错误....


function Invoke-ScriptBlock {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [scriptblock]$Block
    )

    $ErrorActionPreference = 'Continue'

    $stringBlock = "@`"`n" + $Block.ToString().Trim() + "`n`"@"
    $stringValue = . ([scriptblock]::create($stringBlock))

    Write-information "Invoking command: $stringValue"

    . $Block
    if ($lastexitcode -ne 0) { Write-Error "Command exited with code $lastexitcode" -EA Stop }
}

$comment = 'acomment'
Invoke-ScriptBlock { git commit -m $comment }
# prints Invoking command: git commit -m acomment

只要Invoke-ScriptBlock cmdlet不在模块内部,此方法就很好用。如果是这样,我将丢失“调用命令”消息中捕获的变量的闭包。

Import-Module .\Util.psm1
$comment = 'acomment'
Invoke-ScriptBlock { git commit -m $comment }
# prints Invoking command: git commit -m

有没有一种方法可以使用传入的$ Block中的原始上下文重新创建脚本块?

解决方法

没有受支持的方法,但是您可以通过将会话状态引用从原始$Block复制到重新创建的脚本块中来进行反射:

function Invoke-ScriptBlock {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [scriptblock]$Block
    )

    # To prove local and module-scoped variables won't affect the new script block
    $comment = ''

    # Obtain a reference to the relevant internal ScriptBlock property 
    $ssip = [scriptblock].GetProperty('SessionStateInternal',[System.Reflection.BindingFlags]'NonPublic,Instance')

    # Copy the value from $Block
    $ssi = $ssip.GetMethod.Invoke($Block,@())

    # Create new block with the same content 
    $newBlock = [scriptblock]::create("@`"`n" + $Block.ToString().Trim() + "`n`"@")

    # Overwrite session state value with the one with copied from $Block
    $ssip.SetMethod.Invoke($newBlock,@($ssi))

    $stringValue = & $newBlock

    Write-Information "Invoking command: $stringValue"
    & $Block
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?