VB.net COMExeption was unhandled - vb.net

I am creating a user login system using vb.net and MS access. I am unsure what is going wrong with my system and I receive the error message "Item cannot be found in the collection corresponding to the requested name or ordinal" The error is coming up in the section "User.Find(Username)" on the first line of the DO loop. Here is my code:
Public Class Login
Dim LoginError As String ' This will tell the user what is wrong with his login
Public Function Login()
Dim DBConn As New ADODB.Connection ' This is how we tell visual studio
'how to connect to our database
Dim User As New ADODB.Recordset 'We pass our argument through our recordset
Dim Username As String 'This will be our "Query"
Dim strUserDB As String 'This get sets to the email field in our database.
Dim strPassDB As String 'Same as above just for the password
Dim blnUserFound As Boolean 'I will be using a "DO" loop so I will use
'this as my condition
DBConn.Open("Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source = '" & Application.StartupPath & "\UserDetails2000.mdb'")
'The inverted comas in the dataOuce statement as itt keeps the location of your
'file as one string.
User.Open("tblUserDetails", DBConn, ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockOptimistic)
'This is my table 'This is my connection 'These are some settings
blnUserFound = False
Login = False
Username = "User = '" & txtEmail.Text & "'" 'This tells the database to find the email field
'Equivilent to what was entered in the textbox
Do
User.Find(Username) 'This is the full statement that sends my 'Query' to the record set
If User.BOF = False And User.EOF = False Then
'BOF = Begining of file, EOF = End of file, it tests whether the database has
'reached its sentinal value, if it hasent then the username has been found, If it has,
'the username has been found.
strUserDB = User.Fields("Email").Value.ToString
'"Email" is my table field. I am setting strUserDB to the username field of my table
strPassDB = User.Fields("Password").Value.ToString
If strUserDB <> txtEmail.Text Then
User.MoveNext()
'This IF statement handles different CASE usernames, Example, admin and AdMiN
'We use this if statement to differentiate between different CASE letters
Else
blnUserFound = True
If strPassDB = txtPassword.Text Then
User.Close()
DBConn.Close()
Return True
Else
LoginError = "Invalid Password"
User.Close()
DBConn.Close()
Return False
End If
End If
Else
LoginError = "Invalid Username"
User.Close()
DBConn.Close()
Return False
End If
Loop Until blnUserFound = True
LoginError = "Invalid Username"
User.Close()
DBConn.Close()
Return False
End Function
Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click
If Login() = True Then
MessageBox.Show("Login Succesful", "Login Status")
Else
MessageBox.Show(LoginError, "Login Status")
End If
End Sub
End Class

Verify that tblUserDetails contains a column named User.
Maybe User is also a reserved keyword in Access so try setting Username as:
Username = "[User] = '" & txtEmail.Text & "'"

Related

Checks The Informations In Text File. VB.NET

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.

How to avoid following "If" conditions if the first "If" is true

