我已经读过这个问题,尽管它有很多来回,我尽力遵循建议,但仍然不确定如何解决这个问题。
我在
ScriptsToProcess
.ps1
文件中定义了多个类,如下所示:
问题是,当我将模块文件复制到干净状态的虚拟机并尝试使用 cmdlet 时,我收到一条错误消息,指出未找到类型,但如果我关闭并重新打开 PowerShell 或使用
Import-Module
和 -Force
参数然后一切都好。
我需要知道如何解决这个问题而不引入太多重复代码。
我正在使用 PowerShell 7.5
我不完全理解与VM相关的问题,但也许以下方法绕过问题:
将
class
定义为脚本模块 (*.psm1
) 的一部分,而不是通过模块的 *.ps1
清单条目加载到调用者作用域中的 ScriptsToProcess
文件。
本身,这使得您的类只能用于使用解析时
using module
语句导入模块的调用者。
但是,about_Classes帮助主题的使用类型加速器导出类部分描述了一个解决方法,它使您选择的类在所有作用域和运行空间中全局会话可用。
下面的示例代码演示了这种方法,但有以下注意事项:
与基于
using module
的方法一样,您将无法在给定会话中重新加载修改的 class
定义 - 而是启动一个新会话。
与基于
using module
的方法不同(您仍然可以选择与建议的方法组合),(可能是隐式的)导入器不得依赖 class
es 在解析时可用 .
class
暴露给其他运行空间,所以
classes
应使用
[NoRunspaceAffinity()
属性进行装饰,该属性在 v7.4+ 中可用仅有的。也就是说,只要仅使用 single 运行空间(默认运行空间),该方法就可以安全地在早期版本中使用。
remove导出的class
定义 (
Remove-Module
),但是,这不起作用(从 PowerShell 7.4.1 开始) ,因此在下面的代码中被省略。
*.psm1
内容:
# Since the quasi-exported class will be available *process-wide*
# and therefore also in *other runspaces*, be sure to define it with
# the [NoRunspaceAffinity()] attribute.
# Caveat: **v7.4+ only**
[NoRunspaceAffinity()]
class SomeClass { # Note: 'SomeClass' is both its .Name and .FullName.
[int] Get() { return 42 }
}
# Define the types to export with type accelerators.
$exportableTypes = @(
[SomeClass]
)
# Get the non-public TypeAccelerators class for defining new accelerators.
$typeAcceleratorsClass = [psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')
# Add type accelerators for every exportable type.
$existingTypeAccelerators = $typeAcceleratorsClass::Get
foreach ($type in $exportableTypes) {
# !! $TypeAcceleratorsClass::Add() quietly ignores attempts to redefine existing
# !! accelerators with different target types, so we check explicitly.
$existing = $existingTypeAccelerators[$type.FullName]
if ($null -ne $existing -and $existing -ne $type) {
throw "Unable to register type accelerator [$($type.FullName)], because it is already defined with a different type ([$existing])."
}
$typeAcceleratorsClass::Add($type.FullName, $type)
}
与此 *.psm1
关联的模块的任何(可能是隐式的)导入程序都将在运行时使用
[SomeClass]
类。