SendMail Help in VB - vb.net

I developed a sendmail program for support which works great. What I am trying to do now is add a history page, which will show my users what support requests they have sent previously. I plan on use My.Settings to save the each email sent from my program.
Here is my code for the SendMail button which sends me mail:
If TextBox1.Text = "" Then
MsgBox("Please describe the issue you're having Bender, I'm not a mindreader!")
Exit Sub
Else
lblpleasewait.Visible = True
delay(2000)
Dim Recipients As New List(Of String)
Recipients.Add("johndoe#yahoo.com")
Dim FromEmailAddress As String = Recipients(0)
Dim Subject As String = "IT Help!"
Dim Body As String = TextBox1.Text
Dim UserName As String = My.Settings.txtboxUN
Dim Password As String = My.Settings.txtboxPW
Dim Port As Integer = My.Settings.txtboxSMTPPort
Dim Server As String = My.Settings.txtboxSMTP
Dim Attachments As New List(Of String)
MsgBox(SendEmail(Recipients, FromEmailAddress, Subject, Body, UserName, Password, Server, Port, Attachments))
lblpleasewait.Visible = False
TextBox1.Text = ""
TextBox1.Focus()
'This is where the beginning of my code is to send it to the history form.
Dim str(2) As String
Dim itm As ListViewItem
str(0) = Today + " - " + TimeOfDay
str(1) = Body
itm = New ListViewItem(str)
GTSMailHistory.ListView1.Items.Add(itm)
My.Settings.logDate = str(0)
My.Settings.logIssue = str(1)
My.Settings.Save()
End If
As you can from the above code, the last few lines is where I add the Body of the email and the time of day and add it to my listview I have on another form (GTSMailHistory).
My problem is this, that code above sending it over to the other form is saving, but is overwritten with each new email. Its basically not appending new emails to the list, just writing over the first.
The only code I have on the history form is on the LOAD function which is below:
Private Sub GTSMailHistory_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim str(2) As String
Dim itm As ListViewItem
str(0) = My.Settings.logDate
str(1) = My.Settings.logIssue
itm = New ListViewItem(str)
ListView1.Items.Add(itm)
End Sub

I can't leave comments yet so if someone could move this it'd help.
Are you recreating your GTSMailHistory object each pass instead of just once at startup?
Also when saving the date/body to My.Settings you are overwriting the existing values, do you not want these to be lists instead?
In response to your comment:
Joiner, i do want it to be a list. Can i save a listview to my.settings so it remains persistent upon next program launch?
You can use My.Settings to store variables of different types including lists.
In Visual Studio go to:
Project -> Properties -> Settings (Tab) -> Add a setting and its type (browse for more).
See here for an example.

Found sort of an answer. Not really want i want but will suffice right now. I can write this to a textfile and use streamreader to load it to listview.
The below code adds the body and date to listview:
Static i As Integer = 0
Dim newItem As New ListViewItem(Today + " - " + TimeOfDay) '// add text Item.
newItem.SubItems.Add(TextBox2.Text) '// add SubItem.
history.ListView1.Items.Add(newItem) '// add Item to ListView.
i += 1
The below code loads the saved textfile
ListView1.View = View.Details : ListView1.Columns.Add("Date") : ListView1.Columns.Add("Issue")
If IO.File.Exists(myCoolFile) Then '// check if file exists.
Dim myCoolFileLines() As String = IO.File.ReadAllLines(myCoolFile) '// load your file as a string array.
For Each line As String In myCoolFileLines '// loop thru array list.
Dim lineArray() As String = line.Split("#") '// separate by "#" character.
Dim newItem As New ListViewItem(lineArray(0)) '// add text Item.
newItem.SubItems.Add(lineArray(1)) '// add SubItem.
ListView1.Items.Add(newItem) '// add Item to ListView.
Next
End If
On form close it saves my entries:
Dim myWriter As New IO.StreamWriter(myCoolFile)
For Each myItem As ListViewItem In ListView1.Items
myWriter.WriteLine(myItem.Text & "#" & myItem.SubItems(1).Text) '// write Item and SubItem.
Next
myWriter.Close()