I want to make my first If to stop at "Incorrect user and password", but it goes to the second and third If saying "incorrect user" and "incorrect password" after "incorrect user and password".
Public Class Form1
Dim numAttempts As Double = 0
Private Sub btnok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnok.Click
Dim User As String = "ShaoHecc"
Dim Password As String = "daedric123"
Dim loginuser As String
Dim loginpassword As String
Dim wrong As String = False
loginpassword = Val(txtpass.Text)
loginuser = Val(txtuser.Text)
txtpass.Text = loginpassword
txtuser.Text = loginuser
If txtuser.Text = User And
txtpass.Text = Password Then
MessageBox.Show("Access Granted!")
ElseIf txtuser.Text = loginuser And
txtpass.Text = loginpassword Then
MessageBox.Show("Username and Password incorrect, " & numAttempts & " / 3 attempts left")
End If
If txtuser.Text = User = False Then
MessageBox.Show("Username incorrect, you have " & numAttempts & " / 3 attempts left.")
txtuser.Text = Nothing
End If
If txtpass.Text = Password = False Then
MessageBox.Show("Password incorrect, you have " & numAttempts & " / 3 attempts left.")
txtpass.Text = Nothing
End If
If numAttempts = 3 Then
MessageBox.Show("Maxiumum number attempts reached, you have been denied access.")
Application.Exit()
Else
numAttempts = numAttempts + 1
End If
End Sub
End Class
You have far too much code there than what is needed.
You are also using legacy VB6 code where it is not needed.
You appear to have no idea of variables and variable types.
Let me explain a little... Let's work backwards...
Variable types, of which there are many, each are required and/or recommended for a particular task. In your example you have a numAttempts which is used to count the failed attempts, however, you have it as a Double >>> Dim numAttempts As Double, it's wrong and wasteful, just use a standard Integer for a whole number in this situation. This is also of interest: Dim wrong As String = False. There are two things fundamentally wrong here. A string is Text, which means it should always have quotes surrounding the text >>> Dim wrong As String = "False". However, using something to test for True or False should be a Boolean so actually, the correct usage and syntax should be Dim wrong As Boolean = False.
Legacy VB6 code. Never a good thing to mix and match pre-.NET code with .NET code. You're using Val, don't do it. Also, it's worth noting that your usage is not needed and simply incorrect. You are using: loginpassword = Val(txtpass.Text). Why are you doing this? What do you think is happening here? It's going to try to convert whatever is in your txtpass.Text (string) to a Double (not a string) then put it into loginpassword (string).
I hope you don't take offence, I'm just trying to get you to see some flaws so you can try to improve and get to love programming like many people here already do so.
SO let's get back to your original code and question. Below is a simplified version of what you want to do.
Try it, understand it, and then change it as you see fit. For example, if you want a separate Username/Password check.
Good Luck!
Dim numAttempts As Integer = 3
Dim User As String = "ShaoHecc"
Dim Password As String = "daedric123"
Private Sub btnok_Click(sender As Object, e As EventArgs) Handles btnok.Click
'Check if Username or Password are incorrect
If Not txtuser.Text = User Or Not txtpass.Text = Password Then
numAttempts -= 1
If numAttempts = 0 Then
MessageBox.Show("Maxiumum number attempts reached, you have been denied access.")
Application.Exit()
End If
MessageBox.Show("Invalid Username or Password, you have " & numAttempts & " attempts left.")
Exit Sub
End If
'Username and Password are correct
MessageBox.Show("Access Granted!")
numAttempts = 3 'Reset if needed
End Sub

Test whether vb.net code working or not

Maybe this is a stupid question but I am really new in this field..
I am working about authentication in vb.net using AD. After doing some searching, I found a lot of codes related to this. for example:
Private m_ServerName As String
Private m_LoginName As String
Private m_Authenicate As String
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
m_ServerName = DOMAIN_NAME ' Your Domain Name
m_LoginName = Environment.UserName.ToString
m_Authenicate = My.User.Name
End Sub
Public Function IsLogonValid() As Boolean
Dim m_LoginName As String
Dim dirEntry As System.DirectoryServices.DirectoryEntry
Dim dirSearcher As System.DirectoryServices.DirectorySearcher
lblStatus.Text = "Validating User Account"
Try
m_LoginName = Environment.UserName.ToString 'The logged in user ID
dirEntry = New System.DirectoryServices.DirectoryEntry("LDAP://" & DOMAIN_NAME)
dirSearcher = New System.DirectoryServices.DirectorySearcher(dirEntry)
dirSearcher.Filter = "(samAccountName=" & m_LoginName & ")"
'Use the .FindOne() Method to stop as soon as a match is found
Dim sr As SearchResult = dirSearcher.FindOne()
If sr Is Nothing Then 'return false if user isn't found
lblStatus.Text = "User authentication failed"
Return False
End If
Dim de As System.DirectoryServices.DirectoryEntry = sr.GetDirectoryEntry()
sUserName = de.Properties("GivenName").Value.ToString()
lblStatus.Text = "User authentication success"
Return True 'Valid user
Catch ex As Exception ' return false if exception occurs
lblStatus.Text = "User authentication failed"
Return False
End Try
End Function
How can I know whether the code is working or not? Do I have to make a login form?
Just create a form with a textbox/label = lblStatus and run the function.

Struggling with basic VB.net. Variable addition

