【问题标题】:Powershell add type in class in PSM1Powershell在PSM1的类中添加类型
【发布时间】:2020-09-19 13:31:02
【问题描述】:

在 PS1 中,这是可行的

class pxInitFailureMessage {
    static [void] Send ([int32]$processID, [String]$title, [string]$message) {
        Add-Type -AssemblyName:System.Windows.Forms
        Add-Type -AssemblyName:System.Drawing
        $balloonTip = New-Object System.Windows.Forms.NotifyIcon
        $balloonTip.icon = [system.drawing.icon]::ExtractAssociatedIcon($(Get-Process -id:$processID | Select-Object -expandProperty:Path))
        $balloonTip.balloonTipIcon = 'Error'
        $balloonTip.balloonTipTitle = $title
        $balloonTip.balloonTipText = $message
        $balloonTip.visible = $true 
        $balloonTip.ShowBalloonTip(0)
        $balloonTip.Dispose
    }
}
[pxInitFailureMessage]::Send($pid, 'Title', 'Message is just some extra text')

但是,将该类移动到 library.PSM1 文件中,并在 PS1 中

Using module '\\Mac\iCloud Drive\Px Tools 4.#\Dev 4.0\#Spikes\Windows7\library.psm1'
[pxInitFailureMessage]::Send($pid, 'Title', 'Message is just some extra text')

它在 ISE 中有效,但在从快捷方式运行时不能在控制台中。我得到Unable to find type [system.drawing.icon].

显然第一个 Add-Type 有效,我在 New-Object 上没有错误。那么为什么第二种加载失败呢?我还尝试将两个 Add-Type 行移出类,并移入模块文件的根目录,结果相同。起作用的是将这些行添加到 PS1,在using module(必须是第一个非标记行)和调用之间。那行得通,但是你没有一个自包含的类,这似乎有点糟糕。我在这里误会了什么?

如何创建一个使用 .NET 类型的自包含类并从模块文件中使用它?

【问题讨论】:

  • 您检查过 MSDN 库吗? docs.microsoft.com/de-de/powershell/module/… ?特别是 -RequiredAssemblies 部分处理您的问题
  • @user3898488 基于此,我尝试了Get-Module Microsoft.PowerShell.Diagnostics -List | Format-List -Property *,它返回了预期的信息。但是Get-Module System.Drawing.Icon -List | Format-List -Property *Get-Module System.Drawing -List | Format-List -Property * 什么也没返回。也就是说,当我通过 PS 深入研究 .NET 时,我希望这将是一个有用的链接。所以哇!
  • 如果没人知道答案,我可以稍后再看看
  • 它在 ISE 中有效,因为所需的程序集已经加载。将类定义粘贴到普通的 PS 控制台会引发相同的错误(没有实际使用类,仅类定义会引发错误)。换句话说,这不是ps1/psm1的问题。 I also tried moving the two Add-Type lines out of the class, and into the root of the module file, with the same result 当命令包含 class 时,PowerShell 首先评估(解析)它们。所以你需要先以某种方式加载程序集...
  • 是的,我现在意识到根本问题是我要求我的班级走出自身,以及包含它的模块文件,以获取有关完全不同进程的图标信息。哑的。如果我在主脚本中将图标分配给它所属的变量,并将其传递给类,那么一切都会正常工作,并且拥有using assembly System.Drawing 是有道理的,因为那是我需要和使用它的地方。所以,即使我最初的方法奏效了,它仍然是一个糟糕的解决方案。

标签: powershell add-type


【解决方案1】:

对于任何有兴趣的人,我想出的解决方案如下。在 library.PSM1 我有...

class pxInitFailureMessage {
    static [void] Send ([int32]$processID, [String]$title, [string]$message, [System.Drawing.Icon]$icon) {
        Add-Type -AssemblyName:System.Windows.Forms
        $balloonTip = New-Object System.Windows.Forms.NotifyIcon
        $balloonTip.icon = $icon
        $balloonTip.balloonTipIcon = 'Error'
        $balloonTip.balloonTipTitle = $title
        $balloonTip.balloonTipText = $message
        $balloonTip.visible = $true 
        $balloonTip.ShowBalloonTip(0)
        $balloonTip.Dispose
    }
}

在我的脚本中,我有...

using assembly System.Drawing
Using module '.\library.psm1'

$processIcon = [system.drawing.icon]::ExtractAssociatedIcon($(Get-Process -id:$pID | Select-Object -expandProperty:Path))

[pxInitFailureMessage]::Send($pid, 'Title', 'Message is just some extra text', $processIcon)

关键是该类现在是自包含的,并且遵循为该类提供所需的一切的良好实践,因此它不必向外寻找。我可以很容易地使用我自己的 ICO 文件作为图标,就像这样......

$processIcon = [system.drawing.icon]::New('\\Mac\iCloud Drive\Px Tools 4.#\Dev 4.0\Px_Resources\PxIcon.ico')

在此示例中再次使用文字路径。

所以,我今天学到了一件事。呜呜呜。

【讨论】:

    猜你喜欢
    • 2017-07-05
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多