【问题标题】:How can I remove a FileTransferred event handler from a WinSCP Session object?如何从 WinSCP 会话对象中删除 FileTransferred 事件处理程序?
【发布时间】:2017-11-03 02:08:57
【问题描述】:

我为适合我需要的 WinSCP 模块制作了一个小型 PowerShell 包装脚本。 Like in the example for synchronizing local and remote folders 我的使用文件传输事件来记录会话事件。

$fileTransferedEvent = {Receive-FileTransferredEvent $_}
$session.add_FileTransferred($fileTransferedEvent)

该示例在完成后处理会话。我的逻辑保持会话打开,直到我选择完成它,以便我可以在其他 cmdlet 调用中使用相同的会话。

如果其他 cmdlet(甚至再次调用相同的 cmdlet)也使用 add_FileTransferred(),则会产生问题。再次添加事件,触发 X 次输出,其中 X 是调用方法的次数。

我找到了一个名为remove_FileTransferred()的合作伙伴方法,但我不知道如何使用它

Name                   MemberType Definition                                                           
----                   ---------- ----------                                                           
add_FileTransferred    Method     void add_FileTransferred(WinSCP.FileTransferredEventHandler value)   
remove_FileTransferred Method     void remove_FileTransferred(WinSCP.FileTransferredEventHandler value)

它们都接受相同的值,所以我想也许我可以将处理程序的定义传递给它,但这似乎不起作用,即$session.remove_FileTransferred($fileTransferedEvent) 没有完成这项工作。它也不会出错。

如何删除Winscp.Session 对象上的文件传输事件处理程序?

【问题讨论】:

    标签: powershell ftp winscp powershell-5.0 winscp-net


    【解决方案1】:

    这非常适合我:

    $fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
    $session.add_FileTransferred($fileTransferedEvent)
    $session.PutFiles("C:\test.txt", "/").Check()
    $session.remove_FileTransferred($fileTransferedEvent)
    $session.PutFiles("C:\test.txt", "/").Check()
    

    我明白了:

    Upload of C:\test.txt succeeded
    

    如果我不调用remove_FileTransferred,我会得到两次输出,正如预期的那样:

    Upload of C:\test.txt succeeded
    Upload of C:\test.txt succeeded
    

    请参阅Event handlers in PowerShell


    如果您多次添加相同的事件处理程序,则每次引发事件时都会调用该处理程序多次。如果要取消事件订阅,则必须以相同的次数删除处理程序。删除未(或不再)添加的处理程序是 noop。所有这些都是一般规则,不限于Session.FileTransferred 或 WinSCP .NET 程序集。

    例子:

    $fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
    $session.add_FileTransferred($fileTransferedEvent)
    $session.add_FileTransferred($fileTransferedEvent)
    
    Write-Host "two handlers:"
    $session.PutFiles("C:\test.txt", "/").Check()
    
    $session.remove_FileTransferred($fileTransferedEvent)
    Write-Host "one handler:"
    $session.PutFiles("C:\test.txt", "/").Check()
    
    $session.remove_FileTransferred($fileTransferedEvent)
    Write-Host "zero handlers:"
    $session.PutFiles("C:\test.txt", "/").Check()
    
    Write-Host "done"
    

    这会让你:

    two handlers:
    Upload of C:\test.txt succeeded
    Upload of C:\test.txt succeeded
    one handler:
    Upload of C:\test.txt succeeded
    zero handlers:
    done
    

    虽然,可能不太明显的是,以下两个代码 sn-ps 并不相同:

    $fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
    $session.add_FileTransferred($fileTransferedEvent)
    $fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
    $session.add_FileTransferred($fileTransferedEvent)
    
    $fileTransferedEvent = { Write-Host "Upload of $($_.FileName) succeeded" }
    $session.add_FileTransferred($fileTransferedEvent)
    $session.add_FileTransferred($fileTransferedEvent)
    

    第一个 sn-p 添加两个 distinct 事件处理程序,而后者添加两个 相同 处理程序。

    在第一个 sn-p 之后,你不能通过调用这个来删除两个注册:

    $session.remove_FileTransferred($fileTransferedEvent)
    $session.remove_FileTransferred($fileTransferedEvent)
    

    第一个“删除”将删除最后/第二个添加的处理程序。第二个“删除”不会做任何事情,因为它试图删除已经取消的同一个处理程序。由于您没有对第一个处理程序的任何引用,因此您不能再取消它。

    【讨论】:

    • 就是这样。我在定义处理程序的地方创建了一个函数。会话被传入,并且每次都添加一个“新”处理程序。这正是我想要的。谢谢。我孤立了处理程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    相关资源
    最近更新 更多