如何从一个开放的工作环境重新加载模块以影响另一个工作环境 [英] How can I reload modules from one open work environment to affect another working environment

查看:43
本文介绍了如何从一个开放的工作环境重新加载模块以影响另一个工作环境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have my PowerShell project broken into modules. But because they are modules I have to reload them every time I change them. So I wrote a loop that has a FileSystemWatcher and if one of the .psm1 file changes it will either reload or import that module.

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

The problem is that the above loop isn't going to let me run other scripts in its working environment, so a new environment will not have the same modules loaded/reloaded for it. I need to keep these modules out of the primary default PowerShell modules folder(s). Is there a way to run the script that reloads the modules when they change in the same environment or affect a certain environment?

更新

所以我运行以下 Module-Loader.ps1 脚本.当我在修改后保存"*.psm1 文件时,与FileChanged"事件关联的代码块会触发.但是出现了两个问题:1) 当我保存时它会触发两次

So I run the following Module-Loader.ps1 script. The code block associated with the 'FileChanged' event does fire when I 'save' a *.psm1 file after having been modified. However two issues occure: 1) it fires twice when I save

2a) 如果模块没有加载,它会运行Import-Module $PWD\ModuleName,但它至少不会在环境中实际加载(如果我在环境中运行相同的代码,它将加载)

2a) If the module is not loaded, it will run Import-Module $PWD\ModuleName, but it won't have actually loaded at least in the environment (if I run the same code in the environment it will load)

2b) 如果它被加载,并且它试图删除该模块,它会错误认为不存在.

2b) if it is loaded, and it tries to remove the module, it will error that none exists.

# 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
}
}

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

I am of the opinion that though this is being ran in a session, the code block in the event is not associated with this specific environment.

推荐答案

以下是我的一些代码示例,它可以在文件夹中的某些内容发生更改时将文件夹复制到共享文件夹.这有点像我的小保管箱实现 :-)

Here is an example from some code I have that copies a folder to a shared folder any time something has changed in it. It's kinda my little dropbox implementation :-)

任何一种文件系统观察器事件类型,例如 Changed 发生时,Register-ObjectEvent-Action 参数中指定的代码代码> cmdlet 将触发.

Any time one of the file system watcher event types such as Changed occurs, the code specified in the -Action parameter of the Register-ObjectEvent cmdlet will fire.

在您的 -Action 代码中,您将使用 -Force 参数调用 Import-Module 以覆盖当前的记忆.

In your -Action code you would call Import-Module with the -Force parameter to overwrite the current one in memory.

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 }

这篇关于如何从一个开放的工作环境重新加载模块以影响另一个工作环境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