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> | ||