VB.NET登录程序3次验证失败后自动关应用的计数逻辑异常求解
计数逻辑异常的核心原因
- 变量作用域错误:
attempts被定义在btnLogin.Click事件方法内部,属于局部临时变量。每次用户点击登录按钮触发方法时,代码都会执行Dim attempts As Integer = 0,变量值被强制重置为0,无法跨多次按钮点击累计失败次数,这是计数永远无法达到3次阈值的根本原因。 - 逻辑顺序颠倒:原代码在处理登录失败时,先判断
attempts = 3,再执行attempts += 1。就算把计数变量移到类级别存储,也会出现实际失败3次时,判断环节的变量值仅为2,永远触发不了阈值判断的问题。 - 阈值分支缺少退出逻辑:原代码中达到3次尝试的分支仅弹出提示框,没有写入实际关闭应用的代码,就算触发判断,程序也不会自动退出。
- 数据库操作隐患:原代码直接把文本框输入拼接到SQL查询语句中,遇到单引号等特殊字符时会直接报错;同时没有做资源兜底释放,异常场景下会出现数据库连接泄漏。
可落地的修正实现
按照以下步骤调整即可实现3次失败自动关程序的需求:
- 把计数变量定义为类级别的成员,让它的生命周期和当前登录窗体一致,可以在多次按钮点击之间保留累计值。
- 调整判断顺序:登录失败时先给计数变量加1,再判断是否达到3次上限,达到上限就直接调用
Application.Exit()关闭整个应用。 - 用参数化查询替换字符串拼接的SQL写法,避免输入特殊字符导致查询异常。
- 用
Using块包裹所有数据库连接、命令、读取器的操作,自动完成资源释放。
修正后的完整代码:
Imports System.Data.OleDb Public Class frmMainScreen ' 类级别计数变量,跨按钮点击保留累计失败次数 Private loginAttempts As Integer = 0 ' 固定连接字符串,避免每次点击重复拼接 Private ReadOnly connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=H:\Visual studio files\Project\CMPC\uDat.accdb" Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click Dim userMatched As Boolean = False Dim matchedUsername As String = "" ' Using块自动释放数据库连接资源,无需手动写Close逻辑 Using conn As New OleDbConnection(connString) ' 参数化查询,避免SQL拼接风险 Dim query As String = "SELECT [Username] FROM uDat WHERE [username] = @UName AND [password] = @Pwd" Using cmd As New OleDbCommand(query, conn) cmd.Parameters.AddWithValue("@UName", txtUsername.Text.Trim()) cmd.Parameters.AddWithValue("@Pwd", txtPassword.Text.Trim()) conn.Open() Using dr As OleDbDataReader = cmd.ExecuteReader() If dr.Read() Then userMatched = True matchedUsername = dr("Username").ToString() End If End Using End Using End Using ' 处理登录结果 If userMatched Then ' 登录成功,重置计数为0(支持后续登出后重新尝试) loginAttempts = 0 MsgBox($"Welcome {matchedUsername}", MsgBoxStyle.Information) Me.Hide() frmFilters3.ShowDialog() Me.Close() Else ' 失败先累计次数,再判断阈值 loginAttempts += 1 If loginAttempts >= 3 Then MsgBox("You have reached the maximum tries. Please restart the app.", MsgBoxStyle.Critical) Application.Exit() Else MsgBox("Username and password combination not found. Please try again or click register.", MsgBoxStyle.Critical) ' 清空密码框,提升输入体验 txtPassword.Clear() txtPassword.Focus() End If End If End Sub End Class
内容的提问来源于stack exchange,提问作者Luke Cassidy
相关产品推荐
相关产品推荐

