I work on a project "SignInLogeIn" using Visual Basic.NET.
I save the user informations in text file.
the name of the file is "data.txt".
to create a new account in my program. you must enter the name,email,password and the program write the informations in textfile.
i use "Streamwritter" to write the informations.
when user create a new account The program checks if the email entered by the user is already in the text file that contains the users' information.
and the program checks from informations by "StreamReader". it reads the information in text file and checks.
I have the problem.
when I CREATE A new account. problem appears.
and the problem is
"
An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll
Additional information: The process cannot access the file 'D:\1- Anas Files\Projects\VisualBasic.NET\SignInLogIn\SignInLogIn\SignInLogIn\bin\Debug\Data.txt' because it is being used by another process.
"
I think the problem is that I used the file twice
Once to write and once to read.
The error occurs in this line "Dim sw As New StreamWriter("Data.txt")".
how can i solve this problem ?
this is the code of "SignIn" button
Private Sub btnSignIn_Click(sender As Object, e As EventArgs) Handles btnSignIn.Click
Dim strEmail As String = txtEmail.Text
Dim Reg As New Regex("^\w+([-_.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$")
If txtUserName.Text.Trim() = "" Or txtEmail.Text.Trim() = "" Or txtPassword.Text.Trim() = "" Then
MsgBox("Please Enter All Input")
If Not Reg.IsMatch(strEmail) Then
MsgBox("Please Enter Email")
End If
Else
Dim sr As New StreamReader("Data.txt")
Dim sw As New StreamWriter("Data.txt")
Dim strPerson As String = txtUserName.Text & ";" & txtEmail.Text & ";" & txtPassword.Text
Dim line As String = ""
Do
line = sr.ReadLine()
Dim arrData As String() = line.Split(";")
If arrData(1) = strEmail Then
MsgBox("Please Change Email")
Else
sw.WriteLine(strPerson)
sw.Close()
End If
Loop While line <> Nothing
sr.Close()
End If
End Sub
You open twice the same file. First, to read and second to write, this is why you cannot write.
Dim sr As New StreamReader("Data.txt")
Dim lines As String = sr.ReadToEnd().Split(Environment.NewLine)
sr.Close()
Dim strPerson As String = txtUserName.Text & ";" & txtEmail.Text & ";" & txtPassword.Text
Dim sw As New StreamWriter("Data.txt")
For Each line As String In lines
Dim arrData As String() = line.Split(";")
If arrData(1) = strEmail Then
MsgBox("Please Change Email")
Exit For
Else
sw.WriteLine(strPerson)
Exit For
End If
Next
sw.Close()
Streams need to be closed and disposed. They are usually put in Using blocks.
I wasn't quite sure of the program flow you wanted. It seemed, since you created a writer and a reader you intended to add to user to the file if they were not listed.
I broke out some of the code into separate methods. I used System.IO since we have a simple text file.
Private Sub btnSignIn_Click(sender As Object, e As EventArgs) Handles btnSignIn.Click
If ValidInput() Then
Dim strPerson As String = $"{txtUserName.Text};{txtEmail.Text};{txtPassword.Text}"
If Not IsUserInFile(strPerson) Then
File.AppendAllText("Data.txt", strPerson & Environment.NewLine)
End If
End If
End Sub
Private Function ValidInput() As Boolean
Dim strEmail As String = txtEmail.Text
Dim Reg As New Regex("^\w+([-_.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$")
If txtUserName.Text.Trim() = "" OrElse txtEmail.Text.Trim() = "" OrElse txtPassword.Text.Trim() = "" Then
MsgBox("Please Enter All Input")
Return False
If Not Reg.IsMatch(strEmail) Then
MsgBox("Please Enter Email")
Return False
End If
End If
Return True
End Function
Private Function IsUserInFile(Person As String) As Boolean
Dim p = Person.Split(";"c)
Dim lines = File.ReadAllLines("Data.txt")
For Each line In lines
If Person = line Then
Return True
End If
Dim fields = line.Split(";"c)
If fields(0) = p(0) AndAlso fields(2) = p(2) AndAlso fields(1) <> p(1) Then
MessageBox.Show("Please Change Email")
Return False
End If
Next
Return False
End Function
This is going to get messy and slow if there are too many users. This info should really be in a database. The worst thing is the passwords should always be salted and hashed; never stored as plain text even is a database.
Related
The procedure allows the modification of text zones by means of an Modify button on the main form. Using a structure, I read and store lines from a text file, and populated according to line number, 3 text boxes. On the other hand, in order to leave it to the user to modify something in these zones if necessary, I would need to know which text zones have been modified! Claude.
Here is my code:
Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click
' Modifier
Dim bibliotheque As New article
With bibliotheque
.Title = TextBox1.Text
.Name = TextBox2.Text
.Charge = TextBox3.Text
End With
Dim fileName As String = "c:\essai.librairie"
Dim someString As String = Trim(TextBox2.Text)
Dim lignes As String() = File.ReadAllLines(fileName, Encoding.UTF8)
Dim found As Integer = -1
For i As Integer = 0 To lignes.Length - 1
If lignes(i).Contains(someString) Then
found = i
Exit For
End If
Next
Dim lines As String() = File.ReadAllLines("c:\essai.librairie", Encoding.UTF8)
lines(found) = bibliotheque.Title.PadRight(17, " "c).ToString & bibliotheque.Name.PadRight(90, " "c).ToString & bibliotheque.Charge.PadRight(120, " "c).ToString
MessageBox.Show("Enregistrer les données modifiées ?",
"Prénommer", MessageBoxButtons.OKCancel,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
If Windows.Forms.DialogResult.OK Then
File.WriteAllLines("c:\essai.librairie", lines, Encoding.UTF8)
Using fStream As New FileStream("c:\essai.librairie", FileMode.Open, FileAccess.ReadWrite, FileShare.None)
fStream.SetLength(fStream.Length - Environment.NewLine.Length)
End Using
Else
Exit Sub
End If
End Sub
You can use the events txtbox1.changed or txtbox1.leave to take action or flag that textbox as being changed. The .changed event fires every time a character is changed. .leave only fires when focus leaves the text box.
Do
Do
Console.WriteLine("Create a password. It must be 8 characters in length")
password1 = Console.ReadLine()
Loop Until password1.Length = 8
Console.WriteLine("Please re-enter the password.")
password2 = Console.ReadLine()
Loop Until password2 = password1
password = password1
Console.WriteLine("your password has been created.")
Console.ReadLine()
The below code generates the file
Dim fileName = "C:\Users\emily\Documents\Details.csv"
Dim fileAppend As New System.IO.StreamWriter(fileName, True)
fileAppend.WriteLine(name & ", " & age & ", " & username & ", " & password & ", " & yeargroup)
fileAppend.Close()
So basically I have details about the users stored in a csv file. The columns are arranged as follows: name, age, username, password, yeargroup. I need to be able to input a username and for it to be found in the array/list and then input the password and if the password doesn't match for it to start again.
Nice homework. You should think about storing password. Clear text is obviously risky. With the user file load in a table like this will let you manage all of the user. Add,Remove, Change then just save over the userfile.
Public Class Form1
Dim UserTable As New DataTable("UserTable")
Dim SomeUserName As String = "slims"
Dim SomePassword As String = "abc1234!"
Sub ReadUserFile()
Dim fileName = "C:\dump\test.csv"
Dim fileReader As New System.IO.StreamReader(fileName)
UserTable.Columns.Add("Name")
UserTable.Columns.Add("Age")
UserTable.Columns.Add("Username")
UserTable.Columns.Add("Password")
UserTable.Columns.Add("YearGroup")
Do Until fileReader.EndOfStream = True
Dim OneLine As String = fileReader.ReadLine()
UserTable.Rows.Add(OneLine.Split(","))
Loop
fileReader.Close()
End Sub
Sub WriteUserFile()
Dim fileName = "C:\dump\test.csv"
Dim fileWriter As New System.IO.StreamWriter(fileName)
For Each xRow As DataRow In UserTable.Rows
fileWriter.WriteLine(String.Format("{0},{1},{2},{3},{4}", xRow("Name"), xRow("Age"), xRow("Username"), xRow("Password"), xRow("YearGroup")))
Next
fileWriter.Close()
End Sub
Function CheckUserPassword(UserName As String, Password As String) As Boolean
Dim Found As Boolean = False
For Each xRow As DataRow In UserTable.Rows
If (xRow("Username") = SomeUserName) And (xRow("Password") = SomePassword) Then
Found = True
Exit For
Else
Found = False
End If
Next
Return Found
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReadUserFile()
If CheckUserPassword(SomeUserName, SomePassword) = True Then
'Good to go
Else
'bad user/pass
End If
WriteUserFile()
End Sub
End Class
You can use IO.File.ReadAllLines(fileName) to read the lines into an array of strings. Then you can use String.Split() on each line to split the fields and pick out the username and password.
dim allLines as String() = IO.File.ReadAllLines(fileName)
for each line as String in allLines
dim lineArray() as string
lineArray = line.Split(New Char() {","c})
username = lineArray(2)
password = lineArray(3)
if username = theUsernameYouWant then
'Found the user. Now check their password
endif
next
I havn't tested this code. Might have syntax errors.
I think I am over engineering this a bit. Any assistance is greatly appreciated on how I can fix this little problem. I have an app that searches multiple sites. But if a user types a custom parameter of g=, then it will search google. The problem is I have right now is it strips the G from the first word of my search term. For example, If I type g=golf game, google pops up with olf game. With the other searches, the = character is getting stripped. Should I use contains instead of this custom firstChars function?
Here is my code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text = "" Then
MsgBox("Enter text to search on." & vbCrLf & Err.Description, MsgBoxStyle.Information, "Need search term to search on.")
TextBox1.Focus()
End If
Try
'CHECK FOR GOOGLE.COM SEARCHING
Dim MyString As String = TextBox1.Text
Dim MyChar() As Char = {"g", "G", "="}
Dim NewString As String = MyString.TrimStart(MyChar)
Dim myUri As New Uri("http://google.com/search?hl=en&q=" & NewString)
Dim first2Chars As String
Dim first3Chars As String
Dim first4Chars As String
first2Chars = TextBox1.Text.Substring(0, 2)
first3Chars = TextBox1.Text.Substring(0, 3)
first4Chars = TextBox1.Text.Substring(0, 4)
MsgBox(first2Chars)
If first2Chars = "G=" Or first2Chars = "g=" Then
System.Diagnostics.Process.Start(myUri.AbsoluteUri)
ElseIf first3Chars = "TS=" Or first3Chars = "ts=" Then
System.Diagnostics.Process.Start("https://localhost/search.do?query=" & Net.WebUtility.UrlEncode(TextBox1.Text))
ElseIf first4Chars = "PIC=" Or first4Chars = "pic=" Then
System.Diagnostics.Process.Start("https://localhost/search.do?query_pic=" & Net.WebUtility.UrlEncode(TextBox1.Text))
End If
Catch ex As Exception
MsgBox("Error running search. The error was: " & vbCrLf & Err.Description, MsgBoxStyle.Exclamation, "Error")
End Try
End Sub
This is killing me because I know why it's doing it but I don't know how to stop it. I am reading from a text file where I have 2 users on 2 lines: bill|777 & john|333.
My conditional statement satisfies both conditions because when it loops thru, it declines one user and accepts the other causing it to do the if and the else. Please tell me how to do this one at a time. Loop thru the text, get the proper user and then go thru the conditions.
Dim MyReader As New StreamReader("login.txt")
While Not MyReader.EndOfStream
Dim user As String = UsernameTextBox.Text + "|" + PasswordTextBox.Text
Dim names() As String = MyReader.ReadLine().Split()
For Each myName In names
If user = myName Then
Me.Hide()
OrderForm.Show()
Else
MsgBox("Wrong username and password")
End If
Next
End While
MyReader.Close()
Something like this should work:
Using MyReader As New StreamReader("login.txt")
Dim GoodUser As Boolean = False
Dim user As String = UsernameTextBox.Text + "|" + PasswordTextBox.Text
While Not MyReader.EndOfStream
Dim user As String = UsernameTextBox.Text + "|" + PasswordTextBox.Text
Dim names() As String = MyReader.ReadLine().Split()
If Not names Is Nothing Then
For Each myName In names
If user = myName Then
GoodUser = True
Me.Hide()
OrderForm.Show()
Exit While
End If
Next
End If
End While
If Not GoodUser Then
MsgBox("Wrong username and password")
End If
End Using
The using block automatically disposes of the streamreader. A boolean to signify a good login can set the condition when the While loop exits. The Exit While will break out of the loop when the proper user is found. It's usually a good idea to set a conditional to check for empty lines
One thing to watch for. If a user name includes a space your code won't work. You'll have to either restrict the user names or use a different delimiter like ~.
Try this code:
Using r As StreamReader = New StreamReader("login.txt")
Dim line As String = r.ReadLine
Dim user As String = UsernameTextBox.Text + "|" + PasswordTextBox.Text
Dim found As Boolean = False
Do While (Not line Is Nothing)
If (line = user) Then
found = True
break
End If
line = r.ReadLine
Loop
If (Not found) Then
MessageBox.Show("Wrong username and password")
End If
End Using
Just to keep this short I am working on a simple game to be played with anyone in the world who be interested in it, and because I am creating said game I decided to work on a simple launcher for the game one that pings the website for a version, checks that version with a stored text file with the game already installed and see if its a difference in version. If its a difference in version the launcher downloads the game. If the person does not already have the game installed it downloads the game for them.
Now for my problem why I am posting here, I am trying to get the text file already stored on the computer from the AppData directory to be read by the launcher and use it as an comparison with the version on the website. This is what I have for the on launch:
On Launch:
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim wc As New Net.WebClient
Text = wc.DownloadString("https://dl.dropboxusercontent.com/u/47132467/version.txt")
If My.Computer.FileSystem.FileExists("C:\Program Files\SC\SC.exe") Then
StartBtn.Enabled = True
StartBtn.Visible = True
Else
StartBtn.Enabled = False
StartBtn.Visible = False
End If
If My.Computer.FileSystem.FileExists("C:\Program Files\SC\Readme.txt") Then
ReadMeBtn.Visible = True
Else
ReadMeBtn.Visible = False
End If
End Sub
In short I am trying to figure out how to make a text file from the computer itself stored in AppData under Environ("AppData") & "\SC\version.txt" Been trying to figure out how to get the program to Read the local stored text file and put it as a variable where the program will compare it with the text file online. Thanks in Advanced! Sorry if I confuse anyone my brain is in derp mode trying to figure this out for a while now.
Here are 2 Functions Read & Write:
Public Function GetFileContents(ByVal FullPath As String, _
Optional ByRef ErrInfo As String = "") As String
Dim strContents As String
Dim objReader As StreamReader
Try
objReader = New StreamReader(FullPath)
strContents = objReader.ReadToEnd()
objReader.Close()
Return strContents
Catch Ex As Exception
ErrInfo = Ex.Message
End Try
End Function
Public Function SaveTextToFile(ByVal strData As String, _
ByVal FullPath As String, _
Optional ByVal ErrInfo As String = "") As Boolean
Dim Contents As String
Dim bAns As Boolean = False
Dim objReader As StreamWriter
Try
objReader = New StreamWriter(FullPath)
objReader.Write(strData)
objReader.Close()
bAns = True
Catch Ex As Exception
ErrInfo = Ex.Message
End Try
Return bAns
End Function
Call:
Dim File_Path as string = Environ("AppData") & "\SC\version.txt"
Dim versionStr as String = GetFileContents("File_Path")
Label1.text = versionStr
Label1.text.refresh ''// Sometimes this may be required depending on what you are doing!
if you want to read the version directly, rather than a text file, have a look at this code:
If My.Computer.FileSystem.FileExists(fn) Then
Dim fv As FileVersionInfo = FileVersionInfo.GetVersionInfo(fn)
If fv Is Nothing Then Return -1 'file has no version info
Return fv.FileMajorPart * 100000 + fv.FileMinorPart * 1000 + fv.FileBuildPart
Else
Return 0 'file does not exist
End If