2013-03-03 67 views
6

我想从文件导入外部函数,而不是将其转换为模块(我们有数百个每个函数文件,因此将它们视为模块过度使用) 。函数内部从文件到全局范围的点源函​​数

以下是代码说明。请注意,我在导入函数中添加了一些额外的逻辑,例如添加脚本根文件夹以及检查文件存在并抛出特殊错误,以避免需要这种导入的每个脚本中的代码重复。

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!' 

有什么绝招,以点源到全球范围内?

回答

4

您不能使脚本在父范围内运行,但可以通过显式范围化在全局范围内创建函数。

会是这样的工作吗?

# 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' 
+0

非常感谢你,这个不错的hach正在工作。如果你不介意的话,我添加了一些小修补程序来使其工作。 – 2013-03-03 19:52:23

+0

不要介意。我只是想传达一个想法,不一定是一个完整的解决方案。 – mjolinor 2013-03-03 20:02:43

+0

@AntonPurin你可以更新答案,包括你的'小修正'? – 2013-05-29 02:36:37

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() 

当你转换脚本块为字符串.ToString(),变量将扩大。

0

您可以更改在点源文件中定义的功能,使它们在定义全局范围:

function Global:Get-SomeThing { 
    # ... 
} 

当你点一个函数内的源代码时,源代码文件中定义的函数将是全局的。不要说这是最好的主意,只是另一种可能性。

相关问题