13

モジュールに変換するのではなく、ファイルから外部関数をインポートしたい(関数ごとに何百ものファイルがあるので、それらすべてをモジュールとして扱うのはやり過ぎです)。

これがコードの説明です。この種のインポートを必要とする各スクリプトでこのコードの重複を回避するために、スクリプトのルートフォルダーを追加したり、ファイルの存在を確認して特別なエラーをスローしたりするなど、インポート機能にいくつかの追加ロジックがあることに注意してください。

C:\ Repository \ 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

4 に答える 4

6

スクリプトを親スコープで実行することはできませんが、明示的にスコープすることでグローバル スコープで関数を作成できます。

このようなものはあなたのために働くでしょうか?

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

}

上記の正規表現は、ルート関数のみを対象としています (関数は左詰めで、単語の左側に空白はありませんfunction)。間隔 (サブ関数を含む) に関係なく、すべての関数をターゲットにするには、$Script -replace行を次のように変更します。

$Script -replace '^\s*function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)','function Global:$1'
于 2013-03-03T16:44:56.897 に答える
4

ドット ソース ファイルで定義されている関数を変更して、グローバル スコープで定義することができます。

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

関数内からそれをドットソースすると、ドットソースファイルで定義された関数はグローバルになります。これが最良のアイデアだと言っているのではなく、別の可能性です。

于 2016-01-26T20:41:14.157 に答える
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()と、変数が展開されます。

于 2013-03-03T16:31:18.420 に答える