How to download file from SFTP in vb.net - vb.net

I am trying to use the classes in Renci.SshNet.Sftp to download a file from an SFTP server with VB.NET. Here is my code:
Using client As New SftpClient("server", "test", "test")
client.Connect()
Dim list As List(Of SftpFile) = CType(client.ListDirectory(""), List(Of SftpFile))
'------------------------
For Each sFile As SftpFile In list
Console.WriteLine(sFile.Name)
client.DownloadFile("path", ????)
Next
client.Disconnect()
End Using
With this code I can connect to the server and see the file, but I can't download it. I don't know how to call the DownloadFile method.

The second parameter of the DownloadFile method takes a stream. So, you just need to create a new FileStream to write the downloaded data to a new file, like this:
Using fs As New FileStream(localFilePath, FileMode.CreateNew, FileAccess.Write)
client.DownloadFile(serverFilePath, fs)
End Using

Related

how to read a CSV file as resource using TextFieldParser

I have a CSV file in my project resources which I want to read using FileIO.TextFieldParser
I tried Dim parser = new TextFieldParser(My.Resources.ArticlesCSV), but since TextFieldParser expects either a path (as string) or a stream, this is not working.
I guess one possibility is to convert the resource to a stream, but I cannot find how to do that...
What is the best way to get this working?
You can create a new instance of IO.StringReader which is of type TextReader that TextFieldParser will accept. Just pass your CSV file (Thanks to AndrewMorton)
Using strReader As New IO.StringReader(My.Resources.ArticlesCSV)
Using textparser As New TextFieldParser(strReader)
textparser.Delimiters = {","}
While Not textparser.EndOfData
Dim curRow = textparser.ReadFields()
' Do stuff
End While
End Using
End Using

Create a csv file and sftp it with out saving it to a local

My objective is to create a csv and sftp it without saving the file on the local machine using vb.net. Here is my create csv code:
Public Sub writeCSV()
Dim headers = (From header As DataGridViewColumn In
DataGridView1.Columns.Cast(Of DataGridViewColumn)() _
Select header.HeaderText).ToArray
Dim rows = From row As DataGridViewRow In DataGridView1.Rows.Cast(Of
DataGridViewRow)() _
Where Not row.IsNewRow _
Select Array.ConvertAll(row.Cells.Cast(Of
DataGridViewCell).ToArray, Function(c) If(c.Value IsNot Nothing,
c.Value.ToString, ""))
Using sw As New IO.StreamWriter("foo.csv")
sw.WriteLine(String.Join(",", headers))
For Each r In rows
sw.WriteLine(String.Join(",", r))
Next
End Using
'Process.Start("foo.csv")
'SFTP("foo.csv")
End Sub
Instead of starting and/or saving the process.. I'd like to write a sub that i can just sftp this foo.csv to a vendor's server. Is this possible? Also, the SFTP will need to use a key not a password.
Thanks in advance,
The following code uses edtFTPnet/PRO, which I co-developed, to do the task you need:
Sub SendCsvToSFTP(serverAddress As String, userName As String, password As String, fileName As String, csvText As String)
Using sftp As New EnterpriseDT.Net.Ftp.SecureFTPConnection
' Set up the SFTP connection
sftp.ServerAddress = serverAddress
sftp.Protocol = EnterpriseDT.Net.Ftp.FileTransferProtocol.SFTP
sftp.UserName = userName
sftp.Password = password
' Connect to the server
sftp.Connect()
Using csvStream As New MemoryStream()
Using csvWriter As New StreamWriter(csvStream)
csvWriter.Write(csvText) ' Write the CSV text to the writer
csvWriter.Flush() ' Make sure it's all written to the underlying stream
csvStream.Seek(0, SeekOrigin.Begin) ' Now wind back to the beginning before uploading
sftp.UploadStream(csvStream, fileName) ' Upload the stream
End Using
End Using
' Close the SFTP connection
sftp.Close()
End Using
End Sub
As you can see, it uses the SecureFTPConnection class to do the work. Note that edtFTPnet/PRO is a commercial product, but there's a 30-day trial available.
Create your CSV file as a memorystream then send that memorystream to your FTP Server.
Here is a link showing the sending of a memorystream to an FTP server: ASP.NET C# upload MemoryStream content via FTPwebRequest issue

