【问题标题】:Custom Class in a script?脚本中的自定义类?
【发布时间】:2022-10-20 08:29:13
【问题描述】:

几年没有在 PowerShell 中编码,需要创建一个自定义类。浏览文档和一些博客和自定义类似乎很简单,但是每当我尝试从脚本加载一个简单的类时都会收到以下错误。

我试过运行一个测试脚本并用类点源文件:

The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
At C:\Temp\test.ps1:1 char:1
+ . ./classtest.ps1
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (:) [], FileLoadException
+ FullyQualifiedErrorId : System.IO.FileLoadException

直接用类调用文件会抛出同样的错误:

The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
At line:1 char:1
+ .\classtest.ps1
+ ~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (:) [], FileLoadException
+ FullyQualifiedErrorId : System.IO.FileLoadException

我放弃了我的整个课程,只是在网上抓取了一个超级简单的示例,如下所示(这是上述错误中当前 classtest.ps1 中的内容):

class student {
    [string]$FirstName
    [string]$LastName
}

如果我将该类粘贴到正在运行的 PowerShell 窗口中,它就可以正常工作。如果我将它放在一个文件中并尝试运行它,无论是直接调用文件还是尝试将文件点源到另一个脚本中,都会遇到相同的错误。

我在这里缺少一些愚蠢的简单的东西,如何在 PowerShell 脚本中使用类?

【问题讨论】:

  • 您是否使用与引发该错误的类名相同的类名 (Student)?
  • 我什至没有使用这个类。我确实有一个 ps1 文件,其中只有类定义,没有其他内容,甚至没有 cmets,当我运行脚本时它会抛出该错误。我只是希望它运行并且什么都不做,而不是抛出错误。
  • 我个人无法重现我使用的是 PS Core。这可能是 Win PS 的问题?
  • 相信这是您的会话受限语言模式的一部分。
  • 这可能看起来很奇怪,但是您能否创建一个类似New-Student 的函数来执行类似[Student]::new(...) 的功能,然后尝试加载该模块?据我所知,ps 在处理来自其他文件的类时很痛苦。

标签: powershell class


【解决方案1】:

弄清楚了。显然,自定义类库在 PowerShell 中很棘手。必须将其保存为标准文本文件,然后使用 Invoke-Expression 加载该文件以将其加载到我的 PowerShell 脚本中。之后,我可以完全按照我期望的方式使用它。

Invoke-Expression $([System.IO.File]::ReadAllText('C:Tempmyclass.txt'))
$NewStudent = [student]::new()
$NewStudent.FirstName = "bob"
$NewStudent.LastName = "Johson"
$NewStudent

有点烦人,但它确实有效。

【讨论】:

  • 确实有点奇怪,即使在 WinPS 中我也无法复制错误
【解决方案2】:

我同意Vivere 的评论,并且您需要将构造函数添加到类中,例如:

class student {
    [string]$FirstName
    [string]$LastName

    # create an empty student object
    student () {}

    # overload to create a student object with just the firstname
    student ([string]$FirstName) {
        $this.FirstName = $FirstName
    }

    # overload to create a student object with both first and lastname
    student ([string]$FirstName, [string]$LastName) {
        $this.FirstName = $FirstName
        $this.LastName  = $LastName
    }
}

像这样使用它:

$student1 = [student]::new()
$student2 = [student]::new('Name1')
$student3 = [student]::new('Someone', 'Else')

【讨论】:

  • 从班级的角度来看,是的,这是编写班级的更好方法。但这仍然不能解决在脚本中有自定义类的问题。通过您的示例或其他方式,我发现使该工作起作用的唯一方法是在下面对此的回答中使用 invoke-expression 行。我使用的那个愚蠢的简单类只是一个简单的例子来说明问题,你上面的类抛出了同样的错误。
  • @ user3246693 抱歉,但我只能想象您的问题与您用于保存 ps1 文件的文件编码有关。您是否检查了有问题的 .ps1 文件的编码,而不是使用记事本保存时的同一文件?
猜你喜欢
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 2021-07-20
  • 2019-12-01
  • 1970-01-01
  • 2017-12-22
  • 1970-01-01
相关资源
最近更新 更多