我想从文件中导入外部函数,而不是将其转换为模块(我们有数百个每个函数的文件,所以将它们视为模块是过度的)。
这是代码说明。请注意我在Import-Function中有一些额外的逻辑,比如添加脚本根文件夹并检查文件是否存在并抛出特殊错误,以避免每个需要这种导入的脚本中的代码重复。
C:\库\ Foo.ps1:
Function Foo {
Write-Host 'Hello world!'
}
C:\ InvocationTest.ps1:
# Wrapper func
Function Import-Function ($Name) {
# Checks and exception throwing are omitted
. "C:\Repository\$name.ps1"
# Foo function can be invoked in this scope
}
# Wrapped import
Import-Function -Name 'Foo'
Foo # Exception: The term 'Foo' is not recognized
# Direct import
. "C:\Repository\Foo.ps1"
Foo # 'Hello world!'
将来源点到全球范围有什么诀窍吗?
答案 0 :(得分:5)
您无法使脚本在父作用域中运行,但您可以通过显式作用域来在全局作用域中创建一个函数。
这样的事情对你有用吗?
# Wrapper func
Function Import-Function ($Path) {
# Checks and exception throwing are omitted
$script = Get-Content $Path
$Script -replace '^function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)', 'function Global:$1'
.([scriptblock]::Create($script))
}
The above regex仅定位根函数(左对齐函数;单词function
左侧没有空格)。为了定位所有函数,无论间距(包括子函数)如何,将$Script -replace
行更改为:
$Script -replace '^\s*function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)','function Global:$1'
答案 1 :(得分:2)
您可以更改点源文件中定义的函数,以便在全局范围内定义它们:
function Global:Get-SomeThing {
# ...
}
当你从函数中点源时,点源文件中定义的函数将是全局的。不是说这是最好的主意,只是另一种可能性。
答案 2 :(得分:0)
我现在不记得在全局范围内运行函数的方法。你可以这样做:
$name = "myscript"
$myimportcode= {
# Checks and exception throwing are omitted
. .\$name.ps1
# Foo function can be invoked in this scope
}
Invoke-Expression -Command $myimportcode.ToString()
将scriptblock转换为字符串.ToString()
时,变量将展开。