每次执行脚本时重新加载PowerShell模块
我在PowerShell模块文件中有一个类。(每次执行脚本时重新加载PowerShell模块,powershell,module,reload,Powershell,Module,Reload,我在PowerShell模块文件中有一个类。(A.psm1) 我还有一个使用该类的简单脚本 Using module C:\temp\A.psm1 $a = [A]::new() $a.printString() # prints 111 但是如果我从类中更改方法,例如,如图所示(在222上替换111) 如果我重新启动脚本,它仍然会打印111。只有重新启动PowerShell控制台,它才会打印新值。 如果我只在控制台中工作,我可以使用导入模块-强制执行命令。但它在脚本中不起作用 那么,有没
A.psm1
)
我还有一个使用该类的简单脚本
Using module C:\temp\A.psm1
$a = [A]::new()
$a.printString() # prints 111
但是如果我从类中更改方法,例如,如图所示(在222
上替换111
)
如果我重新启动脚本,它仍然会打印111
。只有重新启动PowerShell控制台,它才会打印新值。
如果我只在控制台中工作,我可以使用导入模块-强制执行
命令。但它在脚本中不起作用
那么,有没有一种方法可以在每次启动脚本时重新加载PowerShell模块,而无需重新启动控制台本身?据我所知,不幸的是,没有好的解决方案(从PowerShell 7.2开始):使用模块的
语句-也是从模块加载类es的先决条件-与强制重新加载模块的's-Force
开关没有等效项
解决方法:
# (Force-re)load the module and get a reference to the module.
# This does NOT give you access to the classes defined in the module.
$module = Import-Module C:\temp\A.psm1 -PassThru -Force
# Use the module reference to execute code *in the module's* context,
# where the class *is* defined, so you can obtain a reference to the
# [A] class (type) this way:
$classA = & $module { [A] }
$classA::new().printString()
- 如您所见,这需要修改源代码
- 如果将Visual Studio代码与PowerShell扩展一起使用,则可以避免此问题,如中所示
这种不幸的行为是一种错误,目前还没有真正的好的解决方案
根本原因有点复杂(行为持续5年以上的部分原因),但基本上是以下三方面的冲突:
- PowerShell中的模块生命周期管理(模块应可重新加载)
- .NET中的类型定义生命周期管理(在进程的生命周期内,类型永远不能“未定义”)
- 使用module
的方式提供了自定义类型的解析时间解析——简单地说,这不是一个特别成熟的特性
虽然不存在好的解决方案,但VSCode PowerShell扩展有一个配置选项,因此不存在问题:
设置后,可以使用以下工作流进行测试/调试:
在编辑器中打开脚本
通过调试器运行它(Shift+Ctrl+D
->runanddebug
)
观察printString()
打印111
对模块文件进行更改,然后保存
再次通过调试器运行脚本
观察printString()
现在打印新值
谢谢VS代码中的变通方法适合我的需要@非常高兴听到您的消息,不客气!FWIW这也是我用类开发模块的方法:-)我明白了:-)这很方便。
[void] printString() {
write-host 222
}
# (Force-re)load the module and get a reference to the module.
# This does NOT give you access to the classes defined in the module.
$module = Import-Module C:\temp\A.psm1 -PassThru -Force
# Use the module reference to execute code *in the module's* context,
# where the class *is* defined, so you can obtain a reference to the
# [A] class (type) this way:
$classA = & $module { [A] }
$classA::new().printString()
{
"powershell.debugging.createTemporaryIntegratedConsole": true
}