VB.NET How to save Program settings inside class module - vb.net

I'm currently building a program which requires numerous staff to use my program and the program is located on a shared drive on the network so all users can access the program. In my program I have a Database which I use to manage all the user accounts and other information. When you run the program for the first time ever on the network, it asks the administrator where to create the database. After the program creates the database, I save the connection string to a string variable in a class module within my program. However once I exit the program the value I set the to the string variable in the class gets erased. Is there a way to prevent the string from losing its value after closing the program ? I know I could do this via my.settings but I don't want to do it that way.

You can make your own settings file using a binary serializer.
This method can be used to store an instance of your settings class to a file, which is not very human-readable. If human readability and editability is required, you could use an xml serializer instead. The settings file will reside in the application directory. You can control this with the variable settingsFileName.
Create a new console application and paste the code below. Run it a couple of times and note that the "connection string" is persisted through application close and open.
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Module Module1
Private settingsFileName As String = "Settings.bin"
Private mySettingsClass As SettingsClass
Private Sub loadSettings()
Dim formatter As New BinaryFormatter()
If File.Exists(settingsFileName) Then
Using stream As New FileStream(settingsFileName, FileMode.Open)
mySettingsClass = CType(formatter.Deserialize(stream), SettingsClass)
End Using
Else
Using Stream As New FileStream(settingsFileName, FileMode.CreateNew)
mySettingsClass = New SettingsClass()
formatter.Serialize(Stream, mySettingsClass)
End Using
End If
End Sub
Private Sub saveSettings()
Dim formatter As New BinaryFormatter()
If File.Exists(settingsFileName) Then
Using stream As New FileStream(settingsFileName, FileMode.Truncate)
formatter.Serialize(stream, mySettingsClass)
End Using
Else
Using stream As New FileStream(settingsFileName, FileMode.CreateNew)
formatter.Serialize(stream, mySettingsClass)
End Using
End If
End Sub
<Serializable>
Public Class SettingsClass
Public Property ConnectionString As String = ""
End Class
Sub Main()
Console.WriteLine("Loading settings...")
loadSettings()
Dim connectionString = mySettingsClass.ConnectionString
Console.WriteLine("Connection string: ""{0}""", connectionString)
Console.WriteLine("Enter new connection string...")
mySettingsClass.ConnectionString = Console.ReadLine()
Console.WriteLine("Saving settings...")
saveSettings()
Console.WriteLine("Done!")
Console.ReadLine()
End Sub
End Module
Add additional properties to SettingsClass which can be used elsewhere in your application.

Related

How to create global obects in vb.net

I'm using visual studio 2015.
I'm clearly missing some things...
I want to create a global filestream and stream writer.
Dim wFile As System.IO.FileStream = New FileStream _
("C:\inetpub\wwwroot\SummitMap1Local\Labels\BufferedData.txt", FileMode.Append)
Dim sw As New StreamWriter(wFile)
This works fine. BUT I need to access it globally. Ideally the code would be in its own .aspx file and the wFile and sw objects could be used in a different .aspx file.
Thanks
(odd that I need to edit my original post to add new info)
I am now trying to add a class based on info from MSDN. It's not working. Code -
Imports System
Imports System.IO
Imports System.Text
Public Class test
Public Shared Sub CreateFileStream()
Dim fs As FileStream = New FileStream("C:\inetpub\wwwroot\SummitMap1Local\Labels\BufferedData.txt", FileMode.Append
End Sub
End Class
Then trying to use the class in a function -
Protected Function bufferList(ByVal testData As String) As String
Try
Dim sw As New StreamWriter(fs)
sw.WriteLine(testData)
End Try
End Function
I get an error on 'Dim sw As New StreamWriter(fs)' fs is not declared. It may be inaccessible due to it's protection level
I've tried calling it with test.fs, but test does not have an fs property.

Detect if any file in use by other process of a directory in VB

I am trying to get my vb.net application to look inside a folder and then let me know whether any file older is in use by any application. If in use it will show a message box. I am coding in VB.NET 2008, Express Edition. ...Would anybody know how I do that? Thanks
You can extend the suggested solution with enumerating files in a directory.
Imports System.IO
Imports System.Runtime.InteropServices
Module Module1
Sub Main()
' Here you specify the given directory
Dim rootFolder As DirectoryInfo = New DirectoryInfo("C:\SomeDir")
' Then you enumerate all the files within this directory and its subdirectory
' See System.IO.SearchOption enum for more info
For Each file As FileInfo In rootFolder.EnumerateFiles("*.*", SearchOption.AllDirectories)
' Here you can call the method from the solution linked in Sachin's comment
IsFileOpen(file)
Next
End Sub
' Jeremy Thompson's code from here
Private Sub IsFileOpen(ByVal file As FileInfo)
Dim stream As FileStream = Nothing
Try
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)
stream.Close()
Catch ex As Exception
If TypeOf ex Is IOException AndAlso IsFileLocked(ex) Then
' do something here, either close the file if you have a handle, show a msgbox, retry or as a last resort terminate the process - which could cause corruption and lose data
End If
End Try
End Sub
Private Function IsFileLocked(exception As Exception) As Boolean
Dim errorCode As Integer = Marshal.GetHRForException(exception) And ((1 << 16) - 1)
Return errorCode = 32 OrElse errorCode = 33
End Function
End Module

