WINSCP

Started by stanl, April 06, 2016, 10:35:25 AM

Previous topic - Next topic

stanl

The tech support article below has code uploaded by Deana showing using the WB CLR to run WinSCP.

http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/dotNet/Third~Party~Components/WinScp+SFTP~using~WinSCP~dotNet~.txt

I have WinSCP .net installed and in the GAC - the following Powershell snippet works (fake data for actual FTP site and credentials)


try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "c:\winscp\WinSCPnet.dll"


    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::ftp
        HostName = "ftp.com"
        UserName = "user"
        Password = "password"
        #SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
    }

    $session = New-Object WinSCP.Session
    $session.ExecutablePath = "c:\winscp\winscp.exe"

    try
    {
        # Connect
        $session.Open($sessionOptions)
       

        # Upload files
        $transferOptions = New-Object WinSCP.TransferOptions
        $transferOptions.TransferMode = [WinSCP.TransferMode]::Ascii  #Binary

        $transferResult = $session.PutFiles("y:\dbs\templates\aux_20160315.csv", "/AUXHours", $False, $transferOptions)

        # Throw on any error
        $transferResult.Check()

        # Print results
        foreach ($transfer in $transferResult.Transfers)
        {
            Write-Host ("Upload of {0} succeeded" -f $transfer.FileName)
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }

    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}


I get an error when using the WB Script (attached jpg).  I feel it has to do with this line:
Code (WINBATCH) Select

ObjectClrOption ( 'use', 'WinSCP, Version=1.0.7.3446, Culture=neutral' )


and I have not referenced the correct version. At one point I had a script to return the version info from the GAC, but unable to locate it. Need a plan b

td

If it's a versioning issue maybe try right-clicking on the assembly's dll in the GAC to check the file version (not the product version) and use that for your version in the 'use' option.  Or you could just move the assembly dll to an 'appbase' and  skip the version in the 'use' option that loads the assembly.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Thanks Tony;

I confirmed the version for the dll. The real problem appears to be the winscp.exe - which gives an error about a missing manifest. That error has been brought up on sites like StackOverflow and there didn't seem to be a definitive answer as that issue seems related to 64 vs 32 bit.

On the plus side, I confirmed that the FTP site I needed a script for does not require SFTP, so I was able to quickly compile a script with pure WB and it worked perfectly. So you may relegate this thread to a more theoretical discussion.

td

Theoretically then if the problem is the WinSCP.exe, it would explain why your PS script worked and WinBatch script erred.  The PS script does not attempt to directly load the WinSCP.exe as a dotNet assembly. 

The solution may simply be to not attempt to load WinSCP.exe as a dotNet assembly.   There is no reason why the WinSCPnet.dll cannot access the functionality it needs from the exe by methods other than those employed by the CLR.  For example, it could simply use pinvoke/interop to access the 'native' exports.

I don't have the time to fiddle with it and view the products source code but I did grab the latest version of WinSCP and ran the old Tech Support script after commenting out every thing except the ObjectClrOption for the WinSCPnet assembly and the ObjectClrNew calls.  All the class object were created just fine and that lends some credence to the notion that it is not necessary to use  ObjectClrOption on the executable in the latest version of the product.     
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Happened to stumble across an old WinSCP CLR hosting script while working on something else.  Still works just fine with the latest and greatest WinSCP dll and exe as long as the line with the ObjectClrOption call that attempts to load WinSCP.exe  is commented out.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on April 07, 2016, 10:47:44 AM
Happened to stumble across and old WinSCP CLR hosting script while working on something else.  Still works just fine with the latest and greatest WinSCP dll and exe as long as the line with the ObjectClrOption call that attempts to load the WinSCP.exe script is commented out.

That is correct. I found a one liner PS script to uncover the version info and when I ran it against the exe, it failed saying it wasn't an assembly. Probably should comment out the 'use' line in the script portion of the tech db article I first mentioned, pay it forward for the next user.

Sorry the thread got protracted... just my situation is (1) compile script on home laptop (2) copy onto work PC via usb (3) execute w/out ability to debug until I get home, then repeat 1 and 2.... >:(

td

Quote
That is correct. I found a one liner PS script to uncover the version info and when I ran it against the exe, it failed saying it wasn't an assembly. Probably should comment out the 'use' line in the script portion of the tech db article I first mentioned, pay it forward for the next user.

Actually, it needs more work than that.  The ObjectClrOption('use','WinSCPnet', Version=1.1.6.4433, Culture=neutral') has syntax coloring that indicates that it is a comment but the semicolon is missing. This is likely a copy and paste error.    The version information is unnecessary because the CLR will find the assembly using the 'appbase' path.    Also the WinSCP.SessionOptions class has a property that allows the call to specify a separate location for the exe, "ExecutablePath", when the assembly and exe are not co-located, ie, the exe is in "Program Files' and the assembly is in the script's directory or the GAC.

In short, the use of ObjectClrOption ( 'use', 'WinSCP') vs ObjectClrOption('use','WinSCPnet') depends on which version of WinSCP you are using.  But you just cannot use both.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on April 07, 2016, 12:24:46 PM
Also the WinSCP.SessionOptions class has a property that allows the call to specify a separate location for the exe, "ExecutablePath", when the assembly and exe are not co-located, ie, the exe is in "Program Files' and the assembly is in the script's directory or the GAC.


Yes, that property is part of the PS code I posted. Again, I hope this helps the next user.

td

Quote from: stanl on April 08, 2016, 04:01:23 AM

Yes, that property is part of the PS code I posted. Again, I hope this helps the next user.

Wouldn't know.  Never really looked at it other than to note which assembly or assemblies it loaded.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade