点源文件中的 PowerShell 点源 - 导入 类
PowerShell dot source within a dot sourced file - import classes
我的项目结构如下:
MyScript.ps1
classes\
Car.ps1
Tesla.ps1
汽车。ps1是特斯拉的基地class。ps1。我试图在特斯拉中这样定义特斯拉。ps1:
. "$PSScriptRoot\Car.ps1"
class Tesla : Car
{
}
MyScript.ps1 需要使用 Tesla class,但不需要知道它继承自 Car.
. "$PSScriptRoot\classes\Tesla.ps1"
$tesla = [Tesla]::new()
点源到 classes\Tesla.ps1
工作正常,但这个错误是从 Tesla 文件中抛出的:
Unable to find type [Car]
如果我在 MyScript 中以正确的顺序导入所有文件。ps1,它工作正常。示例:
. "$PSScriptRoot\classes\Car.ps1"
. "$PSScriptRoot\classes\Tesla.ps1"
$tesla = [Tesla]::new()
这很麻烦,尤其是随着复杂性的增加。我点采购不正确吗?有没有更好的方法来使用不在 PSModulePath 中的相对路径导入自定义 PowerShell class?
PetSerAl,像以前无数次一样,在对这个问题的简短评论中提供了关键指针:
由于您使用 classes,您必须使用 modules 并将它们导入using module
个语句 以便使用它们。
不幸的是,在撰写本文时,using module
仍未在 Get-Help about_Modules
中提及。
具体来说,为了在 class
定义中引用类型 (class),PowerShell 在解析时必须知道该类型.
在您的示例中,为了从 class Car
派生 Tesla
,当脚本为 时,PowerShell 必须知道类型 Car
parsed, before 执行开始 - 这就是为什么尝试导入Car
太迟 ] 通过点源其包含的脚本 (. "$PSScriptRoot\Car.ps1"
)
PowerShell 通过以下两种方式之一在解析时了解引用类型:
如果类型已经加载到当前 PowerShell 会话
通过 using module
语句引用定义了类型 (class) 的模块(请注意,还有一个 using assembly
语句用于加载类型来自 DLL,以及 using namespace
以启用仅通过名称引用类型)。
- 请注意,相关的
Import-Module
cmdlet 在这种情况下 不 起作用,因为它在 运行时 执行。
因此,正如 PetSerAl 所建议的那样:
将您的 classes 存储在 module 文件(独立 *.psm1
最简单情况下的文件)
然后使用using module
让Tesla
模块导入Car
模块和MyScript.ps1
脚本导入 Tesla
模块,使用 相对于封闭脚本/模块位置 .
的路径
- 警告:从 PowerShell Core 6.1.0-preview.4 开始,有一个 bug 要求您使用
\
作为相对路径中与 using module
的路径分隔符,即使在类 Unix 平台上,您通常会使用 /
.
MyScript.ps1
classes\
Car.psm1 # Note the .psm1 extension
Tesla.psm1 # Ditto
Car.psm1
:
class Car {}
Tesla.psm1
:
using module .\Car.psm1
class Tesla : Car {}
MyScript.ps1
:
using module .\classes\Tesla.psm1
$tesla = [Tesla]::new()
我的项目结构如下:
MyScript.ps1
classes\
Car.ps1
Tesla.ps1
汽车。ps1是特斯拉的基地class。ps1。我试图在特斯拉中这样定义特斯拉。ps1:
. "$PSScriptRoot\Car.ps1"
class Tesla : Car
{
}
MyScript.ps1 需要使用 Tesla class,但不需要知道它继承自 Car.
. "$PSScriptRoot\classes\Tesla.ps1"
$tesla = [Tesla]::new()
点源到 classes\Tesla.ps1
工作正常,但这个错误是从 Tesla 文件中抛出的:
Unable to find type [Car]
如果我在 MyScript 中以正确的顺序导入所有文件。ps1,它工作正常。示例:
. "$PSScriptRoot\classes\Car.ps1"
. "$PSScriptRoot\classes\Tesla.ps1"
$tesla = [Tesla]::new()
这很麻烦,尤其是随着复杂性的增加。我点采购不正确吗?有没有更好的方法来使用不在 PSModulePath 中的相对路径导入自定义 PowerShell class?
PetSerAl,像以前无数次一样,在对这个问题的简短评论中提供了关键指针:
由于您使用 classes,您必须使用 modules 并将它们导入using module
个语句 以便使用它们。
不幸的是,在撰写本文时,using module
仍未在 Get-Help about_Modules
中提及。
具体来说,为了在 class
定义中引用类型 (class),PowerShell 在解析时必须知道该类型.
在您的示例中,为了从 class Car
派生 Tesla
,当脚本为 时,PowerShell 必须知道类型 Car
parsed, before 执行开始 - 这就是为什么尝试导入Car
太迟 ] 通过点源其包含的脚本 (. "$PSScriptRoot\Car.ps1"
)
PowerShell 通过以下两种方式之一在解析时了解引用类型:
如果类型已经加载到当前 PowerShell 会话
通过
using module
语句引用定义了类型 (class) 的模块(请注意,还有一个using assembly
语句用于加载类型来自 DLL,以及using namespace
以启用仅通过名称引用类型)。- 请注意,相关的
Import-Module
cmdlet 在这种情况下 不 起作用,因为它在 运行时 执行。
- 请注意,相关的
因此,正如 PetSerAl 所建议的那样:
将您的 classes 存储在 module 文件(独立
*.psm1
最简单情况下的文件)然后使用
的路径using module
让Tesla
模块导入Car
模块和MyScript.ps1
脚本导入Tesla
模块,使用 相对于封闭脚本/模块位置 .- 警告:从 PowerShell Core 6.1.0-preview.4 开始,有一个 bug 要求您使用
\
作为相对路径中与using module
的路径分隔符,即使在类 Unix 平台上,您通常会使用/
.
- 警告:从 PowerShell Core 6.1.0-preview.4 开始,有一个 bug 要求您使用
MyScript.ps1
classes\
Car.psm1 # Note the .psm1 extension
Tesla.psm1 # Ditto
Car.psm1
:
class Car {}
Tesla.psm1
:
using module .\Car.psm1
class Tesla : Car {}
MyScript.ps1
:
using module .\classes\Tesla.psm1
$tesla = [Tesla]::new()