Как я могу перезагрузить модули из одной открытой рабочей среды, чтобы повлиять на другую рабочую среду - PullRequest
1 голос
/ 23 декабря 2011

Мой проект PowerShell разбит на модули.Но поскольку они являются модулями, я должен перезагружать их каждый раз, когда меняю их.Поэтому я написал цикл с FileSystemWatcher, и если один из файлов .psm1 изменится, он либо перезагрузит, либо импортирует этот модуль.

Проблема в том, что вышеприведенный цикл не позволит мне запускать другие скриптыв своей рабочей среде, поэтому в новой среде не будут загружаться / перезагружаться те же модули.Мне нужно держать эти модули вне основной папки (модулей) PowerShell по умолчанию.Есть ли способ запустить скрипт, который перезагружает модули, когда они изменяются в той же среде или влияют на определенную среду?


ОБНОВЛЕНИЕ

Итак, я запускаюследующий скрипт Module-Loader.ps1.Блок кода, связанный с событием FileChanged, срабатывает, когда я «сохраняю» файл * .psm1 после его изменения.Однако возникают две проблемы: 1) он срабатывает дважды, когда я сохраняю

2a) Если модуль не загружен, он запускает Import-Module $ PWD \ ModuleName, но фактически не загружается, по крайней мере, всреда (если я запускаю тот же код в среде, которую он загрузит)

2b), если он загружен и пытается удалить модуль, он выдаст ошибку, что его не существует.

# create a FileSystemWatcher on the currect directory
$filter = '*.psm1'
$folder = $PWD
$watcher = New-object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false; EnableRaisingEvents = $true; NotifyFilter = [IO.NotifyFilters]'LastWrite'}
Register-ObjectEvent $watcher Changed -SourceIdentifier FileChanged -Action { 
$name = $Event.SourceEventArgs.Name 
$filename = $name.Remove($name.IndexOf('.'), 5)

$loadedModule = Get-Module | ? { $_.Name -eq $filename }
write-host $filename

if ($loadedModule) {
    write-host "Reloading Module $folder\$($filename)"
    Reload-Module $folder\$filename
} else {
    write-host "Importing Module $folder\$($filename)"
    Import-Module $folder\$filename
}
}

Я считаю, что хотя это выполняется в сеансе, блок кода в событии не связан с этой конкретной средой.

1 Ответ

2 голосов
/ 23 декабря 2011

Вот пример из моего кода, который копирует папку в общую папку каждый раз, когда в ней что-то меняется. Это моя маленькая реализация Dropbox :-)

Каждый раз, когда происходит один из типов событий наблюдателя файловой системы, например Changed, запускается код, указанный в параметре -Action командлета Register-ObjectEvent.

В вашем коде -Action вы бы вызвали Import-Module с параметром -Force, чтобы перезаписать текущий в память.

function Backup-Folder {
    & robocopy.exe "c:\folder" "\\server\share" /MIR /W:10 /R:10
}

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "c:\folder"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true

Register-ObjectEvent $watcher "Changed" -Action { Backup-Folder }
Register-ObjectEvent $watcher "Created" -Action { Backup-Folder }
Register-ObjectEvent $watcher "Deleted" -Action { Backup-Folder }
Register-ObjectEvent $watcher "Renamed" -Action { Backup-Folder }
...