Related

VB.NET 2019 How to populate a Tag Property on a dynamic ToolstripmenuItem

I am struggling to populate a tag property on a dynamically created sub menu which I have created. I have a text file that contains a number of radio station names, BBC1, BBC2, BBC3 for example, as well as the associated stream addresses for said stations. I am able to pull in the names and apply it to the submenu. They appear fine. I can click on the submenus, and the sender() variable confirms the station names correctly. My problem is that I cannot get the Tag property for each sub menu/radio station, to store the stream address. The code gets the radio title cleans the code and inserts it into the RadioStreamsToolStripMenuItem.DropDownItems.Add(station_name) and all is fine. The code then gets the Stream address and inserts it here RadioStreamsToolStripMenuItem.Tag.ToString(). I can tell that it is wrong, but how do I go about ensuring the correct stream goes into the correct radio Tag property. Im very new to this so please be gentle, its just a little hobby.
'======================================================================
'Aquires Radio name and creates a dropdown sub menu within RadioStreams
'======================================================================
Do While (Not line Is Nothing)
If line.StartsWith("#") Then
station_name = Replace(line, "#", "")
Dim x = RadioStreamsToolStripMenuItem.DropDownItems.Add(station_name)
AddHandler x.Click, AddressOf ToolMenuItem_Click
'===================================================
'Aquires Radio Stream to add to the Tag property for each new station
'===================================================
ElseIf line.StartsWith("#") Then
Dim station_stream As String = Replace(line, "#", "")
'The following just checks if the data has gone into the correct place
For Each Myitem As ToolStripItem In RadioStreamsToolStripMenuItem.DropDownItems
If Myitem.Text = station_name Then
MsgBox("MyItems " & Myitem.ToString())
Me.Tag = station_stream
End If
Next
You could use a Dictionary to store the stations a stream addresses. Dictionary lookups are very fast.
I assumed from your code that your text file looks like this
#BBC1
#BBC1streamAddress
#BBC2
#BBC2streamAddress
#BBC3
#BBC3streamAddress
I looped through the lines of the file assigning the trimmed keys and values to the dictionary. Then looped through the dictionary filling the menu. When the user clicks a menu item we get the text of the item and search the dictionary for the correct stream address.
Private RadioDictionary As New Dictionary(Of String, String)
Private Sub OPCode()
Dim lines = File.ReadAllLines("Radio.txt")
For i = 0 To lines.Length - 1 Step 2
RadioDictionary.Add(lines(i).Trim("#"c), lines(i + 1).Trim("#"c))
Next
For Each item In RadioDictionary
Dim x = RadioStreamsToolStripMenuItem.DropDownItems.Add(item.Key)
AddHandler x.Click, AddressOf ToolMenuItem_Click
Next
End Sub
Private Sub ToolMenuItem_Click(sender As Object, e As EventArgs) Handles ToolMenuItem.Click
Dim station = DirectCast(sender, ToolStripDropDownItem).Text
Dim stream = RadioDictionary(station)
End Sub

new folders from a list, from a text file in vb.net

