You need to enable JavaScript to run this app. VB.NET登录程序3次验证失败后自动关应用的计数逻辑异常求解
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 05:36:04