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