【问题标题】:Loading assemblies & running as scheduled task not compatible?加载程序集并按计划任务运行不兼容?
【发布时间】:2019-10-29 09:35:17
【问题描述】:

我正在尝试构建一个由计划任务启动的消息传递系统,并最终允许我在触发软件更新作业之前向用户发送消息。

我的 UserMessage 脚本基本上可以工作...

class PxMessage {

    static [PxMessage] $instance
    static [windows.forms.notifyIcon] $balloon
    static [drawing.icon] $defaultIcon

    static [PxMessage] GetInstance($processID) {
        if ([PxMessage]::instance -eq $null) {
            [PxMessage]::instance = [PxMessage]::new()
            #[void][reflection.assembly]::LoadWithPartialName('Windows.Forms')

            [PxMessage]::balloon = [windows.forms.notifyIcon]::New()
            [PxMessage]::defaultIcon = [drawing.icon]::ExtractAssociatedIcon($(Get-Process -id:$processID | Select-Object -expandProperty:path))
        }
        return [PxMessage]::instance
    }

    [Void] SendMessage ([String]$title, [String]$message, [String]$messageIcon, [String]$icon) {
        if ($icon) {
            [PxMessage]::balloon.icon = [drawing.icon]::ExtractAssociatedIcon($icon) # must be a local path
        } else {
            [PxMessage]::balloon.icon = [PxMessage]::defaultIcon
        }
        [PxMessage]::balloon.balloonTipTitle = $title
        [PxMessage]::balloon.balloonTipText = $message
        [PxMessage]::balloon.balloonTipIcon = $messageIcon
        [PxMessage]::balloon.visible = $true 
        [PxMessage]::balloon.ShowBalloonTip(0)
        [void][PxMessage]::balloon.Dispose
    }
}

$message = [PxMessage]::GetInstance($pid)
$message.SendMessage('Title', 'Message', 'Info', 'C:\PxIcon.ico')

这在 ISE 中运行时有效,当我使用 & "\\Mac\iCloud Drive\Px Tools\Dev 4.0\#Spikes\ScheduledTasks\UserMessage.ps1" 从另一个脚本在控制台中运行它时有效。

但是,当我设置这样的计划任务时......

$runTime = (get-Date) + (New-TimeSpan -seconds:1)
$action = New-ScheduledTaskAction -execute:'powershell.exe' -argument:'-NonInteractive -NoLogo -NoProfile -noExit -executionPolicy Bypass -File "\\Mac\iCloud Drive\Px Tools\Dev 4.0\#Spikes\ScheduledTasks\UserMessage_class.ps1"'
$trigger = New-ScheduledTaskTrigger -once -at:$runTime
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -action:$action -trigger:$trigger -settings:$settings
Register-ScheduledTask -taskName:'Px Tools' -inputObject:$task

我收到错误 Unable to find type [Windows.Forms.NotifyIcon]. 是否存在与计划任务的交互导致加载程序集出现问题?

我知道[reflection.assembly]::LoadWithPartialName 已被弃用,我发现this 列出了一些选项。我试过了 [reflection.assembly]::LoadFrom("C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll"),结果相同。

【问题讨论】:

    标签: powershell scheduled-tasks


    【解决方案1】:

    load the assemblies是不是这样:

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    

    或者indicated here:

    Add-Type -AssemblyName System.Windows.Forms
    

    【讨论】:

    • 两种方法我都试过了。第一个抛出错误,第二个没有错误,但代码也不起作用。我想知道,如果我使用的是静态属性定义中的类型,但在加载所需的程序集之前,那将如何工作?
    • 你也可以using assembly system.drawing.
    • @js2010,如何做到这一点。我在静态声明之前和之后的类中以及在 GetInstance 方法中完全按照您的方式尝试了它,以代替我在该方法之前和开始时所拥有的。所有都标记为错误(红色下划线)。即使将它们放在脚本文件的顶部也不起作用(没有错误,但也没有气球提示),这不会导致类是自包含的,我认为这是可行的。
    • 这在 5.1 中适用于我:using assembly system.windows.forms; using namespace system.windows.forms; [messagebox]::show('hi')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 2017-05-28
    相关资源
    最近更新 更多