点源文件中的PowerShell点源-导入类

时间:2018-07-31 22:09:32

标签: powershell class powershell-module

我的项目的结构如下:

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类?

1 个答案:

答案 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 }}模块,使用相对于封闭脚本/模块位置的路径

    • 注意事项:从PowerShell Core 6.1.0-preview.4开始,有一个 bug 要求您将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