I have this snippet, I just wonder which is the best way to have it async, so it is not going to hang my UI. Have it as Task.run the whole bit, or is there an async version of these connections?
Private Function CheckUDPPortOpen(Address As String, Port As Integer)
Try
Dim udpClient As UdpClient = New UdpClient()
Dim uSocket As Socket = udpClient.Client
uSocket.ReceiveTimeout = 3000
uSocket.Connect(Address, Port)
udpClient.Connect(Address, Port)
Dim RemoteIpEndPoint As IPEndPoint = CreateIPEndPoint(Address & ":" & Port)
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes("?")
udpClient.Send(sendBytes, sendBytes.Length)
Dim receiveBytes As Byte() = udpClient.Receive(RemoteIpEndPoint)
Catch e As SocketException
If e.ErrorCode = 10054 Then
Return "Port is closed"
Else
Return "Port not reachable"
End If
End Try
Return "Port is working fine"
End Function
The RemoteIPEndPoint function:
Public Shared Function CreateIPEndPoint(ByVal endPoint As String) As IPEndPoint
Dim ep As String() = endPoint.Split(":"c)
If ep.Length <> 2 Then Throw New FormatException("Invalid endpoint format")
Dim ip As IPAddress
If Not IPAddress.TryParse(ep(0), ip) Then
Throw New FormatException("Invalid ip-adress")
End If
Dim port As Integer
If Not Integer.TryParse(ep(1), NumberStyles.None, NumberFormatInfo.CurrentInfo, port) Then
Throw New FormatException("Invalid port")
End If
Return New IPEndPoint(ip, port)
End Function
Related
I am trying to get multiple data sets from SQL Server using a VB.NET application. The problem that every time I try to execute the query,
I get this message:
Cannot change property 'ConnectionString'. The current state of the connection is open
Then I tried to fix it by enabling MARS
<connectionStrings>
<add name="ConString"
providerName="System.Data.SqlClient"
connectionString="Data Source=my-PC;Initial Catalog=Project;Persist Security Info=True; MultipleActiveResultSets=true;User ID=user;Password=*****" />
</connectionStrings>
This is my code
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim obj, body
obj = TextBox1.Text
body = TextBox2.Text
For Each mail In getemail()
Send_mail(mail, obj, body, getattachment(mail))
Next
MsgBox("Traitement effectué")
End Sub
Function getemail() As List(Of String)
Dim strMailTo As New List(Of String)
Dim SQL As String = "Select EMail FROM [USER] WHERE EMail Is Not NULL And MatriculeSalarie Is Not NULL And [EMail] <> '' and EtatPaie = 3 and BulletinDematerialise = 1 "
Dim cmd As New SqlCommand
Dim sqLdr As SqlDataReader
Dim dr As DataRow
Try
ConnServer()
cmd.Connection = con
cmd.CommandText = SQL
Using sda As New SqlDataAdapter(cmd)
Using ds As New DataTable()
sda.Fill(ds)
sqLdr = cmd.ExecuteReader()
For i = 0 To ds.Rows.Count - 1
dr = ds.Rows(i)
strMailTo.Add(dr("EMail"))
Next
End Using
End Using
Return strMailTo
sqLdr.Close()
Catch ex As Exception
MsgBox(ex.Message.ToString)
End Try
closeCon()
Return strMailTo
End Function
Function getattachment(email) As String()
Dim SQL As String = "Select MatriculeSalarie FROM [USER] WHERE [EMail]='" & email & "'"
Dim cmd As New SqlCommand
Dim sqLdr As SqlDataReader
ConnServer()
cmd.Connection = con
cmd.CommandText = SQL
Dim mat As String
mat = ""
Dim Dir As String = ConfigurationManager.AppSettings("path1").ToString
Dim file()
sqLdr = cmd.ExecuteReader()
While sqLdr.Read
mat = sqLdr.GetValue(sqLdr.GetOrdinal("MatriculeSalarie"))
End While
file = IO.Directory.GetFiles(Dir, mat.Substring(1) & "*.pdf")
sqLdr.Close()
Return file
End Function
If all you are going to do is show a message box in a Catch, don't do it in the database code. Let the error bubble up to the user interface code and put the Try around where the method is called.
Do not declare variables without a DataType. The button code with Option Infer on sets the type of obj and body.
Private ConStr As String = "Your connection string"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim obj = TextBox1.Text
Dim body = TextBox2.Text
Dim emails As New List(Of String)
Try
emails = getemail()
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "Error retrieving email list")
Exit Sub
End Try
For Each email In emails
Try
Send_mail(email, obj, body, getattachment(email))
Catch ex As Exception
MessageBox.Show(ex.Message, "Error getting attachments")
End Try
Next
MessageBox.Show("Traitement effectué")
End Sub
Parameters used by Sub and Function must have a DataType.
I don't know what you are doing here.
While sqLdr.Read
mat = sqLdr.GetValue(sqLdr.GetOrdinal("MatriculeSalarie"))
End While
Each iteration will overwrite the previous value of mat. I can only assume that you expect only a single value, in which case you can use ExecuteScalar to get the first column of the first row of the result set. Don't do anything with the data until after the connection is closed. Just get the raw data and close (End Using) the connection. Manipulate the data later.
Always use Parameters. Parameters are not treated as executable code by the database server. They are simply values. An example of executable code that could be inserted is "Drop table [USER];" where the value of a parameter belongs. Oops!
Function getemail() As List(Of String)
Dim SQL As String = "Select EMail FROM [USER]
WHERE EMail Is Not NULL
And MatriculeSalarie Is Not NULL
And [EMail] <> ''
And EtatPaie = 3
And BulletinDematerialise = 1;"
Dim dt As New DataTable
Using con As New SqlConnection("Your connection string"),
cmd As New SqlCommand(SQL, con)
con.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Dim strMailTo As New List(Of String)
strMailTo = (From row As DataRow In dt.AsEnumerable
Select row.Field(Of String)(0)).ToList
Return strMailTo
End Function
Function getattachment(email As String) As String()
Dim SQL As String = "Select MatriculeSalarie FROM [USER] WHERE [EMail]='" & email & "'"
Dim mat As String
Using con As New SqlConnection(ConStr),
cmd As New SqlCommand(SQL, con)
cmd.Parameters.Add("#email", SqlDbType.VarChar).Value = email
con.Open()
mat = cmd.ExecuteScalar().ToString()
End Using
Dim Dir As String = ConfigurationManager.AppSettings("path1").ToString
'Your original code was fine, no need for searchPattern.
'I added this so you could see if your search pattern was what you expected.
Dim searchPattern = mat.Substring(1) & "*.pdf"
Debug.Print(searchPattern) 'Appears in the Immediate window
Dim file = IO.Directory.GetFiles(Dir, searchPattern)
Return file
End Function
When I try to cancel an async ADO connection to some DB server that is offline (or not responding), the Cancel method of the ADODB.Connection object blocks for the set time-out period.
I do the async connection like this:
Set Connection = New ADODB.Connection
Connection.Provider = "SQLOLEDB"
Connection.ConnectionTimeout = 60
Connection.ConnectionString = "Initial Catalog=" & RTrim(DBName) & _
";Data Source=" & RTrim(DBServerName) & ";Integrated Security = SSPI"
Connection.Open , , , adAsyncConnect
And then later call the following to cancel/close the connection:
If (Connection.State And adStateConnecting) = adStateConnecting Then
' ==== CONNECTION BLOCKS HERE ======
Connection.Cancel
End If
If (Connection.State And adStateOpen) = adStateOpen Then
Connection.Close
End If
Set Connection = Nothing
Is there a way to not let the Cancel method block?
I found my own solution at the end. Well, at least an acceptable workaround.
First I created a module that could cancel/close the connection in a timer (thanks to an idea from a Code Project article):
Option Explicit
' Timer API:
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, _
ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) _
As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, _
ByVal nIDEvent As Long) As Long
' Collection of connections to cancel
Private m_connections As Collection
' The ID of our API Timer:
Private m_lTimerID As Long
Private Sub TimerProc(ByVal lHwnd As Long, ByVal lMsg As Long, _
ByVal lTimerID As Long, ByVal lTime As Long)
On Error GoTo ErrH:
Dim cnx As ADODB.Connection
' Remove the timer
KillTimer 0, lTimerID
If Not m_connections Is Nothing Then
With m_connections
Do While .Count > 0
Set cnx = .Item(1)
.Remove 1
TryCancelOrCloseConnection cnx
Loop
End With
If m_connections.Count = 0 Then
Set m_connections = Nothing
End If
End If
' Let the next call to CancelOrCloseAsync create a new timer
m_lTimerID = 0
Exit Sub
ErrH:
' Let the next call to CancelOrCloseAsync create a new timer
m_lTimerID = 0
Debug.Print "Error closing connetions timer: " & Err.Description
End Sub
Private Sub TryCancelOrCloseConnection(cnx As ADODB.Connection)
On Error GoTo ErrH
If Not cnx Is Nothing Then
If (cnx.State And adStateConnecting) = adStateConnecting Then
' The call to Cancel here blocks this execution path (until connection time-out),
' but we assume it internally calls DoEvents, because (even though it blocks here) messages get pumped.
cnx.Cancel
End If
' If the connection actually made it to an open state, we make sure it is closed
If (cnx.State And adStateOpen) = adStateOpen Then
cnx.Close
End If
End If
Exit Sub
ErrH:
Debug.Print "ADO Connection Cancel/Close error " & Err.Description
' We deliberately suppress the error here.
' The reason is that accessing the Connection.State property, while there was an error when
' connecting, will raise an error. The idea of this method is simply to make sure we close/cancel
' the pending connection if there was no connection error.
End Sub
Public Sub CancelOrCloseAsync(cnx As ADODB.Connection)
If Not cnx Is Nothing Then
' Add cnx to the collection of connections to cancel
If m_connections Is Nothing Then
Set m_connections = New Collection
End If
m_connections.Add cnx
' Create a timer to start cancelling the connection(s), but only if one is not already busy
' We need to cast the process off to a timer because the Connection.Cancel blocks the
' normal execution path.
If m_lTimerID = 0 Then
m_lTimerID = SetTimer(0, 0, 1, AddressOf TimerProc)
End If
End If
End Sub
I then created a Connection surrogate class called clsADOAsyncConn
Private WithEvents Connection As ADODB.Connection
Private m_Pending As Boolean
Public Event ConnectComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
Public Property Get Provider() As String
Provider = Connection.Provider
End Property
Public Property Let Provider(ByVal val As String)
Connection.Provider = val
End Property
Public Property Get ConnectionTimeout() As Long
ConnectionTimeout = Connection.ConnectionTimeout
End Property
Public Property Let ConnectionTimeout(ByVal val As Long)
Connection.ConnectionTimeout = val
End Property
Public Property Get ConnectionString() As String
ConnectionString = Connection.ConnectionString
End Property
Public Property Let ConnectionString(ByVal val As String)
Connection.ConnectionString = val
End Property
Public Sub OpenAsync(Optional ByVal UserID As String = "", Optional ByVal Password As String = "")
Connection.Open , UserID, Password, adAsyncConnect
m_Pending = True
End Sub
Private Sub Class_Initialize()
Set Connection = New ADODB.Connection
End Sub
Private Sub Class_Terminate()
If Not Connection Is Nothing And m_Pending Then
' While the connection is still pending, when the user of this class reminates the refernce
' of this class, we need to cancel it in its own timer loop or else the caller's code will
' block at the point where the refernce to this object is de-referenced.
CancelOrCloseAsync Connection
End If
End Sub
Private Sub Connection_ConnectComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
m_Pending = False
' Notify the object client of the connection state
RaiseEvent ConnectComplete(pError, adStatus, pConnection)
End Sub
I then update my original connection code to this:
Set Connection = New clsADOAsyncConn
Connection.Provider = "SQLOLEDB"
Connection.ConnectionTimeout = 60
Connection.ConnectionString = "Initial Catalog=" & RTrim(DBName) & _
";Data Source=" & RTrim(DBServerName) & ";Integrated Security = SSPI"
Connection.OpenAsync
The actual connection is then retuned by the clsADOAsyncConn.ConnectComplete event.
The only known issue with this solution is that even though it helps prevent a block in normal execution of code, it still causes a block when the process exits (at least until the last pending connection(s) times out)
I'm building an application that can communicate and send commands to game servers. In the gaming world we call this “rcon” for remote console, but in reality it's just a telnet session. After successful authentication, a text command can be issued to the server and a text response is sent back to the client.
Often times server admins/owners run multiple game servers and every server has its own distinct ip address, port & password. I would like my application to loop through a list/array/datatable/dictionary (or whatever method is best ) of servers, connect and authenticate to each server, then somehow store that connection so commands can be sent to it in the future (Without having to connect & authenticate again)
Below is the code I have that works for a single server. I store the TcpClient(client) & NetworkStream(stm) as global objects which keeps the connection/session open to the server. What is the best method for me to do this with multiple servers since each server will have it's own TcpClient & NetworkStream?
Is there some way for me to store each TcpClient(client) & NetworkStream(stm) in an array, dictionary or something? I'm completely lost with how to approach this.
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports System.Security.Cryptography
Imports System.IO
Public Class Form1
Public client As TcpClient
Public stm As NetworkStream
Sub SendCmd(cmd As String)
Dim data
If cmd.Trim = "" Then
data = Encoding.GetEncoding(1252).GetBytes(cmd)
Else
data = Encoding.GetEncoding(1252).GetBytes(cmd & vbCrLf)
End If
stm.Write(data, 0, data.Length)
Dim resp As Byte() = New Byte(512) {}
Dim memStream = New MemoryStream()
Thread.Sleep(500)
Dim bytes As Integer = 0
If stm.DataAvailable Then
Do
Thread.Sleep(10)
bytes = stm.Read(resp, 0, resp.Length)
memStream.Write(resp, 0, bytes)
Loop While stm.DataAvailable
Dim responsedata As String = Encoding.GetEncoding(1252).GetString(memStream.ToArray())
If responsedata.Contains("### Digest seed: ") Then
'The server is asking for authentication: Login to the server now
Authenticate(responsedata)
End If
OutputRTB.Text &= responsedata
End If
memStream.Close()
End Sub
Sub GetPlayerList()
If stm.CanRead Then
Dim data = Encoding.GetEncoding(1252).GetBytes("bf2cc pl" & vbCrLf)
Dim PlayerDT As New DataTable
PlayerDT.Columns.Add("PlayerSlot", GetType(Integer))
PlayerDT.Columns.Add("HeroName", GetType(String))
PlayerDT.Columns.Add("Score", GetType(String))
PlayerDT.Columns.Add("HeroID", GetType(String))
PlayerDT.Columns.Add("PlayerID", GetType(String))
PlayerDT.Columns.Add("Level", GetType(Integer))
PlayerDT.Columns.Add("Class", GetType(String))
PlayerDT.Columns.Add("Ping", GetType(Integer))
stm.Write(data, 0, data.Length)
Dim resp As Byte() = New Byte(512) {}
Dim memStream = New MemoryStream()
Thread.Sleep(500)
Dim bytes As Integer = 0
If stm.DataAvailable Then
Do
Thread.Sleep(10)
bytes = stm.Read(resp, 0, resp.Length)
memStream.Write(resp, 0, bytes)
Loop While stm.DataAvailable
Dim responsedata As String = Encoding.GetEncoding(1252).GetString(memStream.ToArray())
If responsedata.Contains("### Digest seed: ") Then
'Login to the server
Authenticate(responsedata)
End If
OutputRTB.Text = responsedata.Replace(vbTab, "^")
Dim Rows() As String = responsedata.Split(Environment.NewLine)
For i = 0 To Rows.Length - 1
Dim Cols() As String = Rows(i).Split(vbTab)
If Cols.Length > 40 Then
PlayerDT.Rows.Add(Cols(0).ToString(), Cols(1).ToString(), Cols(37).ToString(), Cols(10).ToString(), Cols(47).ToString(), Cols(39).ToString(), Cols(34).ToString(), Cols(3).ToString)
End If
Next
End If
DataGridView1.DataSource = PlayerDT
DataGridView1.Update()
memStream.Close()
End If
End Sub
Sub Authenticate(ByVal rdata As String)
Dim DigestKeyStart As Integer = rdata.LastIndexOf(":") + 2
Dim DigestKeyLen As Integer = 16
Dim PWResponse As String = rdata.Substring(DigestKeyStart, DigestKeyLen) & PassTXT.Text
PWResponse = "login " & GenerateHash(PWResponse)
SendCmd(PWResponse)
End Sub
Private Function GenerateHash(ByVal SourceText As String) As String
Dim objMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider
Dim arrData() As Byte
Dim arrHash() As Byte
' first convert the string to bytes (using UTF8 encoding for unicode characters)
arrData = System.Text.Encoding.UTF8.GetBytes(SourceText)
' hash contents of this byte array
arrHash = objMD5.ComputeHash(arrData)
' thanks objects
objMD5 = Nothing
' return formatted hash
Return ByteArrayToString(arrHash)
End Function
Private Function ByteArrayToString(ByVal arrInput() As Byte) As String
Dim strOutput As New System.Text.StringBuilder(arrInput.Length)
For i As Integer = 0 To arrInput.Length - 1
strOutput.Append(arrInput(i).ToString("X2"))
Next
Return strOutput.ToString().ToLower
End Function
Private Sub Form1_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
stm.Close()
client.Close()
End Sub
Private Sub ConnectBTN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectBTN.Click
client = New TcpClient(ServerIPTXT.Text, PortTXT.Text)
stm = client.GetStream()
SendCmd(CommandTXT.Text)
End Sub
Private Sub SendCommandBTN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendCommandBTN.Click
SendCmd(CommandTXT.Text)
End Sub
Private Sub GetPlayerListBTN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetPlayerListBTN.Click
GetPlayerList()
End Sub
End Class
BTW This is my first post on stackoverflow, but I have learned so much from this site over the years =)
I am trying to develop a code that manages the firewall ports using vb.net. The first part is to list all ports enabled. so I am trying this code:
Function portsList()
Dim ports As INetFwOpenPorts
Dim port As INetFwOpenPort
Dim myPorts() As INetFwOpenPorts
Dim NetFwMgrType As Type = Type.GetTypeFromProgID("HNetCfg.FwMgr", False)
Dim mgr As INetFwMgr = DirectCast(Activator.CreateInstance(NetFwMgrType), INetFwMgr)
ports = DirectCast(mgr.LocalPolicy.CurrentProfile.GloballyOpenPorts, INetFwOpenPorts)
Dim enumerate As System.Collections.IEnumerator = ports.GetEnumerator()
Dim i As Integer
While enumerate.MoveNext()
port = DirectCast(enumerate.Current, INetFwOpenPort)
myPorts(i) = port
i += 1
End While
Dim portAsString() As String
For j As Integer = 0 To i
portAsString(j) = myPorts(j).ToString
Next
Return portAsString
End Function
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim ports() As String = portsList()
Dim n As String = ports.Length
Dim newString As String = ""
For h As Integer = 0 To n
newString = ports(h) & vbNewLine
Next
RichTextBox1.Text = newString
End Sub
What I want to do is list all the ports in Richtextbox1 after clicking Button4. The error that I am getting is:
NullReferenceException was unHandled. Object reference not set to an instance of an object.
I am new to Vb, how can I get over this?
Try this:
For port As Integer = 1 to maxPorts
Dim host As String = "192.168.1.7"
Dim hostadd As Net.IPAddress = Net.Dns.GetHostEntry(host).AddressList(0)
Dim EPhost As New Net.IPEndPoint(hostadd, port)
Dim s As New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Try
s.Connect(EPhost)
Catch
End Try
If s.Connected Then
'Port opened
Else
'Port closed
End If
Next
Here you have the complete project.
I wrote the following function to verify log in data for user, but so far its not working as it should and I am sure there is something wrong with it:
Private Sub button2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles button2.Click
If loginpasswordtx.Text.Length > 1 And loginpasswordtx.Text.Length > 1 And My.Settings.SQLConnectionString.Length > 5 Then
Try
Dim cnn As New SqlConnection(My.Settings.SQLConnectionString)
Dim cmd = New SqlCommand("SELECT AppUser,AppUserPass FROM OrderAppUsers WHERE AppUser=#AppUser AND AppUserPass=#AppUserPass", cnn)
cmd.Parameters.Add(New SqlParameter("#AppUser", createuserAppUser.Text))
cmd.Parameters.Add(New SqlParameter("#AppUserPass", MD5StringHash(loginpasswordtx.Text)))
cnn.Open()
Dim obj As Object = cmd.ExecuteScalar()
If obj = Nothing Then
MsgBox("Faild to Log in, check your log in info")
cnn.Close()
Return
End If
cnn.Close()
Catch ex As SqlException
MsgBox(ex.Message)
Return
End Try
MsgBox("Logged in Successfully")
End If
End Sub
All I get is a null obj even though user and pass exist in the table.
the following code is for adding new users
Try
Dim cnnstring As String = String.Format("Server={0};Database={1};Trusted_Connection=True;", createuserServerTx.Text, createuserDatabaseTx.Text)
Dim cnn As New SqlConnection(cnnstring)
Dim cmd As New SqlCommand("INSERT INTO OrderAppUsers VALUES (#AppUser, #AppUserPass)", cnn)
cmd.Parameters.Add(New SqlParameter("#AppUser", createuserAppUser.Text))
cmd.Parameters.Add(New SqlParameter("#AppUserPass", MD5StringHash(createuserpassword.Text)))
cnn.Open()
cmd.ExecuteNonQuery()
cnn.Close()
MsgBox("User Crated Successfully")
LayoutControl1.Visibility = Windows.Visibility.Collapsed
My.Settings.SQLConnectionString = cnnstring
My.Settings.Save()
Catch ex As SqlException
MsgBox(ex.Message)
End Try
and the function to generate a custom hash
Private Function MD5StringHash(ByVal strString As String) As String
Dim MD5 As New MD5CryptoServiceProvider
Dim Data As Byte()
Dim Result As Byte()
Dim R As String = ""
Dim Temp As String = ""
Data = Encoding.ASCII.GetBytes(strString)
Result = MD5.ComputeHash(Data)
For i As Integer = 0 To Result.Length - 1
Temp = Hex(3 * Result(i) + 1)
If Len(Temp) = 1 Then Temp = "0" & Temp
R += Temp
Next
Return R
End Function
Try the following when adding parameter
cmd.Parameters.AddWithValue("#AppUser", createuserAppUser.Text)
cmd.Parameters.AddWithValue("#AppUserPass", MD5StringHash(loginpasswordtx.Text))
or just stick with what you did but a little different than yours,
cmd.Parameters.Add("#AppUser", SqlDbType.VarChar)
cmd.Parameters("#AppUser").Value = createuserAppUser.Text
cmd.Parameters.Add("#AppUserPass", SqlDbType.VarChar)
cmd.Parameters("#AppUserPass").Value = MD5StringHash(loginpasswordtx.Text)
by the way, when using ExecuteScalar() it only returns single value. So your query can be written as
SELECT COUNT(*)
FROM OrderAppUsers
WHERE AppUser=#AppUser AND AppUserPass=#AppUserPass
and you can use int variable to store its value
Dim obj As int = Cint(cmd.ExecuteScalar())
so the possible values are 0 or the total number of records return.
If obj = 0 Then
MsgBox("Faild to Log in, check your log in info")
'' other codes
End If
and by refractoring your code, use Using -Statement
Using cnn As New SqlConnection(My.Settings.SQLConnectionString)
Using cmd = New SqlCommand("SELECT COUNT(*) FROM OrderAppUsers WHERE AppUser=#AppUser AND AppUserPass=#AppUserPass", cnn)
cmd.Parameters.AddWithValue("#AppUser", createuserAppUser.Text)
cmd.Parameters.AddWithValue("#AppUserPass", MD5StringHash(loginpasswordtx.Text))
cmd.CommandType = CommandType.Text
Try
cnn.Open()
Dim obj As int = Cint(cmd.ExecuteScalar())
If obj = 0 Then
MsgBox("Faild to Log in, check your log in info")
Else
MsgBox("Logged in Successfully")
End If
Catch(ex As SqlException)
MsgBox(ex.Message.ToString())
End Try
End Using
End Using
I checked your code in my local system and it is working fine i mean i was able to validate its return true i analysis and found its return false only when i am adding one space on password text before encrypt can u check in database value is space adding into password value or can u post your encrypt code