How to make textfile to save in program directory in Visual Studio - vb.net

As i have abandoned the array approach to the problem, i need to know how to make listbox to save in textfile always in program's directory so it can be used/accessed to populate a different listbox, any ideas? Below is my code.
SaveFileDialog1.Filter = "Text files (.txt)|.txt"
SaveFileDialog1.ShowDialog()
If SaveFileDialog1.FileName <> "" Then
Using SW As New IO.StreamWriter(SaveFileDialog1.FileName, False)
For Each itm As String In Me.ListBox1.Items
SW.WriteLine(itm)
Next
End Using
End If

A little bit of research on your part would've helped you understand what you are trying to accomplish better.
How do I get Program Data directory? My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData
How do I Write multiple lines to file? File.WriteAllLines()
How do I Read multiple lines from a file? File.ReadAllLines()
Once you understand the basics you can easily put them together
Create two List boxes, and one button on your WinForm:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.
'Get the Program Data Directory (This is hidden by default by the OS.)
Dim strPath As String = My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData
Dim fileName As String = "myFile.txt"
Dim fullPath = Path.Combine(strPath, fileName)
Dim data As String() = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}
'Save the items to ListBox1 First
For Each item As String In data
ListBox1.Items.Add(item)
Next
'Now write the items to the textfile, line by line.
File.WriteAllLines(fullPath, data)
'Read all lines we just saved and load them onto an array of strings.
Dim tempAllLines() As String = File.ReadAllLines(fullPath)
'Display each on ListBox2 by iterating the array.
For Each line As String In tempAllLines
ListBox2.Items.Add(line)
Next
End Sub
Here, I created this form so you can get an idea of what i'm referring to.

You can get the path to the current executable's folder like this:
folderPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
However, that will only work if the executable is a .NET assembly. Otherwise, you could use the first argument in the command line (which is the full executable file path), like this:
folderPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()(0))
If, on the other hand, you want to get the path of the current assembly (which may be different than the executable that loaded it) you could do this:
folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
Or, if you want to just get the current directory, you could use this:
folderPath = Directory.GetCurrentDirectory()
Once you have the folder path, you can add the file name to it with Path.Combine, like this:
filePath = Path.Combine(folderPath, fileName)
However, it's not recommended that you write data directly to the program's running path, since the user may not have permission to write to that folder. Using the program data folder would certainly be better, but even that can be risky:
folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyAppName")
The recommended place to store data from .NET apps is Isolated Storage.

Related

How to keep the content of ListBox in Vb.net

If i want to keep the content of a textbox i do this
TextBox1.Text = TextBox1.Text & Something
Is there a way to do the same thing for the content of Items of a Listbox?
In my RichTextBox3 i have the list of files in the C:\Work directory
I Tried this code but it's giving me The content of the last line (It's not adding the lines before)
Do Until number = RichTextBox3.Lines.Length
Dim directory = "C:\Work\" & RichTextBox3.Lines(number)
Dim files() As System.IO.FileInfo
Dim dirinfo As New System.IO.DirectoryInfo(directory)
files = dirinfo.GetFiles("*", IO.SearchOption.AllDirectories)
For Each file In files
ListBox1.Items.Add(file)
Next
number = number + 1
Loop
Help is appreciated
Thanks to all of you
I'm not sure that this will address your stated problem but there's a serious issue with that code and I need to provide a long code snippet to address it and that won't be readable in a comment.
The Lines property of a TextBox or RichTextBox is not "live" data, i.e. it doesn't refer to an array stored within the object. Each time you get the property, a new array is created. You are getting RichTextBox3.Lines twice for every iteration of that loop, so that's obviously wrong. You also should not be adding items to the ListBox one by one like that. You should be creating a list of all the items first, then adding them all with a single call to AddRange:
Dim files As New List(Of FileInfo)
For Each line In RichTextBox3.Lines
Dim folderPath = Path.Combine("C:\Work", line)
Dim folder As New DirectoryInfo(folderPath)
files.AddRange(folder.GetFiles("*", SearchOption.AllDirectories))
Next
ListBox1.Items.AddRange(files.ToArray())
If that code doesn't work as expected, you can debug it and view the contents of files at various stages to make sure that you are getting the files you expect. It might also be worth testing folder.Exists before calling GetFiles, unless you're absolutely sure that each line in the RichTextBox represents an existing folder.
This will do what you want.
number = 0
ListBox1.items.clear()
Do Until number = RichTextBox3.Lines.Length
Dim directory = "C:\Work\" & RichTextBox3.Lines(number)
Dim files() As System.IO.FileInfo
Dim dirinfo As New System.IO.DirectoryInfo(directory)
files = dirinfo.GetFiles("*", IO.SearchOption.AllDirectories)
For Each file In files
ListBox1.Items.Add(file)
Next
number = number + 1
Loop

