2

使用 Invoke-Build 我正在尝试创建动态构建任务,该方法的示例如下。其中,以与经典 UNIX make 工具类似的方式,如果输入文件比输出文件新,将为每个输入文件生成一个输出文件。

它通过动态生成一组增量任务然后调用这些任务来实现这一点。

增量任务的生成概述如下:

    $Jobs = Foreach($_ in $Conf ) {
        $SourceFile = Get-Item $_
        $FileName = $SourceFile.Name
        $ObjectName = $FileName -replace '^Thing-(.*)\.conf\.ps1$','$1'
        $TaskName = "Task-$ObjectName"
        $OutFile = "Thing-$ObjectName.ps1"
        # Import the script, overwriting the "$MetaData" variable    
        $MetaData = . $SourceFile

    $TaskCode = @'
.\BuildThing.ps1
BuildThing -MetaData $MetaData
'@
        Write-Verbose "$SourceFile $OutFile"
        $SBInputs = [scriptblock]::Create(  { $SourceFile } ).GetNewClosure()
        $SBOutputs = [scriptblock]::Create( { $OutFile } ).GetNewClosure()
        $SBMain = [scriptblock]::Create($TaskCode).GetNewClosure()
        Task "$TaskName" -Inputs $SBInputs -Outputs $SBOutputs ($SBMain)

        Write-Output $TaskName
    }

除了所需其他功能的范围之外,这似乎确实运作良好。无论我在哪里尝试在任务 Task-Thing- 执行时获取 BuildThing.ps1 脚本,Invoke-Build 都会抱怨 BuildThing 未被识别为:

“cmdlet、函数、脚本文件或可运行程序的名称。”

如果我在运行 Invoke-Build 之前点源相关文件,一切都会按预期工作。

这似乎是一个范围界定问题 - 但目前尚不清楚如何以直接的方式解决它。

如果我尝试以静态方式将 BuildThing.ps1 包含在循环之外,它似乎确实被调用,正如调试所证实的那样,但似乎不在动态任务执行的范围内。

4

1 回答 1

1

关于上述内容,适当的方法似乎是修改 $TaskCode 的定义以点源文件。

如果我们假设 .\BuildThing.ps1 包含一个函数 - 例如

function BuildThing {
param(...)
...
}

那么动态任务代码需要dot source这个代码。对于大量类似的构建任务来说,这似乎效率低下,但它确实解决了这个问题。

$TaskCode = @'
. .\BuildThing.ps1
BuildThing -MetaData $MetaData
'@
于 2015-02-18T09:49:44.547 回答