使用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,它似乎被调用,正如调试所证实的那样,但似乎不在动态任务的执行范围内。
答案 0 :(得分:1)
关于上述内容,适当的方法似乎是将$ TaskCode的定义修改为dot source该文件。
如果我们假设。\ BuildThing.ps1包含一个函数 - 例如
function BuildThing {
param(...)
...
}
然后动态任务代码需要点源此代码。对于大量类似的构建任务而言,这似乎效率低下,但它确实解决了这个问题。
$TaskCode = @'
. .\BuildThing.ps1
BuildThing -MetaData $MetaData
'@