Moving Files From One Folder To Another VB.Net

I am trying to figure out how to move 5 files
settings.txt
settings2.txt
settings3.txt
settings4.txt
settings5.txt
from one folder to another.
Although I know what the file names will be and what folder Name they will be in, I don't know where that folder will be on the Users computer.
My thought process is to use a FolderBrowseDialog which the user can browse to where the Folder is, and then when OK is pressed, it will perform the File copy to the destination folder, overwriting what's there.
This is what I have so far.
Dim FolderPath As String
Dim result As Windows.Forms.DialogResult = FolderBrowserImport.ShowDialog()
If result = DialogResult.OK Then
FolderPath = FolderBrowserImport.SelectedPath & "\"
My.Computer.FileSystem.CopyFile(
FolderPath & "settings.txt", "c:\test\settings.txt", overwrite:=True)
ElseIf result = DialogResult.Cancel Then
Exit Sub
End If
Rather than run this 5 times, is there a way where it can copy all 5 files at once
I know why IdleMind recommended the approach they did, but it would probably make for a bit more readable code to just list out the file names:
Imports System.IO
...
Dim result = FolderBrowserImport.ShowDialog()
If result <> DialogResult.OK Then Exit Sub
For Each s as String in {"settings.txt", "settings2.txt", "settings3.txt", "settings4.txt", "settings5.txt" }
File.Copy( _
Path.Combine(FolderBrowserImport.SelectedPath, s), _
Path.Combine("c:\test", s), _
True _
)
Next s
You can swap this fixed array out for a list that VB prepares for you:
For Each s as String in Directory.GetFiles(FolderBrowserImport.SelectedPath, "settings*.txt", SearchOption.TopDirectoryOnly)
File.Copy(s, Path.Combine("c:\test", Path.GetFilename(s)), True)
Next s
Tips:
It's usually cleaner to do a If bad Then Exit Sub than a If good Then (big load of indented code) End If - test all your known failure conditions at the start and exit the sub if anything fails, rather than arranging a huge amount of indented code
Use Path.Combine to combine path and filenames etc; it knows how to deal with stray \ characters
Use Imports to import namespaces rather than spelling everything out all the time (System.Windows.Forms.DialogResult - a winforms app will probably have all the necessaries imported already in the partial class so you can just say DialogResult. If you get a red wiggly line, point to the adjacent lightbulb and choose to import System.WIndows/Forms etc)
Once you have the selected folder, use a For loop to build up the names of the files you're looking for. Use System.IO.File.Exists() to see if they are there. Use System.IO.Path.Combine() to properly combine your folders with the filenames.
Here's a full example (without exception handling, which should be added):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If FolderBrowserImport.ShowDialog() = DialogResult.OK Then
Dim FolderPath As String = FolderBrowserImport.SelectedPath
For i As Integer = 1 To 5
Dim FileName As String = "settings" & If(i = 1, "", i) & ".txt"
Dim FullPathFileName As String = System.IO.Path.Combine(FolderPath, FileName)
If System.IO.File.Exists(FullPathFileName) Then
Dim DestinationFullPathFileName = System.IO.Path.Combine("c:\test", FileName)
My.Computer.FileSystem.CopyFile(FullPathFileName, DestinationFullPathFileName, True)
Else
' possibly do something in here if the file does not exist?
MessageBox.Show("File not found: " & FullPathFileName)
End If
Next
End If
End Sub

vb check for specific file type in dir and perform code