I'm trying to set up my form program so if the user fails to login 3 times (linked to a database), it closes the program. However, I'm a kinda crap at programming and I can't get the variable to actually hold the addition I'm trying to use?
Private Sub Login_Click(sender As Object, e As EventArgs) Handles Login.Click
Dim uname, pass As String
Dim attempt As Integer = 0
' Warns the user if they have missed out login information.
If UserNameBox.Text = "" Or PasswordBox.Text = "" Then
MessageBox.Show("Please ensure you have entered your username and password", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
uname = UserNameBox.Text
pass = PasswordBox.Text
GetFilteredData("username = '" & uname & "' AND password = '" & pass & "'")
If CountRecords() = 1 Then
MsgBox("Logged In!")
Else
MsgBox("Incorrect Credentials!")
attempt = attempt + 1 ' <-- Main Issue is here
If attempt = 4 Then
Application.Exit()
End If
End If
End If
End Sub
Any help would be amazing. Thanks :D
You're declaring on the attempt varible inside the Login_Click event handler. Hence, each time the Login_Click event is raised, you are initializing it to 0.
Dim attempt As Integer = 0
Try to move it to outer scope, for example make it a member of the Class.
This should work. If you want to have variable accessible from all subs, just take it out too root of class.
Private attempt As Integer = 0
Private Sub Login_Click(sender As Object, e As EventArgs) Handles Login.Click
Dim uname, pass As String
' Warns the user if they have missed out login information.
If UserNameBox.Text = "" Or PasswordBox.Text = "" Then
MessageBox.Show("Please ensure you have entered your username and password", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
uname = UserNameBox.Text
pass = PasswordBox.Text
GetFilteredData("username = '" & uname & "' AND password = '" & pass & "'")
If CountRecords() = 1 Then
MsgBox("Logged In!")
Else
MsgBox("Incorrect Credentials!")
attempt = attempt + 1 ' <-- Main Issue is here
If attempt = 4 Then
Application.Exit()
End If
End If
End If
End Sub

Error when updating SQLite database using VB.Net

Trying to get this code to work so that it will update my SQLite database. Keep getting an error saying that an end of statement is expected error BC30205. I cannot see what i am missing! This is my first ever attempt at an update statement in SQL so i may have missed something obvious! I have marked the line of code i am having the error with with an arrow!
Public Partial Class Change_Password
Public Sub New()
' The Me.InitializeComponent call is required for Windows Forms designer support.
Me.InitializeComponent()
'
' TODO : Add constructor code after InitializeComponents
'
End Sub
Dim SQLconnect As New System.Data.SQLite.SQLiteConnection()
Dim SQLcommand As System.Data.SQLite.SQLiteCommand
Dim SQLreader As System.Data.SQLite.SQLiteDataReader
Dim Password1 As String = ""
Dim Password2 As String = ""
Public Class Password
Public shared usernamechange As String = ""
End Class
Sub Cmd_NextClick(sender As Object, e As EventArgs)
If Trim(txt_Password_Box.Text) = "" Then
MsgBox("Please enter a password")
Else
Password1 = txt_Password_Box.Text
txt_Password_Box.Text = ""
txt_Password_Box.Focus
lbl_Instruction.Text = "Please re-enter the exact same password!"
cmd_Submit.Visible = True
cmd_Next.Visible = False
Me.AcceptButton = cmd_Submit
End If
End Sub
Sub Change_PasswordLoad(sender As Object, e As EventArgs)
cmd_Submit.Visible = False
Me.AcceptButton = cmd_Next
SQLconnect.ConnectionString = "Data Source=KCD.s3db;"
SQLconnect.Open()
End Sub
Sub Cmd_SubmitClick(sender As Object, e As EventArgs)
If Trim(txt_Password_Box.Text) = "" Then
MsgBox("Please enter the password again")
Exit Sub
Else
Password2 = txt_Password_Box.Text
txt_Password_Box.Text = ""
End If
If Password1 = Password2 Then
SQLcommand = SQLconnect.CreateCommand
------> SQLcommand.CommandText = "UPDATE Staff SET Password = '" & password1 & "' WHERE '" Username = "' & password.usernamechange & '"""
SQLcommand.Dispose()
MsgBox("Your password has been changed",vbInformation,"Password Changed")
Me.Close
Else
MsgBox("Passwords do not match. Please try again.")
txt_Password_Box.Focus
cmd_Submit.Visible = False
cmd_Next.Visible = True
Password1 = ""
Password2 = ""
lbl_Instruction.Text = "Please enter a new password!"
Me.AcceptButton = cmd_Next
End If
End Sub
End Class
Hope someone can help me! Thanks
This line doesn't seem right. Change
SQLcommand.CommandText = "UPDATE Staff SET Password = '" & password1 & "' WHERE '" Username = "' & password.usernamechange & '"""
to
SQLcommand.CommandText = "UPDATE Staff SET Password = '" & password1 & "' WHERE Username = '" & password.usernamechange & "'"
BTW, concatenating strings like that leads to being vulnerable to SQL Injection.