save variables to text file in vb.net - vb.net

As the title says I would like to save variables in a .txt file or something similar. (not XML)I've tried My.Settings and I'd like a more portable solution.
Format being something like this:
[config]<br>
StartPath=C:\Users<br>
FormColour=Black

From your question it looks you are thinking about sort of configuration (or similar) file looking like .ini file in older Windows versions. Such a file has one or more [sections] with multiple name=value pairs in each. If this is your case, please take a look here:
Reading/writing an INI file
If you are going to store data which suit multi-level structure better than simple flat structure you show in the sample and you do not like XML for this purpose, you might consider for example JSON (available natively in .NET since version 3.5) or YAML. Their libraries are freely available for .NET.

For a portable solution you can use my INI File Manager which is really easy and secure to use.
#Region " INI File Manager " ' By Elektro
Public Class INIFileManager
#Region " Members "
#Region " Properties "
''' <summary>
''' Indicates the initialization file path.
''' </summary>
Public Shared Property FilePath As String =
IO.Path.Combine(Application.StartupPath, Process.GetCurrentProcess().ProcessName & ".ini")
#End Region
#Region " Variables "
''' <summary>
''' Stores the initialization file content.
''' </summary>
Private Shared Content As New List(Of String)
''' <summary>
''' Stores the INI section names.
''' </summary>
Private Shared SectionNames As String() = {String.Empty}
''' <summary>
''' Indicates the start element index of a section name.
''' </summary>
Private Shared SectionStartIndex As Integer = -1
''' <summary>
''' Indicates the end element index of a section name.
''' </summary>
Private Shared SectionEndIndex As Integer = -1
''' <summary>
''' Stores a single sorted section block with their keys and values.
''' </summary>
Private Shared SortedSection As New List(Of String)
''' <summary>
''' Stores all the sorted section blocks with their keys and values.
''' </summary>
Private Shared SortedSections As New List(Of String)
''' <summary>
''' Indicates the INI element index that contains the Key and value.
''' </summary>
Private Shared KeyIndex As Integer = -1
''' <summary>
''' Indicates the culture to compare the strings.
''' </summary>
Private Shared ReadOnly CompareMode As StringComparison = StringComparison.InvariantCultureIgnoreCase
#End Region
#Region " Exceptions "
''' <summary>
''' Exception is thrown when a section name parameter has invalid format.
''' </summary>
Private Class SectionNameInvalidFormatException
Inherits Exception
Public Sub New()
MyBase.New("Section name parameter has invalid format." &
Environment.NewLine &
"The rigth syntax is: [SectionName]")
End Sub
Public Sub New(message As String)
MyBase.New(message)
End Sub
Public Sub New(message As String, inner As Exception)
MyBase.New(message, inner)
End Sub
End Class
#End Region
#End Region
#Region " Methods "
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub ReferenceEquals()
End Sub
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub Equals()
End Sub
Public Class [File]
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub ReferenceEquals()
End Sub
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub Equals()
End Sub
''' <summary>
''' Checks whether the initialization file exist.
''' </summary>
''' <returns>True if initialization file exist, otherwise False.</returns>
Public Shared Function Exist() As Boolean
Return IO.File.Exists(FilePath)
End Function
''' <summary>
''' Creates the initialization file.
''' If the file already exist it would be replaced.
''' </summary>
''' <param name="Encoding">The Text encoding to write the initialization file.</param>
''' <returns>True if the operation success, otherwise False.</returns>
Public Shared Function Create(Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
Try
IO.File.WriteAllText(FilePath,
String.Empty,
If(Encoding Is Nothing, System.Text.Encoding.Default, Encoding))
Catch ex As Exception
Throw
Return False
End Try
Return True
End Function
''' <summary>
''' Deletes the initialization file.
''' </summary>
''' <returns>True if the operation success, otherwise False.</returns>
Public Shared Function Delete() As Boolean
If Not [File].Exist Then Return False
Try
IO.File.Delete(FilePath)
Catch ex As Exception
Throw
Return False
End Try
Content = Nothing
Return True
End Function
''' <summary>
''' Returns the initialization file content.
''' </summary>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
Public Shared Function [Get](Optional ByVal Encoding As System.Text.Encoding = Nothing) As List(Of String)
Content = IO.File.ReadAllLines(FilePath,
If(Encoding Is Nothing, System.Text.Encoding.Default, Encoding)).ToList()
Return Content
End Function
''' <summary>
''' Sort the initialization file content by the Key names.
''' If the initialization file contains sections then the sections are sorted by their names also.
''' </summary>
''' <param name="RemoveEmptyLines">Remove empty lines.</param>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
''' <returns>True if the operation success, otherwise False.</returns>
Public Shared Function Sort(Optional ByVal RemoveEmptyLines As Boolean = False,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Not [File].Exist() Then Return False
[File].[Get](Encoding)
Select Case Section.Has(Encoding)
Case True ' initialization file contains at least one Section.
SortedSection.Clear()
SortedSections.Clear()
Section.GetNames(Encoding) ' Get the (sorted) section names
For Each name As String In SectionNames
SortedSection = Section.[Get](name, Encoding) ' Get the single section lines.
If RemoveEmptyLines Then ' Remove empty lines.
SortedSection = SortedSection.Where(Function(line) _
Not String.IsNullOrEmpty(line) AndAlso
Not String.IsNullOrWhiteSpace(line)).ToList
End If
SortedSection.Sort() ' Sort the single section keys.
SortedSections.Add(name) ' Add the section name to the sorted sections list.
SortedSections.AddRange(SortedSection) ' Add the single section to the sorted sections list.
Next name
Content = SortedSections
Case False ' initialization file doesn't contains any Section.
Content.Sort()
If RemoveEmptyLines Then
Content = Content.Where(Function(line) _
Not String.IsNullOrEmpty(line) AndAlso
Not String.IsNullOrWhiteSpace(line)).ToList
End If
End Select ' Section.Has()
' Save changes.
Return [File].Write(Content, Encoding)
End Function
''' <summary>
''' Writes a new initialization file with the specified text content..
''' </summary>
''' <param name="Content">Indicates the text content to write in the initialization file.</param>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
''' <returns>True if the operation success, otherwise False.</returns>
Public Shared Function Write(ByVal Content As List(Of String),
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
Try
IO.File.WriteAllLines(FilePath,
Content,
If(Encoding Is Nothing, System.Text.Encoding.Default, Encoding))
Catch ex As Exception
Throw
Return False
End Try
Return True
End Function
End Class
Public Class [Key]
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub ReferenceEquals()
End Sub
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub Equals()
End Sub
''' <summary>
''' Return a value indicating whether a key name exist or not.
''' </summary>
''' <param name="KeyName">Indicates the key name that contains the value to modify.</param>
''' <param name="SectionName">Indicates the Section name where to find the key name.</param>
''' <param name="Encoding">The Text encoding to write the initialization file.</param>
''' <returns>True if the key name exist, otherwise False.</returns>
Public Shared Function Exist(ByVal KeyName As String,
Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Not [File].Exist() Then Return False
[File].[Get](Encoding)
[Key].GetIndex(KeyName, SectionName)
Select Case SectionName Is Nothing
Case True
Return Convert.ToBoolean(Not KeyIndex)
Case Else
Return Convert.ToBoolean(Not (KeyIndex + SectionStartIndex))
End Select
End Function
''' <summary>
''' Set the value of an existing key name.
'''
''' If the initialization file doesn't exists, or else the Key doesn't exist,
''' or else the Section parameter is not specified and the key name doesn't exist;
''' then the 'key=value' is appended to the end of the initialization file.
'''
''' if the specified Section name exist but the Key name doesn't exist,
''' then the 'key=value' is appended to the end of the Section.
'''
''' </summary>
''' <param name="KeyName">Indicates the key name that contains the value to modify.</param>
''' <param name="Value">Indicates the new value.</param>
''' <param name="SectionName">Indicates the Section name where to find the key name.</param>
Public Shared Function [Set](ByVal KeyName As String,
ByVal Value As String,
Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Not [File].Exist() Then [File].Create()
[File].[Get](Encoding)
[Key].GetIndex(KeyName, SectionName)
' If KeyName is not found and indicated Section is found, then...
If KeyIndex = -1 AndAlso SectionEndIndex <> -1 Then
' If section EndIndex is the last line of file, then...
If SectionEndIndex = Content.Count Then
Content(Content.Count - 1) = Content(Content.Count - 1) &
Environment.NewLine &
String.Format("{0}={1}", KeyName, Value)
Else ' If not section EndIndex is the last line of file, then...
Content(SectionEndIndex) = String.Format("{0}={1}", KeyName, Value) &
Environment.NewLine &
Content(SectionEndIndex)
End If
' If KeyName is found then...
ElseIf KeyIndex <> -1 Then
Content(KeyIndex) = String.Format("{0}={1}", KeyName, Value)
' If KeyName is not found and Section parameter is passed. then...
ElseIf KeyIndex = -1 AndAlso SectionName IsNot Nothing Then
Content.Add(SectionName)
Content.Add(String.Format("{0}={1}", KeyName, Value))
' If KeyName is not found, then...
ElseIf KeyIndex = -1 Then
Content.Add(String.Format("{0}={1}", KeyName, Value))
End If
' Save changes.
Return [File].Write(Content, Encoding)
End Function
''' <summary>
''' Get the value of an existing key name.
''' If the initialization file or else the Key doesn't exist then a 'Nothing' object is returned.
''' </summary>
''' <param name="KeyName">Indicates the key name to retrieve their value.</param>
''' <param name="DefaultValue">Indicates a default value to return if the key name is not found.</param>
''' <param name="SectionName">Indicates the Section name where to find the key name.</param>
Public Shared Function [Get](ByVal KeyName As String,
Optional ByVal DefaultValue As Object = Nothing,
Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Object
If Not [File].Exist() Then Return DefaultValue
[File].[Get](Encoding)
[Key].GetIndex(KeyName, SectionName)
Select Case KeyIndex
Case Is <> -1 ' KeyName found.
Return Content(KeyIndex).Substring(Content(KeyIndex).IndexOf("=") + 1)
Case Else ' KeyName not found.
Return DefaultValue
End Select
End Function
''' <summary>
''' Returns the initialization file line index of the key name.
''' </summary>
''' <param name="KeyName">Indicates the Key name to retrieve their value.</param>
''' <param name="SectionName">Indicates the Section name where to find the key name.</param>
Private Shared Sub GetIndex(ByVal KeyName As String,
Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing)
If Content Is Nothing Then [File].Get(Encoding)
' Reset the INI index elements to negative values.
KeyIndex = -1
SectionStartIndex = -1
SectionEndIndex = -1
If SectionName IsNot Nothing AndAlso Not SectionName Like "[[]?*[]]" Then
Throw New SectionNameInvalidFormatException
Exit Sub
End If
' Locate the KeyName and set their element index.
' If the KeyName is not found then the value is set to "-1" to return an specified default value.
Select Case String.IsNullOrEmpty(SectionName)
Case True ' Any SectionName parameter is specified.
KeyIndex = Content.FindIndex(Function(line) line.StartsWith(String.Format("{0}=", KeyName),
StringComparison.InvariantCultureIgnoreCase))
Case False ' SectionName parameter is specified.
Select Case Section.Has(Encoding)
Case True ' INI contains at least one Section.
SectionStartIndex = Content.FindIndex(Function(line) line.Trim.Equals(SectionName.Trim, CompareMode))
If SectionStartIndex = -1 Then ' Section doesn't exist.
Exit Sub
End If
SectionEndIndex = Content.FindIndex(SectionStartIndex + 1, Function(line) line.Trim Like "[[]?*[]]")
If SectionEndIndex = -1 Then
' This fixes the value if the section is at the end of file.
SectionEndIndex = Content.Count
End If
KeyIndex = Content.FindIndex(SectionStartIndex, SectionEndIndex - SectionStartIndex,
Function(line) line.StartsWith(String.Format("{0}=", KeyName),
StringComparison.InvariantCultureIgnoreCase))
Case False ' INI doesn't contains Sections.
GetIndex(KeyName, , Encoding)
End Select ' Section.Has()
End Select ' String.IsNullOrEmpty(SectionName)
End Sub
''' <summary>
''' Remove an existing key name.
''' </summary>
''' <param name="KeyName">Indicates the key name to retrieve their value.</param>
''' <param name="SectionName">Indicates the Section name where to find the key name.</param>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
Public Shared Function Remove(ByVal KeyName As String,
Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Not [File].Exist() Then Return False
[File].[Get](Encoding)
[Key].GetIndex(KeyName, SectionName)
Select Case KeyIndex
Case Is <> -1 ' Key found.
' Remove the element containing the key name.
Content.RemoveAt(KeyIndex)
' Save changes.
Return [File].Write(Content, Encoding)
Case Else ' KeyName not found.
Return False
End Select
End Function
End Class
Public Class Section
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub ReferenceEquals()
End Sub
<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>
Private Shadows Sub Equals()
End Sub
''' <summary>
''' Adds a new section at bottom of the initialization file.
''' </summary>
''' <param name="SectionName">Indicates the Section name to add.</param>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
Public Shared Function Add(Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Not [File].Exist() Then [File].Create()
If Not SectionName Like "[[]?*[]]" Then
Throw New SectionNameInvalidFormatException
Exit Function
End If
[File].[Get](Encoding)
Select Case Section.GetNames(Encoding).Where(Function(line) line.Trim.Equals(SectionName.Trim, CompareMode)).Any
Case False ' Any of the existing Section names is equal to given section name.
' Add the new section name.
Content.Add(SectionName)
' Save changes.
Return [File].Write(Content, Encoding)
Case Else ' An existing Section name is equal to given section name.
Return False
End Select
End Function
''' <summary>
''' Returns all the keys and values of an existing Section Name.
''' </summary>
''' <param name="SectionName">Indicates the section name where to retrieve their keynames and values.</param>
Public Shared Function [Get](ByVal SectionName As String,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As List(Of String)
If Content Is Nothing Then [File].Get(Encoding)
SectionStartIndex = Content.FindIndex(Function(line) line.Trim.Equals(SectionName.Trim, CompareMode))
SectionEndIndex = Content.FindIndex(SectionStartIndex + 1, Function(line) line.Trim Like "[[]?*[]]")
If SectionEndIndex = -1 Then
SectionEndIndex = Content.Count ' This fixes the value if the section is at the end of file.
End If
Return Content.GetRange(SectionStartIndex, SectionEndIndex - SectionStartIndex).Skip(1).ToList
End Function
''' <summary>
''' Returns all the section names of the initialization file.
''' </summary>
Public Shared Function GetNames(Optional ByVal Encoding As System.Text.Encoding = Nothing) As String()
If Content Is Nothing Then [File].Get(Encoding)
' Get the Section names.
SectionNames = (From line In Content Where line.Trim Like "[[]?*[]]").ToArray
' Sort the Section names.
If SectionNames.Count <> 0 Then Array.Sort(SectionNames)
' Return the Section names.
Return SectionNames
End Function
''' <summary>
''' Gets a value indicating whether the initialization file contains at least one Section.
''' </summary>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
Public Shared Function Has(Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Content Is Nothing Then [File].Get(Encoding)
Return (From line In Content Where line.Trim Like "[[]?*[]]").Any()
End Function
''' <summary>
''' Removes an existing section with all of it's keys and values.
''' </summary>
''' <param name="SectionName">Indicates the Section name to remove with all of it's key/values.</param>
''' <param name="Encoding">The Text encoding to read the initialization file.</param>
Public Shared Function Remove(Optional ByVal SectionName As String = Nothing,
Optional ByVal Encoding As System.Text.Encoding = Nothing) As Boolean
If Not [File].Exist() Then Return False
If Not SectionName Like "[[]?*[]]" Then
Throw New SectionNameInvalidFormatException
Exit Function
End If
[File].[Get](Encoding)
Select Case [Section].GetNames(Encoding).Where(Function(line) line.Trim.Equals(SectionName.Trim, CompareMode)).Any
Case True ' An existing Section name is equal to given section name.
' Get the section StartIndex and EndIndex.
[Get](SectionName)
' Remove the section range index.
Content.RemoveRange(SectionStartIndex, SectionEndIndex - SectionStartIndex)
' Save changes.
Return [File].Write(Content, Encoding)
Case Else ' Any of the existing Section names is equal to given section name.
Return False
End Select
End Function
End Class
#End Region
End Class
#End Region
Here are some usage examples:
' Set the initialization file path.
'INIFileManager.FilePath = IO.Path.Combine(Application.StartupPath, "Config.ini")
' Create the initialization file.
'INIFileManager.File.Create()
' Check that the initialization file exist.
'MsgBox(INIFileManager.File.Exist)
' Writes a new entire initialization file with the specified text content.
'INIFileManager.File.Write(New List(Of String) From {"[Section Name 1]"})
' Set an existing value or append it at the enf of the initialization file.
'INIFileManager.Key.Set("KeyName1", "Value1")
' Set an existing value on a specific section or append them at the enf of the initialization file.
'INIFileManager.Key.Set("KeyName2", "Value2", "[Section Name 2]")
' Gets the value of the specified Key name,
'MsgBox(INIFileManager.Key.Get("KeyName1"))
' Gets the value of the specified Key name on the specified Section.
'MsgBox(INIFileManager.Key.Get("KeyName2", , "[Section Name 2]"))
' Gets the value of the specified Key name and returns a default value if the key name is not found.
'MsgBox(INIFileManager.Key.Get("KeyName0", "I'm a default value"))
' Gets the value of the specified Key name, and assign it to a control property.
'CheckBox1.Checked = CType(INIFileManager.Key.Get("KeyName1"), Boolean)
' Checks whether a Key exists.
'MsgBox(INIFileManager.Key.Exist("KeyName1"))
' Checks whether a Key exists on a specific section.
'MsgBox(INIFileManager.Key.Exist("KeyName2", "[First Section]"))
' Remove a key name.
'INIFileManager.Key.Remove("KeyName1")
' Remove a key name on the specified Section.
'INIFileManager.Key.Remove("KeyName2", "[Section Name 2]")
' Add a new section.
'INIFileManager.Section.Add("[Section Name 3]")
' Get the contents of a specific section.
'MsgBox(String.Join(Environment.NewLine, INIFileManager.Section.Get("[Section Name 1]")))
' Remove an existing section.
'INIFileManager.Section.Remove("[Section Name 2]")
'' Checks that the initialization file contains at least one section.
'MsgBox(INIFileManager.Section.Has())
'' Sort the initialization file (And remove empty lines).
'INIFileManager.File.Sort(True)
'' Gets the initialization file section names.
'MsgBox(String.Join(", ", INIFileManager.Section.GetNames()))
'' Gets the initialization file content.
'MsgBox(String.Join(Environment.NewLine, INIFileManager.File.Get()))
'' Delete the initialization file from disk.
'INIFileManager.File.Delete()

I suggest using an app.config instead. Using ConfigurationManager class, you can easily read/write multiple sections with little to no code. INI is going away as means of configuration, XML will probably stay for some time, I'd say stick to that. I recently wrote an article showing simple usage:
VB.NET - Reading and writing app.config # neolisk.com
Relevant parts are included here for convenience:
Imports System.Configuration
Imports System.Reflection
Public Class AppConfig
Private _config As Configuration
Private _settings As AppSettingsSection
Public Function GetProperty(propertyName As String) As String
Return _settings.Settings.Item(propertyName).Value
End Function
Public Sub SetProperty(propertyName As String, propertyValue As String)
_settings.Settings.Item(propertyName).Value = propertyValue
End Sub
Public Sub New()
_config = ConfigurationManager.OpenExeConfiguration(
Assembly.GetEntryAssembly().Location)
_settings = _config.AppSettings
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
_config.Save(ConfigurationSaveMode.Modified)
End Sub
End Class
Usage:
Dim _appConfig As New AppConfig
_appConfig.SetProperty(propertyName, propertyValue)
_appConfig.GetProperty(propertyName)
You will need to extend the above class to support multiple sections.

Related

GetFields Operator

I'm using a function to get the field data from a list. I need to know if the .GetFields operator will just return the fields, or if it will actually populate them with the data stored there? I think it's the latter after reading on msdn but I have no clue and I've never used these "test methods" before :(. Any help is appreciated! (or even if you can tell me how to do a test method would help!)
Here is code:
''' <summary>
''' This function will return all of the fields for a certain class as well as the data stored in them
''' </summary>
''' <param name="list"></param>
''' <returns></returns>
Public Shared Function GetFieldData(ByVal list As IList(Of Object)) As FieldInfo()
Dim fields() As FieldInfo = list.Single.GetType().GetFields()
Return fields
End Function
End Class
Here is code for creating newitems
''' <summary>
''' This function will create new Before and After objects
''' everything should be passed in as a IEnum
''' </summary>
''' <param name="Before"></param>
''' <param name="After"></param>
''' <returns></returns>
Function NewItem(Before As IEnumerable(Of Object), After As IEnumerable(Of Object))
If (Not ObjectsAreSameClass(Before, After)) Then 'If object classes are not the same, send an error message, else continue
'Pop error
Else
Dim BeforeFields() As FieldInfo = GetFieldData(Before)
Dim AfterFields() As FieldInfo = GetFieldData(After)
ObjectCounter += 1
'Now check and make sure the objects are not the same
If (BeforeFields.Equals(AfterFields)) Then
'Objects are the same so pop error?
End If
End If
Return Nothing
End Function
FieldInfo is information about the field, not including its value. To get the value you have to provide an instance of that object type. Here's an example that you can place on a form to see how it works:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim info() As FieldInfo = GetType(Form).GetFields(BindingFlags.NonPublic Or
BindingFlags.Instance)
For Each item As FieldInfo In info
Dim value As Object = item.GetValue(Me) ' Get the value from 'Me'
If Not IsNothing(value) Then
Debug.Print("{0} = {1}", item.Name, value.ToString())
Else
Debug.Print("{0} = Nothing", item.Name)
End If
Next
End Sub

How to read data from serial port in vb.net?

I made a class and there is this sub named SendUSSD, when this is called it sends a ussd code like *123# to a COM port where a gsm mobile is connected. This ussd is supposed to return the mobile balance.
If IsOpen = True Then 'checks if the port is open
SMSPort.WriteLine("AT+CUSD=1,""*123#""" vbCr) 'this sends the ussd code
Form1.TextBox2.Text = SMSPort.ReadLine().ToString() 'this shows the response
End If
Now the problem is sometimes I get the full response like "Your current balance is so and so". But, most of the time I get a part of the message like "Your curr". My guess is that it takes some time to get the response, so how do I make this Form1.TextBox2.Text = SMSPort.ReadLine().ToString() line wait until the last character which is a full-stop to appear and then execute the line?
im using this class to connect com ports.
'connect like this
Public comm As New CommunicationManager
comm.Parity = "None"
comm.StopBits = "One"
comm.DataBits = "8"
comm.BaudRate = "38400"
comm.PortName = comport_ismi
comm.OpenPort()
and the class
Imports System.Text
Imports System.Drawing
Imports System.IO.Ports
Imports System.Windows.Forms
Public Class CommunicationManager
#Region "Manager Enums"
''' <summary>
''' enumeration to hold our transmission types
''' </summary>
Public Enum TransmissionType
Text
Hex
End Enum
''' <summary>
''' enumeration to hold our message types
''' </summary>
Public Enum MessageType
Incoming
Outgoing
Normal
Warning
[Error]
End Enum
#End Region
#Region "Manager Variables"
'property variables
Private _baudRate As String = String.Empty
Private _parity As String = String.Empty
Private _stopBits As String = String.Empty
Private _dataBits As String = String.Empty
Private _portName As String = String.Empty
Private _transType As TransmissionType
Private _displayWindow As RichTextBox
'global manager variables
Private MessageColor As Color() = {Color.Blue, Color.Green, Color.Black, Color.Orange, Color.Red}
Private comPort As New SerialPort()
#End Region
#Region "Manager Properties"
''' <summary>
''' Property to hold the BaudRate
''' of our manager class
''' </summary>
Public Property BaudRate() As String
Get
Return _baudRate
End Get
Set(value As String)
_baudRate = value
End Set
End Property
''' <summary>
''' property to hold the Parity
''' of our manager class
''' </summary>
Public Property Parity() As String
Get
Return _parity
End Get
Set(value As String)
_parity = value
End Set
End Property
''' <summary>
''' property to hold the StopBits
''' of our manager class
''' </summary>
Public Property StopBits() As String
Get
Return _stopBits
End Get
Set(value As String)
_stopBits = value
End Set
End Property
''' <summary>
''' property to hold the DataBits
''' of our manager class
''' </summary>
Public Property DataBits() As String
Get
Return _dataBits
End Get
Set(value As String)
_dataBits = value
End Set
End Property
''' <summary>
''' property to hold the PortName
''' of our manager class
''' </summary>
Public Property PortName() As String
Get
Return _portName
End Get
Set(value As String)
_portName = value
End Set
End Property
''' <summary>
''' property to hold our TransmissionType
''' of our manager class
''' </summary>
Public Property CurrentTransmissionType() As TransmissionType
Get
Return _transType
End Get
Set(value As TransmissionType)
_transType = value
End Set
End Property
''' <summary>
''' property to hold our display window
''' value
''' </summary>
Public Property DisplayWindow() As RichTextBox
Get
Return _displayWindow
End Get
Set(value As RichTextBox)
_displayWindow = value
End Set
End Property
#End Region
#Region "Manager Constructors"
''' <summary>
''' Constructor to set the properties of our Manager Class
''' </summary>
''' <param name="baud">Desired BaudRate</param>
''' <param name="par">Desired Parity</param>
''' <param name="sBits">Desired StopBits</param>
''' <param name="dBits">Desired DataBits</param>
''' <param name="name">Desired PortName</param>
Public Sub New(baud As String, par As String, sBits As String, dBits As String, name As String, rtb As RichTextBox)
_baudRate = baud
_parity = par
_stopBits = sBits
_dataBits = dBits
_portName = name
_displayWindow = rtb
'now add an event handler
AddHandler comPort.DataReceived, New SerialDataReceivedEventHandler(AddressOf comPort_DataReceived)
End Sub
''' <summary>
''' Comstructor to set the properties of our
''' serial port communicator to nothing
''' </summary>
Public Sub New()
_baudRate = String.Empty
_parity = String.Empty
_stopBits = String.Empty
_dataBits = String.Empty
_portName = comport_ismi
_displayWindow = Nothing
'add event handler
AddHandler comPort.DataReceived, New SerialDataReceivedEventHandler(AddressOf comPort_DataReceived)
End Sub
#End Region
#Region "WriteData"
Public Sub WriteData(msg As String)
Select Case CurrentTransmissionType
Case TransmissionType.Text
'first make sure the port is open
'if its not open then open it
If Not (comPort.IsOpen = True) Then
comPort.Open()
End If
'send the message to the port
comPort.Write(msg)
'display the message
DisplayData(MessageType.Outgoing, msg & Convert.ToString(vbLf))
Exit Select
Case TransmissionType.Hex
Try
'convert the message to byte array
Dim newMsg As Byte() = HexToByte(msg)
'send the message to the port
comPort.Write(newMsg, 0, newMsg.Length)
'convert back to hex and display
DisplayData(MessageType.Outgoing, ByteToHex(newMsg) & Convert.ToString(vbLf))
Catch ex As FormatException
'display error message
DisplayData(MessageType.[Error], ex.Message)
Finally
_displayWindow.SelectAll()
End Try
Exit Select
Case Else
'first make sure the port is open
'if its not open then open it
If Not (comPort.IsOpen = True) Then
comPort.Open()
End If
'send the message to the port
comPort.Write(msg)
'display the message
DisplayData(MessageType.Outgoing, msg & Convert.ToString(vbLf))
Exit Select
End Select
End Sub
#End Region
#Region "HexToByte"
''' <summary>
''' method to convert hex string into a byte array
''' </summary>
''' <param name="msg">string to convert</param>
''' <returns>a byte array</returns>
Private Function HexToByte(msg As String) As Byte()
'remove any spaces from the string
msg = msg.Replace(" ", "")
'create a byte array the length of the
'divided by 2 (Hex is 2 characters in length)
Dim comBuffer As Byte() = New Byte(msg.Length / 2 - 1) {}
'loop through the length of the provided string
For i As Integer = 0 To msg.Length - 1 Step 2
'convert each set of 2 characters to a byte
'and add to the array
comBuffer(i / 2) = CByte(Convert.ToByte(msg.Substring(i, 2), 16))
Next
'return the array
Return comBuffer
End Function
#End Region
#Region "ByteToHex"
''' <summary>
''' method to convert a byte array into a hex string
''' </summary>
''' <param name="comByte">byte array to convert</param>
''' <returns>a hex string</returns>
Private Function ByteToHex(comByte As Byte()) As String
'create a new StringBuilder object
Dim builder As New StringBuilder(comByte.Length * 3)
'loop through each byte in the array
For Each data As Byte In comByte
'convert the byte to a string and add to the stringbuilder
builder.Append(Convert.ToString(data, 16).PadLeft(2, "0"c).PadRight(3, " "c))
Next
'return the converted value
Return builder.ToString().ToUpper()
End Function
#End Region
#Region "DisplayData"
''' <summary>
''' method to display the data to & from the port
''' on the screen
''' </summary>
''' <param name="type">MessageType of the message</param>
''' <param name="msg">Message to display</param>
<STAThread> _
Private Sub DisplayData(type As MessageType, msg As String)
'_displayWindow.Invoke(New EventHandler(Sub()
' _displayWindow.SelectedText = String.Empty
' _displayWindow.SelectionFont = New Font(_displayWindow.SelectionFont, FontStyle.Bold)
' _displayWindow.SelectionColor = MessageColor(CInt(type))
' _displayWindow.AppendText(msg)
' _displayWindow.ScrollToCaret()
' End Sub))
End Sub
#End Region
#Region "OpenPort"
Public Function OpenPort() As Boolean
Try
'first check if the port is already open
'if its open then close it
If comPort.IsOpen = True Then
comPort.Close()
End If
'set the properties of our SerialPort Object
comPort.BaudRate = Integer.Parse(_baudRate)
'BaudRate
comPort.DataBits = Integer.Parse(_dataBits)
'DataBits
comPort.StopBits = DirectCast([Enum].Parse(GetType(StopBits), _stopBits), StopBits)
'StopBits
comPort.Parity = DirectCast([Enum].Parse(GetType(Parity), _parity), Parity)
'Parity
comPort.PortName = _portName
'PortName
'now open the port
comPort.Open()
'display message
DisplayData(MessageType.Normal, "Port AÇILDI: " + DateTime.Now + vbLf)
'return true
Return True
Catch ex As Exception
DisplayData(MessageType.[Error], ex.Message)
Return False
End Try
End Function
#End Region
#Region "ClosePort"
Public Function ClosePort() As Boolean
Try
'first check if the port is already open
'if its open then close it
If comPort.IsOpen = True Then
comPort.Close()
End If
'display message
DisplayData(MessageType.Normal, "Port KAPANDI: " + DateTime.Now + vbLf)
'return true if port is closed
If comPort.IsOpen = False Then
Return True
End If
DisplayData(MessageType.Normal, "Kapatmada hata oluştu" & vbLf)
Return False
Catch ex As Exception
DisplayData(MessageType.[Error], ex.Message)
Return False
End Try
End Function
#End Region
#Region "SetParityValues"
Public Sub SetParityValues(obj As Object)
For Each str As String In [Enum].GetNames(GetType(Parity))
DirectCast(obj, ComboBox).Items.Add(str)
Next
End Sub
#End Region
#Region "SetStopBitValues"
Public Sub SetStopBitValues(obj As Object)
For Each str As String In [Enum].GetNames(GetType(StopBits))
DirectCast(obj, ComboBox).Items.Add(str)
Next
End Sub
#End Region
#Region "SetPortNameValues"
Public Sub SetPortNameValues(obj As Object)
For Each str As String In SerialPort.GetPortNames()
DirectCast(obj, ComboBox).Items.Add(str)
Next
End Sub
#End Region
#Region "comPort_DataReceived"
''' <summary>
''' method that will be called when theres data waiting in the buffer
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub comPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
'determine the mode the user selected (binary/string)
Select Case CurrentTransmissionType
'user chose string
Case TransmissionType.Text
'read data waiting in the buffer
Dim msg As String = comPort.ReadExisting()
'display the data to the user
DisplayData(MessageType.Incoming, msg)
' + "\n"); **************
Exit Select
'user chose binary
Case TransmissionType.Hex
'retrieve number of bytes in the buffer
Dim bytes As Integer = comPort.BytesToRead
'create a byte array to hold the awaiting data
Dim comBuffer As Byte() = New Byte(bytes - 1) {}
'read the data and store it
comPort.Read(comBuffer, 0, bytes)
'display the data to the user
DisplayData(MessageType.Incoming, ByteToHex(comBuffer))
' + "\n");
Exit Select
Case Else
'read data waiting in the buffer
Dim str As String = comPort.ReadExisting()
'display the data to the user
DisplayData(MessageType.Incoming, str)
' + "\n");
Exit Select
End Select
End Sub
#End Region
End Class
I guess you are using the DataReceived event, if so, you can just take the data and split it by the lastIndexOf(Enviroment.NewLine).
you will have two part the first one is a string with some amount of lines and the second one is a string that contain no more lines.
You can take the first part and split it by new line and even create a new event (LineReceived).
for the second part(the part after the lastIndexOf(Enviroment.NewLine)) of the data just concatenate it to the beginning of the data that will arrive the next time.
Try setting comm.Newline. Probably should be vbCR.

Check if FTP folder exists & if not then create it

I need a function to complete the following tasks:
Check if a folder exists (via its name) - if not then, create it.
Upload a file into the directory.
I tried with the following code, but it does not seem to check and create the directory:
Dim request As System.Net.FtpWebRequest = DirectCast(System.Net.FtpWebRequest.Create("HOST"), System.Net.FtpWebRequest)
request.Credentials = New System.Net.NetworkCredential("uase", "pass")
request.Method = System.Net.WebRequestMethods.Ftp.UploadFile
Dim file() As Byte = System.IO.File.ReadAllBytes("C:\Users\Nini\Desktop\10ebd0d.png")
Dim str As System.IO.Stream = request.GetRequestStream()
str.Write(file, 0, file.Length)
str.Close()
str.Dispose()
1.Check if a folder exists (via its name) - if not then, create it.
I'll admit that this is not the most robust or elegant solution but I was OK with something 'quick and dirty' for the occasional one-off need that I have for this.
Dim request As FtpWebRequest = FtpWebRequest.Create("ftp://myftp/parentfolder")
Dim creds As NetworkCredential = New NetworkCredential("user", "pwd")
request.Credentials = creds
Dim resp As FtpWebResponse = Nothing
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails
request.KeepAlive = True
Using resp
resp = request.GetResponse()
Dim sr As StreamReader = New StreamReader(resp.GetResponseStream(), System.Text.Encoding.ASCII)
Dim s As String = sr.ReadToEnd()
If Not s.Contains("newfolder") Then
request = FtpWebRequest.Create("ftp://myftp/parentfolder/newfolder")
request.Credentials = creds
request.Method = WebRequestMethods.Ftp.MakeDirectory
resp = request.GetResponse()
Console.WriteLine(resp.StatusCode & "Created")
Else
Console.WriteLine("Directory already exists")
End If
Console.ReadLine()
End Using
You could use the FTPClient library for .NET
I've did an helper Class to manage the library (but is easy as is provided there is no need to use an helper Class)
The methods that you're interested to are DirectoryExists, CreateDirectory, and UploadFile
This is an example usage:
Public Class Form1
Private WithEvents UploadClient As New System.Net.WebClient()
Private WithEvents DownloadClient As New System.Net.WebClient()
Private ftp As New FTP("ftpsite", "username", "password")
Private Sub Test() Handles MyBase.Shown
ftp.Connect()
ftp.CreateDirectory("/DirectoryName", True)
ftp.UploadFile(UploadClient, "C:\File.txt", "/DirectoryName/NewFile.txt", False)
ftp.DownloadFile(DownloadClient, "/DirectoryName/NewFile.txt", "c:\DownloadedFile.txt", True)
End Sub
Private Sub Client_UploadProgress(sender As System.Net.WebClient, e As System.Net.UploadProgressChangedEventArgs) _
Handles UploadClient.UploadProgressChanged
Label_Upload.Text = e.ProgressPercentage & "%"
End Sub
Private Sub Client_UploadCompleted(sender As System.Net.WebClient, e As System.Net.UploadFileCompletedEventArgs) _
Handles UploadClient.UploadFileCompleted
Label_UploadCompleted.Text = e.Result.ToString
End Sub
Private Sub Client_DownloadProgress(sender As System.Net.WebClient, e As System.Net.DownloadProgressChangedEventArgs) _
Handles DownloadClient.DownloadProgressChanged
Label_Download.Text = e.ProgressPercentage & "%"
End Sub
Private Sub Client_DownloadCompleted(sender As System.Net.WebClient, e As System.ComponentModel.AsyncCompletedEventArgs) _
Handles DownloadClient.DownloadFileCompleted
Label_DownloadCompleted.Text = "Done!"
End Sub
End Class
The Helper Class:
Imports System.Net
Imports System.Net.FtpClient
Imports System.Net.FtpClient.Extensions
#Region " FTPClient Helper "
' [ FTPClient Helper ]
'
' // By Elektro
Public Class FTP
#Region " Variables "
Private conn As New FtpClient
''' <summary>
''' The FTP site.
''' </summary>
Private Property host As String = String.Empty
''' <summary>
''' The user name.
''' </summary>
Private Property user As String = String.Empty
''' <summary>
''' The user password.
''' </summary>
Private Property pass As String = String.Empty
' Friend m_reset As New ManualResetEvent(False) ' Use it for CallBacks
#End Region
#Region " Constructor "
''' <summary>
''' .
''' </summary>
''' <param name="host">Indicates the ftp site.</param>
''' <param name="user">Indicates the username.</param>
''' <param name="pass">Indicates the password.</param>
Public Sub New(ByVal host As String,
ByVal user As String,
ByVal pass As String)
If Not host.ToLower.StartsWith("ftp://") Then
Me.host = "ftp://" & host
Else
Me.host = host
End If
If Me.host.Last = "/" Then
Me.host = Me.host.Remove(Me.host.Length - 1)
End If
Me.user = user
Me.pass = pass
With conn
.Host = If(host.Last = "/", host.Remove(host.Length - 1), host)
.Credentials = New NetworkCredential(Me.user, Me.pass)
End With
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Connects to server.
''' </summary>
Public Sub Connect()
conn.Connect()
End Sub
''' <summary>
''' Disconnects from server.
''' </summary>
Public Sub Disconnect()
conn.Disconnect()
End Sub
''' <summary>
''' Creates a directory on server.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
''' <param name="force">Try to force all non-existant pieces of the path to be created.</param>
Public Sub CreateDirectory(ByVal directorypath As String, ByVal force As Boolean)
conn.CreateDirectory(directorypath, force)
End Sub
''' <summary>
''' Creates a directory on server.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
''' <param name="force">Try to force all non-existant pieces of the path to be created.</param>
''' <param name="FtpListOption">Options that dictate how a list is performed ans what information is gathered.</param>
Public Sub DeleteDirectory(ByVal directorypath As String,
ByVal force As Boolean,
Optional ByVal FtpListOption As FtpListOption =
FtpListOption.AllFiles Or FtpListOption.ForceList)
' Remove the directory and all objects beneath it. The last parameter
' forces System.Net.FtpClient to use LIST -a for getting a list of objects
' beneath the specified directory.
conn.DeleteDirectory(directorypath, force, FtpListOption)
End Sub
''' <summary>
''' Deletes a file on server.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Sub DeleteFile(ByVal filepath As String)
conn.DeleteFile(filepath)
End Sub
''' <summary>
''' Checks if a directory exist on server.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
Public Function DirectoryExists(ByVal directorypath As String) As Boolean
Return conn.DirectoryExists(directorypath)
End Function
''' <summary>
''' Executes a command on server.
''' </summary>
''' <param name="command">Indicates the command to execute on the server.</param>
''' <returns>Returns an object containing the server reply information.</returns>
Public Function Execute(ByVal command As String) As FtpReply
Return (InlineAssignHelper(New FtpReply, conn.Execute(command)))
End Function
''' <summary>
''' Tries to execute a command on server.
''' </summary>
''' <param name="command">Indicates the command to execute on the server.</param>
''' <returns>Returns TRUE if command execution successfull, otherwise returns False.</returns>
Public Function TryExecute(ByVal command As String) As Boolean
Dim reply As FtpReply = Nothing
Return (InlineAssignHelper(reply, conn.Execute(command))).Success
End Function
''' <summary>
''' Checks if a file exist on server.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
''' <param name="FtpListOption">Options that dictate how a list is performed ans what information is gathered.</param>
Public Function FileExists(ByVal filepath As String,
Optional ByVal FtpListOption As FtpListOption =
FtpListOption.AllFiles Or FtpListOption.ForceList) As Boolean
' The last parameter forces System.Net.FtpClient to use LIST -a
' for getting a list of objects in the parent directory.
Return conn.FileExists(filepath, FtpListOption)
End Function
''' <summary>
''' Retrieves a checksum of the given file
''' using a checksumming method that the server supports, if any.
''' The algorithm used goes in this order:
''' 1. HASH command (server preferred algorithm).
''' 2. MD5 / XMD5 commands
''' 3. XSHA1 command
''' 4. XSHA256 command
''' 5. XSHA512 command
''' 6. XCRC command
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Function GetChecksum(ByVal filepath As String) As FtpHash
Return conn.GetChecksum(filepath)
End Function
''' <summary>
''' Gets the checksum of file on server and compare it with the checksum of local file.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
''' <param name="localfilepath">Indicates the local disk file path.</param>
''' <param name="algorithm">Indicates the algorithm that should be used to verify checksums.</param>
''' <returns>Returns TRUE if both checksums are equal, otherwise returns False.</returns>
Public Function VerifyChecksum(ByVal filepath As String,
ByVal localfilepath As String,
ByVal algorithm As FtpHashAlgorithm) As Boolean
Dim hash As FtpHash = Nothing
hash = conn.GetChecksum(filepath)
' Make sure it returned a, to the best of our knowledge, valid hash object.
' The commands for retrieving checksums are
' non-standard extensions to the protocol so we have to
' presume that the response was in a format understood by
' System.Net.FtpClient and parsed correctly.
'
' In addition, there is no built-in support for verifying CRC hashes.
' You will need to write you own or use a third-party solution.
If hash.IsValid AndAlso hash.Algorithm <> algorithm Then
Return hash.Verify(localfilepath)
Else
Return Nothing
End If
End Function
''' <summary>
''' Gets the size of file.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Function GetFileSize(ByVal filepath As String) As Long
Return conn.GetFileSize(filepath)
End Function
''' <summary>
''' Gets the currently HASH algorithm used for the HASH command on server.
''' </summary>
Public Function GetHashAlgorithm() As FtpHashAlgorithm
Return conn.GetHashAlgorithm()
End Function
''' <summary>
''' Gets the modified time of file.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Function GetModifiedTime(ByVal filepath As String) As Date
Return conn.GetModifiedTime(filepath)
End Function
''' <summary>
''' Returns a file/directory listing using the NLST command.
''' </summary>
''' <param name="directorypath">Indicates the ftp file path.</param>
Public Function GetNameListing(ByVal directorypath As String) As String()
Return conn.GetNameListing(directorypath)
End Function
''' <summary>
''' Gets the current working directory on server.
''' </summary>
Public Function GetWorkingDirectory() As String
Return conn.GetWorkingDirectory()
End Function
''' <summary>
''' Opens the specified file to be appended to...
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Function OpenAppend(ByVal filepath As String) As IO.Stream
Return conn.OpenAppend(filepath)
End Function
''' <summary>
''' Opens the specified file for reading.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Function OpenRead(ByVal filepath As String) As IO.Stream
Return conn.OpenRead(filepath)
End Function
''' <summary>
''' Opens the specified file for writing.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
Public Function OpenWrite(ByVal filepath As String) As IO.Stream
Return conn.OpenWrite(filepath)
End Function
''' <summary>
''' Rename a file on the server.
''' </summary>
''' <param name="filepath">Indicates the ftp file path.</param>
''' <param name="newfilepath">Indicates the new ftp file path.</param>
Public Sub RenameFile(ByVal filepath As String, ByVal newfilepath As String)
If conn.FileExists(filepath) Then
conn.Rename(filepath, newfilepath)
Else
Throw New Exception(filepath & " File does not exist on server.")
End If
End Sub
''' <summary>
''' Rename a directory on the server.
''' </summary>
''' <param name="directorypath">Indicates the ftp file path.</param>
''' <param name="newdirectorypath">Indicates the new ftp file path.</param>
Public Sub RenameDirectory(ByVal directorypath As String, ByVal newdirectorypath As String)
If conn.DirectoryExists(directorypath) Then
conn.Rename(directorypath, newdirectorypath)
Else
Throw New Exception(directorypath & " Directory does not exist on server.")
End If
End Sub
''' <summary>
''' Tells the server wich hash algorithm to use for the HASH command.
''' </summary>
''' <param name="algorithm">Indicates the HASH algorithm.</param>
Public Function SetHashAlgorithm(ByVal algorithm As FtpHashAlgorithm) As Boolean
If conn.HashAlgorithms.HasFlag(algorithm) Then
conn.SetHashAlgorithm(algorithm)
Return True
Else
Return False
End If
End Function
''' <summary>
''' Sets the working directory on the server.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
Public Sub SetWorkingDirectory(ByVal directorypath As String)
conn.SetWorkingDirectory(directorypath)
End Sub
''' <summary>
''' Gets a directory list on the specified path.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
''' <param name="FtpListOption">Options that dictate how a list is performed ans what information is gathered.</param>
Public Function GetDirectories(ByVal directorypath As String,
Optional ByVal FtpListOption As FtpListOption =
FtpListOption.AllFiles) As FtpListItem()
Return conn.GetListing(directorypath, FtpListOption).
Where(Function(item) item.Type = FtpFileSystemObjectType.Directory)
End Function
''' <summary>
''' Gets a file list on the specified path.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
''' <param name="FtpListOption">Options that dictate how a list is performed ans what information is gathered.</param>
Public Function GetFiles(ByVal directorypath As String,
Optional ByVal FtpListOption As FtpListOption =
FtpListOption.AllFiles) As FtpListItem()
Return conn.GetListing(directorypath, FtpListOption).
Where(Function(item) item.Type = FtpFileSystemObjectType.File)
End Function
''' <summary>
''' Gets a link list on the specified path.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
''' <param name="FtpListOption">Options that dictate how a list is performed ans what information is gathered.</param>
Public Function GetLinks(ByVal directorypath As String,
Optional ByVal FtpListOption As FtpListOption =
FtpListOption.AllFiles) As FtpListItem()
Return conn.GetListing(directorypath, FtpListOption).
Where(Function(item) item.Type = FtpFileSystemObjectType.Link)
End Function
''' <summary>
''' Gets a file/folder list on the specified path.
''' </summary>
''' <param name="directorypath">Indicates the ftp directory path.</param>
''' <param name="FtpListOption">Options that dictate how a list is performed ans what information is gathered.</param>
Public Function GetListing(ByVal directorypath As String,
Optional ByVal FtpListOption As FtpListOption =
FtpListOption.AllFiles) As FtpListItem()
Return conn.GetListing(directorypath, FtpListOption)
End Function
''' <summary>
''' Log to a console window
''' </summary>
Public Sub LogToConsole()
FtpTrace.AddListener(New ConsoleTraceListener())
' now use System.Net.FtpCLient as usual and the server transactions
' will be written to the Console window.
End Sub
''' <summary>
''' Log to a text file
''' </summary>
''' <param name="filepath">Indicates the file where to save the log.</param>
Public Sub LogToFile(ByVal filepath As String)
FtpTrace.AddListener(New TextWriterTraceListener(filepath))
' now use System.Net.FtpCLient as usual and the server transactions
' will be written to the specified log file.
End Sub
''' <summary>
''' Uploads a file to FTP.
''' </summary>
''' <param name="UploadClient">Indicates the WebClient object to upload the file.</param>
''' <param name="filepath">Indicates the ftp fle path.</param>
''' <param name="localfilepath">Specifies the local path where to save the downloaded file.</param>
''' <param name="Asynchronous">Indicates whether the download should be an Asynchronous operation,
''' to raise WebClient events.</param>
Public Sub UploadFile(ByRef UploadClient As WebClient,
ByVal localfilepath As String,
Optional ByVal filepath As String = Nothing,
Optional ByVal Asynchronous As Boolean = False)
If filepath Is Nothing Then
filepath = Me.host & "/" & New IO.FileInfo(localfilepath).Name
ElseIf filepath.StartsWith("/") Then
filepath = Me.host & filepath
Else
filepath = Me.host & "/" & filepath
End If
With UploadClient
.Credentials = New NetworkCredential(Me.user, Me.pass)
If Asynchronous Then
.UploadFileAsync(New Uri(filepath), "STOR", localfilepath)
Else
.UploadFile(New Uri(filepath), "STOR", localfilepath)
End If
End With
End Sub
''' <summary>
''' Downloads a file from FTP.
''' </summary>
''' <param name="DownloadClient">Indicates the WebClient object to download the file.</param>
''' <param name="filepath">Indicates the ftp fle path.</param>
''' <param name="localfilepath">Specifies the local path where to save the downloaded file.</param>
''' <param name="Asynchronous">Indicates whether the download should be an Asynchronous operation,
''' to raise WebClient events.</param>
Public Sub DownloadFile(ByRef DownloadClient As WebClient,
ByVal filepath As String,
ByVal localfilepath As String,
Optional ByVal Asynchronous As Boolean = False)
If filepath.StartsWith("/") Then
filepath = Me.host & filepath
Else
filepath = Me.host & "/" & filepath
End If
With DownloadClient
.Credentials = New NetworkCredential(Me.user, Me.pass)
If Asynchronous Then
.DownloadFileAsync(New Uri(filepath), localfilepath)
Else
.DownloadFile(New Uri(filepath), localfilepath)
End If
End With
End Sub
#End Region
#Region " Miscellaneous methods "
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
target = value
Return value
End Function
#End Region
End Class
#End Region

Download text file and set components?

How to make vb download a text file and then read all the lines to see what components are available and then set them on form? Text file would contain something like this:
[1] = number of component, pyc_file as the component name to display to user. and last is a link from where the file is downloaded.
The pyc_file should be displayed next on a checkbox.
[1];pyc_file;www.mediafire.com/abcd1234/_init_.pyc;
I don't know how to explain it very well. I hope you understand!
You can create your own type to parse the parts like this:
Public Class Form1
Dim LineToParse As String =
"[1];pyc_file;www.mediafire.com/abcd1234/_init_.pyc;"
Private Sub Test() Handles MyBase.Shown
Dim Comp As Component = Me.GetComponent(LineToParse)
Dim sb As New System.Text.StringBuilder
sb.AppendFormat("Line: {0}", LineToParse)
sb.AppendLine(Environment.NewLine)
sb.AppendFormat("Index: {0}", CStr(Comp.Index))
sb.AppendLine()
sb.AppendFormat("Name: {0}", Comp.Name)
sb.AppendLine()
sb.AppendFormat("Url: {0}", Comp.URL)
MessageBox.Show(sb.ToString, "Component information",
MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
''' <summary>
''' Parses a comma-delimited component text-line and returns a Component Object.
''' </summary>
''' <param name="ComponentLine">Indicates the component line to parse.</param>
''' <returns>Component.</returns>
Friend Function GetComponent(ByVal ComponentLine As String) As Component
Dim ComponentParts As IEnumerable(Of String) =
ComponentLine.Split(";"c)
Dim Index As Integer =
Integer.Parse(ComponentParts(0).
Replace("[", String.Empty).Replace("]", String.Empty))
Dim Name As String =
ComponentParts(1)
Dim URL As Uri =
New Uri(If(Not ComponentParts(2).StartsWith("http://", StringComparison.OrdinalIgnoreCase),
String.Format("http://{0}", ComponentParts(2)),
ComponentParts(2)))
Return New Component With
{
.Index = Index,
.Name = Name,
.URL = URL
}
End Function
''' <summary>
''' A component.
''' </summary>
Friend NotInheritable Class Component
''' <summary>
''' Indicates the number of component.
''' </summary>
Public Property Index As Integer
''' <summary>
''' Indicates the component name to display to user.
''' </summary>
Public Property Name As String
''' <summary>
''' Indicates a link from where the file is downloaded.
''' </summary>
Public Property URL As Uri
End Class
End Class
I have solved it now :-)
Wasn't actually that hard.

VB.net - Simultaneous Audio

So I'm working on a simple VB.net game for school, in which you pop bubbles. We need to have a sound play when you pop a bubble, which is very simple with the audio play function;
Private Sub bubblePop(sender As Object, e As EventArgs) Handles bubble.Click
My.Computer.Audio.Play(My.Resources.pop, _
AudioPlayMode.Background)
End Sub
However we also have a little backing track for the game that we want to loop in the background infinitely. We tried this with a similar instance of that function;
Private Sub GameScreen_Load(sender As Object, e As EventArgs) Handles MyBase.Load
My.Computer.Audio.Play(My.Resources.musicLoop, _
AudioPlayMode.BackgroundLoop)
End Sub
The function shown above only allows one audio file to be played at once, meaning when a bubble is popped the music disappears for good.
I've tried using two seperate windows media player things, but that isn't working either;
Public pop As String = "pop.wav"
Public minesound As String = "mine.wav"
Public Sub soundEffects(sound)
If sound = pop Then
GameScreen.AxWindowsMediaPlayer2.URL = pop
ElseIf sound = minesound Then
GameScreen.AxWindowsMediaPlayer2.URL = minesound
End If
End Sub
Any help or advice is very appreciated! Thank you!
Basically you need to run an asynchronous operation to play more than one file at once.
I've started writting a solution using My.Computer method but even using a Task/Thread it seems that (strangely) is not sufficient to play a secondary file without stopping the playback of the first file ran so maybe other factor (unknown for me) could be involved, then I've solved it using MCI.
The usage can be this:
Dim TaskCancellationTokenSource As New CancellationTokenSource
Dim TaskToken As CancellationToken = TaskCancellationTokenSource.Token
Private Sub BubbleLoop(ByVal CancellationToken As Threading.CancellationToken)
Dim AudioFileLoop = New MCIPlayer(Me, "C:\BubbleLoop.wav")
Do Until CancellationToken.IsCancellationRequested
AudioFileLoop.Play(AudioPlayMode.WaitToComplete)
Loop
AudioFileLoop.Close()
End Sub
Private Sub Test()
' This plays a file asynchronously into an infinite loop.
Task.Factory.StartNew(Sub() BubbleLoop(TaskToken), TaskToken)
' Wait 2 seconds (just to demonstrate this example)
Threading.Thread.Sleep(2 * 1000)
' Play any other file while the loop is still playing.
Dim AudioFile = New MCIPlayer(Me, "C:\SingleBubble.mp3")
AudioFile.Play(AudioPlayMode.Background)
' Cancel the Bubble Loop.
TaskCancellationTokenSource.Cancel()
End Sub
And you need to add this basic MCI class that I've did (It's not full tsted):
' [ MCI Player ]
'
' // By Elektro H#cker
#Region " Usage Examples "
'Dim AudioFile As New MCIPlayer(Me, "C:\Audio.wav")
'AudioFile.Play(AudioPlayMode.BackgroundLoop)
'Dim sb As New System.Text.StringBuilder
'sb.AppendLine("Filename: " & AudioFile.Filename)
'sb.AppendLine("State...: " & AudioFile.State.ToString)
'sb.AppendLine("Mode....: " & AudioFile.PlaybackMode.ToString)
'sb.AppendLine("Channels: " & CStr(AudioFile.Channels))
'sb.AppendLine("Duration: " & TimeSpan.FromMilliseconds(AudioFile.Duration).ToString("hh\:mm\:ss"))
'MessageBox.Show(sb.ToString, "MCI Player", MessageBoxButtons.OK, MessageBoxIcon.Information)
'AudioFile.Stop()
#End Region
#Region " MCI Player "
''' <summary>
''' Play Wave, MP3 or MIDI files
''' </summary>
Public Class MCIPlayer
Inherits NativeWindow
Implements IDisposable
#Region " API "
''' <summary>
''' Sends a command string to an MCI device.
''' The device that the command is sent to is specified in the command string.
''' </summary>
''' <param name="command">
''' Pointer to a null-terminated string that specifies an MCI command string.
''' For a list, see Multimedia Command Strings.
''' </param>
''' <param name="buffer">
''' Buffer that receives return information.
''' If no return information is needed, this parameter can be NULL.
''' </param>
''' <param name="bufferSize">
''' Size, in characters, of the return buffer specified.
''' </param>
''' <param name="hwndCallback">
''' Handle to a callback window if the "notify" flag was specified in the command string.
''' </param>
<System.Runtime.InteropServices.
DllImport("winmm.dll", SetLastError:=True)>
Private Shared Function mciSendString(
ByVal command As String,
ByVal buffer As System.Text.StringBuilder,
ByVal bufferSize As Integer,
ByVal hwndCallback As IntPtr
) As Integer
End Function
#End Region
#Region " Variables "
''' <summary>
''' The form to manage Windows Messages.
''' </summary>
Private WithEvents form As Form = Nothing
''' <summary>
''' Indicates the audio play command of mciSendString.
''' </summary>
Private PlayCommand As String = String.Empty
''' <summary>
''' Buffer that receives return information.
''' </summary>
Private ReturnInfo As New System.Text.StringBuilder() With {.Capacity = 255}
''' <summary>
''' The current filename of the file that is to be played.
''' </summary>
Private _filename As String = String.Empty
''' <summary>
''' Indicates the current playback mode.
''' </summary>
Private _PlaybackMode As AudioPlayMode
''' <summary>
''' Flag to cancel the BackgroundLoop PlaybackMode.
''' </summary>
Private CancelLoop As Boolean = False
#End Region
#Region " Properties "
''' <summary>
''' The current filename of the file that is to be played.
''' </summary>
Public Property Filename() As String
Get
Return _filename
End Get
Set(ByVal value As String)
If Not IO.File.Exists(value) Then
Throw New IO.FileNotFoundException
Exit Property
End If
_filename = value
End Set
End Property
''' <summary>
''' Gets che current Playback State.
''' </summary>
Public ReadOnly Property State As PlaybackState
Get
mciSendString("status file mode", ReturnInfo, ReturnInfo.Capacity, IntPtr.Zero)
Return [Enum].Parse(GetType(PlaybackState), ReturnInfo.ToString, True)
End Get
End Property
''' <summary>
''' Gets or sets the playback mode of the current file.
''' </summary>
Public Property PlaybackMode As AudioPlayMode
Get
Return _PlaybackMode
End Get
Set(value As AudioPlayMode)
_PlaybackMode = value
End Set
End Property
''' <summary>
''' Gets the channels of the file.
''' </summary>
ReadOnly Property Channels() As Integer
Get
mciSendString("status file channels", ReturnInfo, ReturnInfo.Capacity, IntPtr.Zero)
Return If(IsNumeric(ReturnInfo.ToString),
CInt(ReturnInfo.ToString),
-1)
End Get
End Property
''' <summary>
''' Gets the file duration in Milleseconds.
''' </summary>
ReadOnly Property Duration() As Integer
Get
mciSendString("set file time format milliseconds", Nothing, 0, IntPtr.Zero)
mciSendString("status file length", ReturnInfo, ReturnInfo.Capacity, IntPtr.Zero)
Return If(String.IsNullOrEmpty(ReturnInfo.ToString), 0, CInt(ReturnInfo.ToString))
End Get
End Property
#End Region
#Region " Enumerations "
''' <summary>
''' Audio File playback state.
''' </summary>
Public Enum PlaybackState As Short
''' <summary>
''' File is playing.
''' </summary>
Playing = 0
''' <summary>
''' File is paused.
''' </summary>
Paused = 1
''' <summary>
''' File is stopped.
''' </summary>
Stopped = 2
End Enum
''' <summary>
''' Windows Message Identifiers.
''' </summary>
Public Enum KnownMessages As Integer
''' <summary>
''' Notifies an application that an MCI device has completed an operation.
''' MCI devices send this message only when the MCI_NOTIFY flag is used.
''' </summary>
MM_MCINOTIFY = 953
End Enum
#End Region
#Region " Constructor "
''' <summary>
''' Play Wave, MP3 or MIDI files.
''' </summary>
''' <param name="AudioFile">Indicates the filename of the media to play.</param>
''' <remarks></remarks>
Public Sub New(ByVal form As Form, ByVal AudioFile As String)
Me.Filename = AudioFile
' Set the Formulary.
Me.form = form
' Assign the form handle.
SetFormHandle()
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Plays the file that is specified as the filename.
''' </summary>
''' <remarks></remarks>
Public Sub Play(ByVal PlayMode As AudioPlayMode)
DisposedCheck()
Select Case PlayMode
Case AudioPlayMode.Background
PlayCommand = "play file from 0"
Me.PlaybackMode = AudioPlayMode.Background
Case AudioPlayMode.BackgroundLoop
PlayCommand = "play file from 0 notify"
Me.PlaybackMode = AudioPlayMode.BackgroundLoop
Case AudioPlayMode.WaitToComplete
PlayCommand = "play file from 0 wait"
Me.PlaybackMode = AudioPlayMode.WaitToComplete
End Select
' Open command
Select Case Me.Filename.Split(".").LastOrDefault
Case "mp3"
mciSendString(String.Format("open ""{0}"" type mpegvideo alias file", Me.Filename),
Nothing,
0,
IntPtr.Zero)
Case "wav"
mciSendString(String.Format("open ""{0}"" type waveaudio alias file", Me.Filename),
Nothing,
0,
IntPtr.Zero)
Case "mid", "midi"
mciSendString("stop midi", Nothing, 0, 0)
mciSendString("close midi", Nothing, 0, 0)
mciSendString(String.Format("open sequencer! ""{0}"" alias file", Me.Filename),
Nothing,
0, IntPtr.Zero)
Case Else
Throw New Exception("File type not supported.")
[Close]()
End Select
' Play command
mciSendString(PlayCommand, Nothing, 0, If(PlaybackMode = AudioPlayMode.BackgroundLoop,
Me.Handle,
IntPtr.Zero))
End Sub
''' <summary>
''' Pause the current playback.
''' </summary>
''' <remarks></remarks>
Public Sub Pause()
DisposedCheck()
CancelLoop = True
mciSendString("pause file", Nothing, 0, IntPtr.Zero)
End Sub
''' <summary>
''' Resume the current playback if it is currently paused.
''' </summary>
Public Sub [Resume]()
DisposedCheck()
If Me.State = PlaybackState.Paused Then
CancelLoop = False
mciSendString("resume file", Nothing, 0, IntPtr.Zero)
End If
End Sub
''' <summary>
''' Stop the current playback.
''' </summary>
Public Sub [Stop]()
DisposedCheck()
CancelLoop = True
mciSendString("stop file", Nothing, 0, IntPtr.Zero)
End Sub
''' <summary>
''' Close the current file.
''' </summary>
Public Overloads Sub [Close]()
DisposedCheck()
CancelLoop = True
mciSendString("close file", Nothing, 0, IntPtr.Zero)
End Sub
#End Region
#Region " Event Handlers "
''' <summary>
''' Assign the handle of the target form to this NativeWindow,
''' necessary to override WndProc.
''' </summary>
Private Sub SetFormHandle() _
Handles form.HandleCreated, form.Load, form.Shown
Try
If Not Me.Handle.Equals(Me.form.Handle) Then
Me.AssignHandle(Me.form.Handle)
End If
Catch ' ex As InvalidOperationException
End Try
End Sub
''' <summary>
''' Releases the Handle.
''' </summary>
Private Sub OnHandleDestroyed() _
Handles form.HandleDestroyed
Me.ReleaseHandle()
End Sub
#End Region
#Region " Windows Messages "
''' <summary>
''' Processes Windows messages for this Window.
''' </summary>
''' <param name="m">
''' Contains the Windows Message parameters.
''' </param>
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If m.Msg = KnownMessages.MM_MCINOTIFY Then
If Not CancelLoop Then
Play(AudioPlayMode.BackgroundLoop)
Else
CancelLoop = False
End If
End If
End Sub
#End Region
#Region " IDisposable "
''' <summary>
''' To detect redundant calls when disposing.
''' </summary>
Private IsDisposed As Boolean = False
''' <summary>
''' Prevents calls to methods after disposing.
''' </summary>
Private Sub DisposedCheck()
If Me.IsDisposed Then
Throw New ObjectDisposedException(Me.GetType().FullName)
End If
End Sub
''' <summary>
''' Disposes the objects generated by this instance.
''' </summary>
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
' IDisposable
Protected Overridable Sub Dispose(IsDisposing As Boolean)
If Not Me.IsDisposed Then
If IsDisposing Then
[Close]()
Me.form = Nothing
Me.ReleaseHandle()
Me.DestroyHandle()
End If
End If
Me.IsDisposed = True
End Sub
#End Region
End Class
#End Region