I'm trying to make a program that checks for specific file type in a directory, then executes a code if there are any files of that type found.
I'm assuming something like this:
For Each foundFile As String In
My.Computer.FileSystem.GetFiles(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
(If any found files are, for example, "txt" files, then display their content.)
Next
Thanks in advance.
You can use Directory.GetFiles or Directory.EnumerateFiles with a parameter for the extension-filter:
Dim directoryPath = My.Computer.FileSystem.SpecialDirectories.MyDocuments
Dim allTxtFiles = Directory.EnumerateFiles(directoryPath, ".txt")
For each file As String In allTxtFiles
Console.WriteLine(file)
Next
The difference between both methods is that the first returns a String(), so loads all into memory immediately whereas the second returns a "query". If you want to use LINQ it's better to use EnumerateFiles, f.e. if you want to take the first 10 files:
Dim firstTenFiles As List(Of String) = allTxtFiles.Take(10).ToList()
Dim di As DirectoryInfo = New DirectoryInfo(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
For Each fi In di.GetFiles("*.txt")
Dim content As String = My.Computer.FileSystem.ReadAllText(fi.FullName)
Console.WriteLine(fi.Name)
Next

How to Access a txt file in a Folder created inside a VB project

I'm creating a VB project for Quiz App (in VS 2013). So I have some preset questions which are inside the project (I have created a folder inside my project and added a text file).
My question is how can I read and write contents to that file? Or if not is there any way to copy that txt file to Documents/MyAppname when installing the app so that I can edit it from that location?
In the example below I am focusing on accessing files one folder under the executable folder, not in another folder else wheres. Files are read if they exists and then depending on the first character on each line upper or lower case the line then save data back to the same file. Of course there are many ways to work with files, this is but one.
The following, created in the project folder in Solution Explorer a folder named Files, add to text files, textfile1.txt and textfile2.txt. Place several non empty lines in each with each line starting with a character. Each textfile, set in properties under solution explorer Copy to Output Directory to "Copy if newer".
Hopefully this is in tune with what you want. It may or may not work as expected via ClickOnce as I don't use ClickOnce to validate this.
In a form, one button with the following code.
Public Class Form1
Private TextFilePath As String =
IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "Files")
Private TextFiles As New List(Of String) From
{
"TextFile1.txt",
"TextFile2.txt",
"TextFile3.txt"
}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileName As String = ""
' loop thru each file
For Each fileBaseName As String In TextFiles
FileName = IO.Path.Combine(TextFilePath, fileBaseName)
' only access file if it exist currently
If IO.File.Exists(FileName) Then
' read file into string array
Dim contents As String() = IO.File.ReadAllLines(FileName)
' upper or lower case line based on first char.
' this means you can flip flop on each click on the button
For x As Integer = 0 To contents.Count - 1
If Char.IsUpper(CChar(contents(x))) Then
contents(x) = contents(x).ToLower
Else
contents(x) = contents(x).ToUpper
End If
Next
' save changes, being pesstimistic so we use a try-catch
Try
IO.File.WriteAllLines(FileName, contents)
Catch ex As Exception
Console.WriteLine("Attempted to save {0} failed. Error: {1}",
FileName,
ex.Message)
End Try
Else
Console.WriteLine("Does not exists {0}", FileName)
End If
Next
End Sub
End Class
This may help you
Dim objStreamReader As StreamReader
Dim strLine As String
'Pass the file path and the file name to the StreamReader constructor.
objStreamReader = New StreamReader("C:\Boot.ini")
'Read the first line of text.
strLine = objStreamReader.ReadLine
'Continue to read until you reach the end of the file.
Do While Not strLine Is Nothing
'Write the line to the Console window.
Console.WriteLine(strLine)
'Read the next line.
strLine = objStreamReader.ReadLine
Loop
'Close the file.
objStreamReader.Close()
Console.ReadLine()
You can also check this link.

how do I put contents of C: into an array?

Am learning arrays at the moment and I have the below piece of code that goes through drive C: and displays the files in in a list box.
I want to try and expand it to use array.sort so that it gets the files, puts them into an array, and then I can sort by filename or file size. I have been rattling my brain over this - as to how do I put the files into an array.
Would like an explanation if possible as more interested in learning it rather than the answer.
Thanks!
Private Sub btnclick_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnclick.Click
Call Clearlist()
Dim strFilesinfo As System.IO.FileInfo
Dim strlength As Double = 0
Dim strname As String = ""
For Each strFiles As String In My.Computer.FileSystem.GetFiles("c:\")
strFilesinfo = My.Computer.FileSystem.GetFileInfo(strFiles)
strlength = strFilesinfo.Length
strname = strFilesinfo.Name
lstData.Items.Add(strname & " " & strlength.ToString("N0"))
Next
End Sub
End Class
To allow the data to be sortable, you'd need to be displaying something that could treat that information separately (i.e. a class or structure). You might also find that a different type of control, such as a DataGridView might be easier to get to grips with.
The .Net framework does define an interface, IBindingList which collections can implement to show that they report, amongst other things, sorting.
I'm providing this as a sample for learning purposes but it should not be used as-is. Getting every file from the entire C:\ should not be done like this. Aside from the performance issues there are windows security limitations that won't actually let you do this.
The FileList being populated here is getting just the TopDirectoryOnly. If you change that input to "AllDirectories" it will get all the subdirectories but it will fail as I stated before.
Dim path As String = "C:\"
Dim dir As New System.IO.DirectoryInfo(path)
Dim fileList = dir.GetFiles("*.*", IO.SearchOption.TopDirectoryOnly)
Dim fileSort = (From file In fileList _
Order By file.Name _
Select file.Name, file.Length).ToList
For Each file In fileSort
With file
lstData.Items.Add(String.Format("{0} {1}", .Name, .Length.ToString("N0")))
End With
Next file
Just change the Order By in the LINQ query to change how the sorting is done. There are many other ways to do the sorting but LINQ will handle it for you with very little code.