1

我将 PowerShell 项目分解为模块。但是因为它们是模块,所以我每次更改它们时都必须重新加载它们。因此,我编写了一个具有 FileSystemWatcher 的循环,如果其中一个 .psm1 文件发生更改,它将重新加载或导入该模块。

问题是上述循环不会让我在其工作环境中运行其他脚本,因此新环境不会为其加载/重新加载相同的模块。我需要将这些模块保留在主要的默认 PowerShell 模块文件夹之外。当模块在同一环境中更改或影响特定环境时,是否有办法运行重新加载模块的脚本?


更新

所以我运行以下 Module-Loader.ps1 脚本。当我在修改后“保存”*.psm1 文件时,与“FileChanged”事件关联的代码块会触发。但是发生了两个问题: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
}
}

我认为虽然这是在会话中运行的,但事件中的代码块与此特定环境无关。

4

1 回答 1

2

这是我拥有的一些代码中的一个示例,该示例将文件夹复制到共享文件夹中,只要其中有任何更改。这有点像我的小保管箱实现:-)

每当文件系统观察程序事件类型之一发生时, cmdlet参数中Changed指定的代码都会触发。-ActionRegister-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 }
于 2011-12-23T17:24:51.280 回答