2011-12-23 65 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

相關問題