Вызов локальной функции из файла с точечным источником

#powershell

#powershell

Вопрос:

У меня есть основной скрипт, который я запускаю. Что он делает, так это считывает каталог, заполненный другими сценариями powershell, dot включает их все и запускает в каждом из них предопределенный метод, состоящий из первой части имени файла, разделенного точкой. Пример:

  1. Запустите master.ps1
  2. Master.ps1 точечные источники .resourcesub.ps1
  3. В Sub.ps1 определена функция с именем ‘dosub’
  4. Master.ps1 запускает ‘dosub’ с помощью Invoke-Expression

В sub.ps1 также определена функция ‘saysomething’. Реализованный в ‘dosub’ — это вызов ‘saysomething’.

Моя проблема в том, что я продолжаю получать ошибку:

Термин «saysomething» не распознается как имя командлета, функции, файла сценария или рабочей программы. Проверьте правильность написания имени или, если был указан путь, убедитесь, что путь указан правильно, и повторите попытку.

Почему метод ‘dosub’ не может найти метод ‘saysomething’, который определен в том же файле?

master.ps1:

 $handlersDir = "handlers"

$handlers = @(Get-ChildItem $handlersDir)

foreach ( $handler in $handlers ) {

    . .$handlersDir$handler

    $fnParts = $handler.Name.split(".")

    $exp = "do"   $fnParts[0]
    Invoke-Expression $exp
}
 

sub.ps1:

 function saysomething() {
    Write-Host "I'm here to say something!"
}


function dosub() {
    saysomething
    Write-Host "In dosub!"
}
 

Комментарии:

1. Ваш пример работает для меня. Является ли то, что вы опубликовали, именно тем, что вы используете, вашей системой?

Ответ №1:

Ваш код работает в моей системе. Однако вы можете немного упростить это:

 $handlersDir = "handlers"

$handlers = @(Get-ChildItem $handlersDir)
foreach ( $handler in $handlers ) 
{
    . .$handlersDir$handler

    $exp = "do"   $handler.BaseName
    Write-Host "Calling $exp"
    amp; $exp
}
 

Обратите внимание на доступность BaseName свойства. Вам также не нужно использовать Invoke-Expression . Вы можете просто вызвать именованную команду, используя оператор call ( amp; ) .

Комментарии:

1. Ну, странная часть здесь для меня заключается в том, что я вижу вывод узла записи «В dosub!», А также ошибку «Термин «saysomething» не распознается …». Это означает, что мой главный скрипт просматривает, находит и запускает код в «вложенных» файлах. Это исключает неправильные настройки «нормальной» среды и оставляет только более загадочные возможности. Я попробую это на другой машине и посмотрю, повезет ли мне больше.

2. Я провел свой тест на PowerShell v2. Вы используете версию v1?

Ответ №2:

То, что вы указали, работает по мере необходимости. Вероятно, на вашем компьютере нет соответствующих каталогов и т. Д. Или вы запускаете что-то еще и размещаете здесь другой (рабочий!) Код.

Вы также можете внести следующие исправления:

 . .$handlersDir$handler
 

вместо приведенного выше вы можете сделать:

 . $handler.fullname
 

Вместо разделения имени файла вы можете сделать:

 $exp = "do"   $handler.basename
 

Комментарии:

1. Спасибо за указатель на базовое имя, я отключу его прямо сейчас. Что касается кода, я вставляю его прямо из файла, никаких изменений нет!

2. @QuinnPeters — У меня это работает. Убедитесь, что у вас есть каталог обработчиков и файлы в нем. Что-то может быть не так в вашей «среде».