This is an old revision of the document!
Using WinSCP .NET Assembly from Perl (ActivePerl)
This feature is available only in the latest beta release.
This article is based on ActivePerl Perl distribution.
Advertisement
Installing and Registering for COM
First, you need to install the WinSCP .NET assembly and register it for COM.
Using from Perl (ActivePerl)
You use WinSCP .NET assembly from Perl as any other COM library (In this example we are using Win32::OLE
package).
Though there are some less known techniques and peculiarities that you may need to use, which are described in following sections.
Accessing Enumeration Values
As Perl accesses COM classes via IDispatch
, it does not make use of type library, hence it does not have direct access to constants defined there, like Protocol.Sftp
for instance.
One of several ways to use these constants is to use Win32::OLE::Const->Load
method. It returns hash array of all enum members from type library, with keys like <type>_<member>
, e.g. Protocol.Sftp
becomes Protocol_Sftp
.
Following example shows how to access Protocol_Sftp
constant:
use Win32::OLE; use Win32::OLE::Const; use Win32::OLE::Variant; Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE); my $session = Win32::OLE->new('WinSCP.Session'); my $consts = Win32::OLE::Const->Load($session); my $sessionOptions = Win32::OLE->new('WinSCP.SessionOptions'); $sessionOptions->{'Protocol'} = $consts->{'Protocol_Sftp'}; $sessionOptions->{'HostName'} = 'example.com'; $sessionOptions->{'UserName'} = 'user'; $sessionOptions->{'Password'} = 'mypassword'; $sessionOptions->{'SshHostKey'} = 'ssh-rsa 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx';
Advertisement
Event Handlers
The Session
class exposes several events.
If you need to make use of these events:
- Define event handling function that takes arguments
object
,event
and array of event arguments; - Make it handle the event you need by comparing value of
event
argument against names of theSession
events (e.g.FileTransferred
); - Associate the event handling function with an instance of
Session
class usingWin32::OLE->WithEvents
mehod.
See following code snippet:
use feature qw(switch); # in order to use given sub session_Events() { my ($obj, $event, @args) = @_; given ($event) { when ('FileTransferred') { my ($sender, $e) = @args; printf "%s => %s\n", ( $e->{'FileName'}, $e->{'Destination'} ); } } } my $session = Win32::OLE->new('WinSCP.Session'); Win32::OLE->WithEvents($session, \&session_Events);
Boolean Arguments
Some arguments of the assembly methods are of Boolean
type. They do not accept integer values 0
or 1
. Use Win32::OLE::Variant
instead, e.g. Variant(VT_BOOL, 1)
.
You can define constants TRUE
and FALSE
for use with the assembly:
use Win32::OLE::Variant; use constant { TRUE => Variant(VT_BOOL, 1), FALSE => Variant(VT_BOOL, 0) };
Example
This example is functionally equivalent to overall C# example for WinSCP .NET assembly.
Advertisement
use strict; use warnings; use Win32::OLE; use Win32::OLE::Const; use Win32::OLE::Variant; use constant { TRUE => Variant(VT_BOOL, 1), FALSE => Variant(VT_BOOL, 0) }; my $session = Win32::OLE->new('WinSCP.Session'); # Load constants my $consts = Win32::OLE::Const->Load($session); # Setup session options my $sessionOptions = Win32::OLE->new('WinSCP.SessionOptions'); $sessionOptions->{'Protocol'} = $consts->{'Protocol_Sftp'}; $sessionOptions->{'HostName'} = 'example.com'; $sessionOptions->{'UserName'} = 'user'; $sessionOptions->{'Password'} = 'mypassword'; $sessionOptions->{'SshHostKey'} = 'ssh-rsa 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx'; # Connect $session->Open($sessionOptions); # Upload files my $transferOptions = Win32::OLE->new('WinSCP.TransferOptions'); $transferOptions->{'TransferMode'} = $consts->{'TransferMode_Binary'}; my $transferResult = $session->PutFiles('d:\\toupload\\*', '/home/user/', FALSE, $transferOptions); # Throw on any error $transferResult->Check(); # Print results my $items = Win32::OLE::Enum->new($transferResult->{'Transfers'}); my $item; while (defined($item = $items->Next)) { print $item->{'FileName'} . "\n"; }