Writing PDF in C:\ folder

I'm using .NET 4 on Windows 10.
I have a winform application written in vb.net which converts TIFF into PDF using PDFSharp api.
When I try to save the PDF into the C:\ folder there is no exception raised but nothing is written.
When I check if I have write access permission on folder C:\ , VB.NET tells me I do.
I'm using this chunk of code:
Private Function HasFolderWriteAccess(path As String) As Boolean
Try
Using inputstreamreader As New StreamReader(path)
inputstreamreader.Close()
End Using
Using inputStream As FileStream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.None)
inputStream.Close()
Return True
End Using
Catch ex As Exception
Return False
End Try
End Function
When I try to write a file using a StreamWriter, I face the same behavior:
Dim FILE_NAME As String = "C:\test2.txt"
Dim objWriter As New System.IO.StreamWriter(FILE_NAME)
objWriter.Write("Some text....")
objWriter.Close()
MessageBox.Show("Text written to file")
Is there some kind of magic happening in the Windows 10 C:\ folder that I don't know ?
Thanks for your replies.
Chris Dunaway's answer (in the comments) is right:
...look in this folder instead: C:\Users\User_name\‌​AppData\Local\Virtual‌​Store and see if your file is there. Windows doesn't allow writing of files to certain folders and silently redirects them to the virtual store...

Cannot write to a file after reading it with IO.StreamReader

I am making an encryption program that also functions as a notepad (CryptoMatic). There is a Open function with the following code:
Dim r As New StreamReader(filename)
Dim text As String = r.ReadToEnd
txtFileContents.text = text
r.Dispose()
r.Close()
Now there is the save and save as button
the save button checks if the file had been saved previously or not. If yes then I am trying to write to that file with the following code:
Dim myFileStream As New System.IO.FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None)
myFileStream.Lock(0, 100)
Dim myWriter As New System.IO.StreamWriter(myFileStream)
myWriter.WriteLine(text)
myWriter.Flush()
myWriter.Close()
myFileStream.Close()
myFileStream.Unlock(0, 100)
Now when i press the save button it gives the following error:
The process cannot access the file 'C:\Users\VisualTech\Documents\Visual Studio 2010\Projects\CryptoMatic Update\CryptoMatic Update\bin\Debug\text.txt' because it is being used by another process.
and the application stops, can anyone please help me?
I have tried your code above and have noticed two things:
You don't need a myFileStream.Lock call because you already open it
with FileShare.None
You can't call myFileStream.Unlock(0, 100) after the call to
myFileStream.Close()
So I have rewritten your code in this way.
Sub Main
Dim text = "This is a text to write in the stream"
Using myFileStream As New System.IO.FileStream("D:\temp\testlock.txt", FileMode.Append, FileAccess.Write, FileShare.None)
Using myWriter As New System.IO.StreamWriter(myFileStream)
myWriter.WriteLine(text)
End Using
End Using
End Sub

Using StreamReader to determine if File has been changed

I am curious. If I am using a combination of streamreader and streamwriter is there a way that I can have a stream written only if File X has been modified?
This code may not be constructed in the best way. It is attached to help in getting my questions accross.
sCommand = "whoami.exe >> C:\Desktop\Test.txt"
Using swrr As New StreamWriter(File.Open(ErrorLog, FileMode.OpenOrCreate))
For Each strUserName As String In strLines
Shell("cmd.exe /c" & sCommand, AppWinStyle.Hide, True, )
'command Cannot Execute, List Why and Move onto Next Command
Using sr As New StreamReader(File.Open(Test.txt, FileMode.OpenOrCreate))
If '''??File has been modifed??''''' Then swrr.WriteLine("PASS") Else swrr.WriteLine("FAIL")
End Using
Next
End Using
You can call File.ReadAllText(path) to get a string containing the text.
You can then compare the new string to the old one.
The correct way to read the output of a command is to use the Process class with RedirectStandardOutput.
You can then create a StreamReader around StandardOutput and call ReadToEnd().