Serializing and Searching Object Collections

I would appreciate if somebody could answer some questions regarding storing and searching object collections please. If you could give a basic example of any suggestions I would be very grateful.
Storing:
I'm writing an application which needs to search Active Directory for computer objects, and I'm storing them in a collection of objects. I want to save the computer objects collection along with additional information which is not stored in Active Directory (e.g. the computer's MAC address) for the next time the application is run. I also want to save a list of OU's.
Here is my object collection so far (It will have more properties). What is the best method of saving the collection? Preferably not using a database or will saving to a file have a drastic performance impact?
Or is there a better way to do what I have below?
Public Class Computer
Public Property Name As String
Public Property FQDN As String
Public Property Path As String
End Class
Public Class ComputerCollection
Inherits Collections.CollectionBase
Public Sub Add(ByVal computer As Computer) 'Adds a new computer object to the collection
List.Add(computer)
End Sub
End Class
Searching:
I have a layout similar to ADUC with a tree view of OU's and a list view displaying computer objects in the selected OU. The following code loops through the computer object collection checking if the path of the computer object matches the selected OU path and then displays them in the list view.
Is this the best method in terms of performance? or is there a faster way?
Private Sub tvOU_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles tvOU.AfterSelect
lvComputers.Items.Clear()
If tvOU.SelectedNode.Name > "" Then
For Each computerObj In computers
If computerObj.Path.ToString.Replace("CN=" + computerObj.Name + ",", "") = tvOU.SelectedNode.Name Then
Dim lvItem As New ListViewItem
lvItem.Text = computerObj.Name
lvComputers.Items.Add(lvItem)
End If
Next
Else
Exit Sub
End If
End Sub
A simple List(Of Computer) is indeed all you need unless there is some other unknown requirement. Saving is very simple using serialization for this type of thing, and would work the same for a List or Collection<T>.
Imports System.Collections.ObjectModel
Public Class ComputersCollection
Inherits Collection(Of Computer)
' NOT the crude thing in the VB NameSpace
' there is almost nothing to add: item, add and remove
' are in the base class
' ... perhaps saving and retrieving them by a key (name)
' which may do away with the search procedure in the posted code
End Class
Private Computers As New Collection(Of Computer)
' or
Private Computers As New List(Of Computer)
The other part, saving your collection, can be simple with serialization. First, you will have to add the Serializable attribute to your Computer class:
<Serializable>
Public Class Computer
If you forget, you get the error Class foobar is not marked as serializable. Save to disk:
Imports System.Runtime.Serialization
Private myComputerFile As String = ...
Dim bf As New BinaryFormatter
Using fs As New FileStream(myComputerFile , FileMode.OpenOrCreate)
bf.Serialize(fs, Computers)
End Using
Then you can recreate the List or Collection just as easily; this time the List:
' ToDo: add a check to skip if file is not there
' as in the first time run
Dim bf As New BinaryFormatter
Using fs As New FileStream(myComputerFile , FileMode.Open)
Computers = CType(bf.Deserialize(fs), List(Of Computers))
End Using
Alternatively you can use the XML serializer to create an XML File or use the faster, smarter binary serializer is ProtoBuf-Net

How to save the contents (Not Texts Nor Images) of a form with a custom extension and open the saved custom file

I need some help for the project I am working on for my internship.
In the VB project, I have a windows form (Form1.vb) with a custom user control called WaveForm1 (which acts like the graph of an oscilloscope). I can run the VB program and assign values to the channels to get the wave forms in the WaveForm1 user control when the project is running.
Then, I need to save the WaveForm1 together with the Channels plotted in the graph under a custom file extension (.gph, .wfm ,..) using a SaveFileDialog.
The saved file should be able to open in the vb project when it is opened with a button (btnOpen) by using a OpenFileDialog.
How the file is opened in the project doesn't matter as long as the saved graph can be viewed. ( Example, the saved file can be viewed in another WaveForm2 control in Form1.vb or it can be viewed in a separate window form.) It would also be fine if the whole formed can be saved and opened again from the project with the btnOpen button control.
I have searched about custom file creations & saving files and all I could find were how to save text files, excel files or images using a StreamWriter/Reader, binaryReader/Writer, and so on.
I would really appreciate any help regarding saving anything other than text files or drawings.
Please feel free to confirm with me if you are not clear about my questions.
You should try to create a class with some properties then you can save that class using BinarryFormatter. You can give your custom extension to that class and save it through SaveFileDialog and open it by OpenFileDialog.
Class
<Serializable()>
Public Class myGraph
Private _value1 As String
Public Property Value1 As String
Get
Return _value1
End Get
Set(value As String)
_value1 = value
End Set
End Property
Private _value2 As String
Public Property Value2 As String
Get
Return _value2
End Get
Set(value As String)
_value2 = value
End Set
End Property
Private _value3 As String
Public Property Value3 As String
Get
Return _value3
End Get
Set(value As String)
_value3 = value
End Set
End Property
End Class
Method to to Save and Load File
''To Save file
Public Sub SaveFile(GRAPH_1 As myGraph)
''To Save File
Dim dlgSave As New SaveFileDialog
dlgSave.Filter = "My File|*.grp"
dlgSave.DefaultExt = ".gpr"
If dlgSave.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim formatter As New BinaryFormatter
Using stream As New MemoryStream
formatter.Serialize(stream, GRAPH_1)
Using sw As New FileStream(dlgSave.FileName, FileMode.Create)
Dim data() As Byte = stream.ToArray()
sw.Write(data, 0, data.Length)
End Using
End Using
End If
End Sub
''To Load fie
Public Function LoadFile() As myGraph
Dim GRAPH_2 As myGraph = Nothing
Dim dlgOpen As New OpenFileDialog
dlgOpen.Filter = "My File|*.grp"
If dlgOpen.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim formatter As New BinaryFormatter
Using stream As New FileStream(dlgOpen.FileName, FileMode.Open)
GRAPH_2 = TryCast(formatter.Deserialize(stream), myGraph)
End Using
End If
Return GRAPH_2
End Function
How to Use File
''To Save File
Dim GRAPH_1 As New myGraph
With GRAPH_1
.Value1 = "ABC"
.Value2 = "XYZ"
.Value3 = "PQR"
End With
SaveFile(GRAPH_1)
''ToLoad File
Dim GRAPH_2 As myGraph = LoadFile()
If GRAPH_2 IsNot Nothing Then
''Place your code here
''And assign values to your graph from that (myGraph)class.
End If

Save user-defined object into Windows Registry using VB.NET

I need to save created object into Windows Registry and after reopening application to read it? I know how to save and read string but this is complex object.
Any idea?
You maybe want to use a XmlSerializer (or other serializers). It's easy to use, and the documentation is full of examples.
But why storing it in the registry?
Better use Application Settings and User Settings.
EDIT:
Instead of the registry, save your object to a file in the ApplicationData directory of the user. You can get the path to this directory with
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Full example:
Imports System.IO
Imports System.Xml.Serialization
Module Module1
Public Class MySuperClass
Public Property MyString() As String
Public Property MyInt() As Int32
End Class
Public Sub Main(ByVal args() As String)
Dim myFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyApplication")
If Not Directory.Exists(myFolder) Then
Directory.CreateDirectory(myFolder)
End If
Dim myFile = Path.Combine(myFolder, "MySettings.txt")
Dim o = New MySuperClass With {.MyString = "Hi!", .MyInt = 42}
Dim x = New XmlSerializer(GetType(MySuperClass))
Using sr = New StreamWriter(myFile)
' Save directly to file
x.Serialize(sr, o)
End Using
' for demonstrating purpose
o = Nothing
Using sr = New StreamReader(myFile)
' Load directly from file
o = CType(x.Deserialize(sr), MySuperClass)
End Using
End Sub
End Module