I want to be able to create new folders from a list that is stored in a text file.
The names are stored like
test1
test2
test3
so my code so far, loads the path to create the new folders, (which is the oldest folder in the given parent folder) stored in another text file "Foldercreation.txt"
then open the file with the names of the folders I want to create, "Folderstocreate.txt" and stores them all in filereader2.
but then when trying to create the folders for each line nothing happens.
My current code;
Dim fileReader, filereader2 As System.IO.StreamReader
Dim stringreader, parfolder As String
Dim path, foldername As List(Of String)
Dim count As Byte
If MsgBox("Are you sure you want to create these folders?,
Before clicking yes, make sure EVERYONE is out of paperport & you have entered the correct numbers.", MsgBoxStyle.YesNo, "WARNING!") = MsgBoxResult.Yes Then
If strnumbx.Text = "" Then
MsgBox("You have not entered a start number for the folders.", MsgBoxStyle.OkOnly, "Error")
End If
'Loads a text file at the given location, to read to.
fileReader = My.Computer.FileSystem.OpenTextFileReader("C:\Data\Test\Foldercreation.txt")
'Set stringreader as the read line from the file
stringreader = fileReader.ReadLine()
path = System.IO.Directory.GetDirectories(stringreader).ToList
path.Sort()
count = path.Count - 1
parfolder = path(count)
'System.IO.Directory.CreateDirectory(parfolder & "\test")
filereader2 = New StreamReader("C:\Data\Test\Folderstocreate.txt", True)
filereader2.ReadToEnd()
For Each line In filereader2.ReadToEnd()
System.IO.Directory.CreateDirectory(parfolder & fileReader.ReadToEnd(count - 1))
count = count + 1
Next
End If
fileReader.Close()
filereader2.Close()
This function would do it but you may want to put in some exception handling.
Directory.CreateDirectory will create all parent folders if they don't exist.
Private Sub CreateAllDirectories(ByVal strFileList As String)
Dim strDirectories As String() = File.ReadAllLines(strFileList)
For Each strDirectory As String In strDirectories
If Not Directory.Exists(strDirectory) Then
Directory.CreateDirectory(strDirectory)
End If
Next
End Sub

vb.net save listbox items empty lines

I want to save listbox items to a txt file while using savefiledialog
This is the code I'm using, it's working but it will put a new line between every item. And I'd like to save without those empty lines. If anyone could help, thanks!
My code:
If ListBox1.Items.Count > 0 Then
SaveFileDialog1.InitialDirectory = "C:/"
SaveFileDialog1.Title = "YOUR RESULTS"
SaveFileDialog1.FileName = Label4.Text
SaveFileDialog1.Filter = ("text files (*.txt) | *.txt")
SaveFileDialog1.ShowDialog()
Dim w As New IO.StreamWriter(SaveFileDialog1.FileName)
Dim i As Integer
For i = 0 To ListBox1.Items.Count - 1
w.WriteLine(ListBox1.Items(i).ToString)
Next
w.Close()
Else
MsgBox("There is nothing to save", MsgBoxStyle.Information)
End If
To remove spaces from the start of a string, use the default String.TrimStart() extension method, as follows:
w.WriteLine(ListBox1.Items(i).ToString.TrimStart)
To remove only spaces from the end, use the default String.TrimEnd()
extension method, and for remove both spaces from start and end of a string, use String.Trim()
Update
I suggest you to use a StringBuilder object as follows:
Dim sb As New StringBuilder
For Each lbItem As Object In ListBox1.Items
sb.Append(lbItem.ToString)
Next
File.WriteAllText(SaveFileDialog1.FileName, sb.ToString, Encoding.Default)

How to create .key file with specific text

I've been trying to make a program that is able to create a file with a .key extension, which contains a 5 line text.
It is fundamental to have 5 lines, otherwise it won't work.
I use
Dim filepath As String = TextBox1.Text + "\\rarreg.key"
Dim rarreg As New IO.StreamWriter(filepath, True)
rarreg.Write(String.Join(Environment.NewLine, hiddenTxt))
The hiddenTxt contains all the text needed and it's multilined.
However, when I click on the button to call this functions, it succesfully creates the file, but it comes empty.
Try this
' Add any initialization after the InitializeComponent() call.
Dim filepath As String = ""
Dim dialog As New SaveFileDialog
dialog.DefaultExt = "key"
dialog.FileName = "rarreg.key"
dialog.InitialDirectory = "c:\temp"
Dim results As DialogResult = dialog.ShowDialog()
If results <> Windows.Forms.DialogResult.Cancel Then
filepath = dialog.FileName
End If​

VB.NET + Add folders to treeview and files to listview

I want to create a simple printer manager to use in our Terminal server environment. Because of GPO restrictions, there are limits of what built-in functionality I can use. So I decided to try to write my own simple GUI to do that.
Now, the printers are distributed in a folder, with subfolders to categorize them. In each folder there are .lnk files to the actual printer on the printserver.
What I want to do is to populate a treeview with the folders, and the printers in a listview, based on which item is clicked on the treeview.
I've already managed to search for directories and to search the files for each item I've clicked. But I realized, why not use a collection or similar to do this during the startup of the form? That way, it'll be faster. Because right now, there's a small delay each time I click an item in the treeview. Because it scans for files each time.
How can I add the same to a collection and use that instead?
Here's my current code:
Public Sub populateTreeView(ByVal strPath As String)
Dim di As New IO.DirectoryInfo(strPath)
Dim diar1 As IO.DirectoryInfo() = di.GetDirectories()
Dim dra As IO.DirectoryInfo
For Each dra In diar1
ImageList1.Images.Add(GetSmallIcon(dra.FullName))
TreeView1.Nodes.Add("", dra.Name, nIndex)
nIndex = nIndex + 1
Next
End Sub
Private Sub TreeView1_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterSelect
ListView1.Clear()
nIndex = 0
Dim di As New IO.DirectoryInfo(strIniSettings & "\" & TreeView1.SelectedNode.Text)
Dim diar1 As IO.FileInfo() = di.GetFiles()
Dim dra As IO.FileInfo
For Each dra In diar1
Dim strName As String
strName = Replace(dra.Name, ".lnk", "")
ImageList2.Images.Add(GetLargeIcon(dra.FullName))
ListView1.Items.Add("", strName, nIndex)
nIndex = nIndex + 1
Next
End Sub
Notice the Imagelists? I also get the Icon for each item as well.
Since your data is not complex, a simple LookUp may be the right collection for you (or just a plain Dictionary).
Just query the printers once, and store it in a member variable, or just use the Tag property of the TreeNodes so store the file names.
In the example below, I'm using a simple Linq query to create a LookUp where the Key is the directory name (you could also just use full path to the directory), and the items are the file names.
You could then either query the collection by a given Key (the directory name), or use the Tag property.
LINQPad example:
Sub Main
' query printers once (just replace C:\test with your path)
' store the result in a member variable of your form
Dim printer = new DirectoryInfo("C:\test").GetDirectories() _
.SelectMany(Function(d) d.GetFiles()) _
.ToLookup(Function(f) f.Directory.Name, Function(f) f.Name)
' Or, using a Dictionary
' Dim printer = new DirectoryInfo("C:\test").GetDirectories() _
' .ToDictionary(Function(d) d.Name, Function(d) d.GetFiles().Select(Function(f) f.Name).ToList())
Dim l = new ListView() With {.Dock = DockStyle.Right}
Dim t = new TreeView() With {.Dock = DockStyle.Left}
AddHandler t.AfterSelect, Sub(s, e)
' This is your AfterSelect event handler
' The filenames are stored in the Tag of the TreeNode
' You could also use 'For Each p As String in printer(e.Node.Text)'
l.Items.Clear()
For Each p As String in e.Node.Tag
Dim item = l.Items.Add(p.Replace(".lnk", ""))
'TODO: Set Icon on item
Next
End Sub
' Populate TreeView once
For Each folder in printer
Dim fNode = t.Nodes.Add(folder.Key)
'TODO: Set Icon on fNode
' store the files in the Tag of the node.
' You don't have to, but it will make it easier
fNode.Tag = folder
Next
' Show test form
Dim w = new Form()
w.Controls.Add(t)
w.Controls.Add(l)
w.Show()
End Sub