Differences

This shows you the differences between the selected revisions of the page.

2009-05-26 2010-07-01
wording (martin) no summary (goldberg)
Line 237: Line 237:
</code> </code>
 +Modified the above example to be a more robust vb.net function implementation:
 +<code>
 +Imports System
 +Imports System.IO
 +Imports System.Diagnostics
 +Imports System.Xml
 +Imports System.Xml.XPath
 +Imports System.Configuration.ConfigurationManager
 +
 +Public Class SFTP
 +    ' SFTP support, built on WinSCP
 +    ' AF Goldberg, July 2010
 +    Public Shared Function PutSFTP(ByRef filename As String, ByRef remotehost As String, ByRef username As String, ByRef password As String, _
 +                          Optional ByVal outfilename As String = Nothing, Optional ByVal output As String = Nothing,
 +                          Optional ByRef errmsg As String = Nothing) As Boolean
 +
 +        ' Run hidden WinSCP process
 +        Dim winscp As Process = New Process()
 +        Dim logname As String = Path.ChangeExtension(Path.GetTempFileName, "xml")
 +        With winscp.StartInfo
 +            ' SFTPExecutable needs to be defined in app.config to point to winscp.com
 +            Try
 +                .FileName = AppSettings("SFTPExecutable")
 +                If .FileName Is Nothing OrElse .FileName.Length = 0 Then Throw (New Exception("from PutSFTP: SFTPExecutable not set in config file."))
 +            Catch ex As Exception
 +                errmsg = ex.Message
 +                Return False
 +            End Try
 +            .Arguments = "/log=" + logname
 +            .UseShellExecute = False
 +            .RedirectStandardInput = True
 +            .RedirectStandardOutput = True
 +            .CreateNoWindow = True
 +        End With
 +        Try
 +            winscp.Start()
 +        Catch ex As Exception
 +            errmsg = "from PutSFTP:  Could not run the WinSCP executable " & winscp.StartInfo.FileName & Environment.NewLine & ex.Message
 +            Return False
 +        End Try
 +
 +        ' Feed in the scripting commands
 +        With winscp.StandardInput
 +            .WriteLine("option batch abort")
 +            .WriteLine("option confirm off")
 +            .WriteLine("open sftp://" & username & ":" & password & "@" & remotehost)
 +            If outfilename Is Nothing Then .WriteLine("put " & filename) Else .WriteLine("put " & filename & " """ & outfilename & """")
 +            .Close()
 +        End With
 +        If Not output Is Nothing Then output = winscp.StandardOutput.ReadToEnd()
 +
 +        ' Wait until WinSCP finishes
 +        winscp.WaitForExit()
 +
 +        ' Parse and interpret the XML log
 +        ' (Note that in case of fatal failure the log file may not exist at all)
 +        If Not File.Exists(logname) Then
 +            errmsg = "from PutSFTP:  The WinSCP executable appears to have crashed."
 +            Return False
 +        End If
 +
 +        Dim log As XPathDocument = New XPathDocument(logname)
 +        Dim ns As XmlNamespaceManager = New XmlNamespaceManager(New NameTable())
 +        ns.AddNamespace("w", "http://winscp.net/schema/session/1.0")
 +        Dim nav As XPathNavigator = log.CreateNavigator()
 +
 +        ' Success (0) or error?
 +        Dim status As Boolean = (winscp.ExitCode = 0)
 +        If Not status Then
 +            errmsg = "from PutSFTP:  There was an error transferring " & filename & "."
 +            ' See if there are any messages associated with the error
 +            For Each message As XPathNavigator In nav.Select("//w:message", ns)
 +                errmsg &= Environment.NewLine & message.Value
 +            Next message
 +        End If
 +
 +        Try
 +            My.Computer.FileSystem.DeleteFile(logname)
 +        Catch ex As Exception
 +            ' at least we tried to clean up
 +        End Try
 +
 +        Return status
 +    End Function
 +End Class
 +</code>