2011-12-23 39 views
1

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

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


UPDATE

于是我运行下面的模块,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 
} 
} 

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

+0

我不太确定我理解你的问题。你是说,因为它是一个循环,它阻止了其他代码的运行?如果是这样,您可以让文件系统监视器通过注册事件处理程序而不是使用循环来异步触发脚本块。如果这听起来像你所需要的,我可以给你一些示例代码。 – 2011-12-23 15:07:04

+0

@Andy:是的,因为它在一个循环中,它阻塞了其他代码。而且由于重新加载/导入模块只会在文件系统观察器运行的当前环境中运行,所以我无法重新运行依赖于重新加载/导入的模块的脚本。我不确定手表是否会发生事件会起作用,因为那时我必须硬编码将会发生什么。但是,如果它不多,你能举一些例子吗? – pghtech 2011-12-23 15:26:23

回答

2

下面是一些代码,我有一些代码将文件夹复制到共享文件夹中,随时更改其中的某些内容。它有点我的小Dropbox的实施:-)

任何时候,只要文件系统观察的事件类型,如Changed发生的一个,在Register-ObjectEvent cmdlet将火灾-Action参数指定的代码。

在你-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 } 
+0

我接受了你的建议并采用了相同的路线,我的Action基本上检查是否加载了模块,并导入或重新加载更改的模块(.psm1)文件。但是,我发现无论执行代码块时是否返回,都不会加载模块 - 至少在运行脚本的环境中将代码块绑定到事件。 – pghtech 2011-12-26 16:00:12

+0

我试图查看是否有方法在代码块中传递特定于环境的信息,并针对特定会话/环境加载模块 – pghtech 2011-12-26 16:13:14

+0

如果我的理解正确,请说出以下内容。 1.导入模块加载初始模块。 2.模块文件改变。 3.事件处理程序触发脚本块。 4.脚本块重新加载模块。 5.模块更改不生效。是对的吗? – 2011-12-26 16:35:49

相关问题