You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关闭C# WinForms应用时无法向MS Access插入超时日志

应用关闭时无法插入MS Access超时日志的解决方案

问题描述

使用Application.Exit()或this.Close()可正常关闭应用,但无法向MS Access数据库的tblLogs表插入用户超时日志。需求是关闭表单时,自动插入包含Log Time、STATUS、UserID、UserType的超时记录。尝试从LoginForm文本框获取用户ID和密码查询信息后调用RecordTimeOut方法插入日志,但未成功。

用户提供的代码

关闭按钮事件代码

private void btnCloseLight_Click(object sender, EventArgs e)
{
    try
    { 
        //For Getting data from Login Form
        LoginForm form1instance = new LoginForm();
        string userId = form1instance.Form1userLoginTextBox;
        string password = form1instance.Form1passLoginTextBox;

        connection.Open();
        cmd = new OleDbCommand("SELECT [UserID], [UserType] FROM tblUser WHERE UserID = @UserID AND Password = @Password", connection);
        cmd.Parameters.AddWithValue("@UserID", userId);
        cmd.Parameters.AddWithValue("@Password", password);

        OleDbDataReader reader = cmd.ExecuteReader();

        if (reader.Read())
        {
            string userID = reader["UserID"].ToString();
            int userType = Convert.ToInt32(reader["UserType"]);

            //Inserting Time OUT to tblLogs
            RecordTimeOut(userID, userType);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error: " + ex.Message);
    }
    finally
    {
        if (connection.State == ConnectionState.Open)
            connection.Close();
        
    }
}

public void RecordTimeOut(string userId, int userType)
{
    try
    {
        using (OleDbConnection insertConnection = new OleDbConnection(connectionString))
        {
            string status = "TIME OUT";

            insertConnection.Open();
            cmd = new OleDbCommand("INSERT INTO tblLogs ([Log Time], [STATUS], [UserID], [UserType]) VALUES ([@Log Time], [@STATUS], [@UserID], [@UserType])", connection);

            cmd.Parameters.AddWithValue("@Log Time", DateTime.Now.ToString());
            cmd.Parameters.AddWithValue("@STATUS", status);
            cmd.Parameters.AddWithValue("@UserID", userId);
            cmd.Parameters.Add("@UserType", OleDbType.Integer).Value = userType;

            cmd.ExecuteNonQuery();

        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error Inserting Log: " + ex.Message);
    }
}

登录模块代码

#region LogIn
 public void OpenStudentForm()
 {
     //Close Login form
     this.Hide();

     //Shows the New Forms
     StudentForm stuForm = new StudentForm();
     stuForm.FormClosed += (s, args) => this.Close(); // Close the App is when this Form is Closed
     stuForm.Show();
 }

 public void OpenInstructorForm()
 {
     //Close Login form
     this.Hide();

     InstructorForm insForm = new InstructorForm();
     insForm.FormClosed += (s, args) => this.Close(); // Close the App is when this Form is Closed
     insForm.Show();
 }

 public void OpenSystemAdminForm()
 {
     //Close Login form
     this.Hide();

     SystemAdminForm sysAdminForm = new SystemAdminForm();
     sysAdminForm.FormClosed += (s, args) => this.Close(); // Close the App is when this Form is Closed
     sysAdminForm.Show();
 }

 private void btnLogin_Click(object sender, EventArgs e)
 {
     string userIDLogin = userIdLoginTextBox.Texts;
     string passwordLogin = passwordLoginTextBox.Texts;

     try
     {
         connection.Open();
         cmd = new OleDbCommand("SELECT [UserID], [UserType] FROM tblUser WHERE UserID = @UserID AND Password = @Password", connection);
         cmd.Parameters.AddWithValue("@UserID", userIDLogin);
         cmd.Parameters.AddWithValue("@Password", passwordLogin);

         OleDbDataReader reader = cmd.ExecuteReader();

         if (reader.Read())
         {
             string userID = reader["UserID"].ToString();
             int userType= Convert.ToInt32(reader["UserType"]);

             //Inserting Login Info to tblLogs
             InsertLoginLog(userID, userType);

             switch (userType)
             {
                 case 0: //Student
                     OpenStudentForm();
                     break;
                 case 1: //Instructor
                     MessageBox.Show("Instructor");
                     OpenInstructorForm();
                     break;
                 case 2: //System Admin
                     MessageBox.Show("System Admin");
                     OpenSystemAdminForm();
                     break;
                 default:
                     MessageBox.Show("Unknown User Type");
                     break;
             }
         }
         else
         {
             MessageBox.Show("Invalid User ID or Password");
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Error: " + ex.Message);
     }
     finally
     {
         if (connection.State == ConnectionState.Open)
             connection.Close();
     }
 }

 public void InsertLoginLog(string userID, int userType)
 {

     try
     {
         using (OleDbConnection insertConnection = new OleDbConnection(connectionString))
         {
             string status = "TIME IN";

             insertConnection.Open();
             cmd = new OleDbCommand("INSERT INTO tblLogs ([Log Time], [STATUS], [UserID], [UserType]) VALUES ([@Log Time], [@STATUS], [@UserID], [@UserType])", connection);

             cmd.Parameters.AddWithValue("@Log Time", DateTime.Now.ToString());
             cmd.Parameters.AddWithValue("@STATUS", status);
             cmd.Parameters.AddWithValue("@UserID", userID);
             cmd.Parameters.Add("@UserType", OleDbType.Integer).Value = userType;

             cmd.ExecuteNonQuery();
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Error inserting Log: " + ex.Message);
     }
 }
 #endregion

问题根源分析

  1. 错误获取登录用户信息:关闭按钮事件中新建了LoginForm实例,这是一个全新的空表单,并非用户登录时使用的实例,因此文本框内容为空,查询不到用户数据,RecordTimeOut方法不会被执行。
  2. 数据库连接与命令不匹配:RecordTimeOut和InsertLoginLog方法中,创建OleDbCommand时使用了全局的connection对象,而非using块内的insertConnection,导致命令与连接不匹配,无法执行插入操作。
  3. 参数格式错误:SQL语句中参数名被方括号包裹,OleDb对参数的解析是按顺序匹配而非名称,多余的方括号会导致参数识别失败;同时将DateTime.Now转为字符串插入,可能引发日期格式兼容问题。

修复方案

1. 保存登录用户的全局信息

在LoginForm中添加静态变量存储登录用户信息,避免关闭时重新查询:

// LoginForm中添加静态变量
public static string CurrentUserID { get; private set; }
public static int CurrentUserType { get; private set; }

在登录成功的逻辑中赋值:

if (reader.Read())
{
    CurrentUserID = reader["UserID"].ToString();
    CurrentUserType = Convert.ToInt32(reader["UserType"]);
    InsertLoginLog(CurrentUserID, CurrentUserType);
    // 后续打开对应表单逻辑
}

2. 修复数据库插入方法

修正RecordTimeOut方法,确保使用当前using块内的连接,参数写法正确,直接传递DateTime类型:

public void RecordTimeOut()
{
    try
    {
        using (OleDbConnection insertConnection = new OleDbConnection(connectionString))
        {
            string status = "TIME OUT";
            insertConnection.Open();
            string sql = "INSERT INTO tblLogs ([Log Time], [STATUS], [UserID], [UserType]) VALUES (@LogTime, @Status, @UserID, @UserType)";
            using (OleDbCommand cmd = new OleDbCommand(sql, insertConnection))
            {
                cmd.Parameters.AddWithValue("@LogTime", DateTime.Now);
                cmd.Parameters.AddWithValue("@Status", status);
                cmd.Parameters.AddWithValue("@UserID", LoginForm.CurrentUserID);
                cmd.Parameters.Add("@UserType", OleDbType.Integer).Value = LoginForm.CurrentUserType;

                cmd.ExecuteNonQuery();
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error Inserting Log: " + ex.Message);
    }
}

同理修正InsertLoginLog方法,确保连接和参数匹配。

3. 修改关闭按钮事件逻辑

直接使用全局存储的用户信息调用RecordTimeOut:

private void btnCloseLight_Click(object sender, EventArgs e)
{
    try
    {
        if (!string.IsNullOrEmpty(LoginForm.CurrentUserID))
        {
            RecordTimeOut();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error: " + ex.Message);
    }
    finally
    {
        Application.Exit();
    }
}

4. 处理表单关闭事件

在各功能表单的FormClosing事件中确保日志插入完成后再关闭:

private void StudentForm_FormClosing(object sender, FormClosingEventArgs e)
{
    LoginForm loginForm = new LoginForm();
    loginForm.RecordTimeOut();
    e.Cancel = false;
}

内容的提问来源于stack exchange,提问作者Aguni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:13:11