摘要:通过人脸识别与管理系统界面的开发(WinForm界面增强,OpenCV-Python智能识别),我将以一个用户登录窗体的两种不同登录验证方式向各位同学介绍如何利用WinForm开发出漂亮的应用程序窗体,为我们后面的各个章节中的窗体开发打下基础。另外也会向各位同学介绍WinForrm窗体如何调用Python程序让OpenCV-Python程序嵌入到我们的登录窗体中,从而实现人脸识别的。博文提供了完整的Python代码和使用教程,适合新入门的朋友参考,完整代码资源文件请转至文末的下载链接。本博文目录如下:
本章节主要介绍的内容如下:
目录
一,如何利用WinForm三层架构(表现层UI,业务逻辑层BLL,数据访问层DAL,实体类Model)实现用户登录。
1,创建数据库表
2,数据库维护工具 SQLiteStudio
3,实体类Model 创建
4,数据访问层DAL 创建
5,业务逻辑层BLL 创建
6,数据库操作帮助类
7,UI层调用
8,登录成功后进入主窗体
9,源码分享,教学ppt分享
10,写在最后
========================================================================
1,创建数据库表
本系统使用的数据库为Sqlite3,创建表 sql如下:
PRAGMA foreign_keys = off;
BEGIN TRANSACTION;
-- Table: UserInfo
CREATE TABLE UserInfo (ID VARCHAR (25) PRIMARY KEY, UserName VARCHAR (50), Pwd VARCHAR (25), Tel VARCHAR (25), Gender VARCHAR (25), Email VARCHAR (50), Idcard VARCHAR (50), Faceinfo VARCHAR (400));
INSERT INTO UserInfo (ID, UserName, Pwd, Tel, Gender, Email, Idcard, Faceinfo) VALUES ('1', 'chenjq', '111111', '13545250214', 'N', '[email protected]', '420982198407189834', NULL);
-- Index: sqlite_autoindex_UserInfo_1
CREATE INDEX sqlite_autoindex_UserInfo_1 ON UserInfo (ID COLLATE BINARY);
COMMIT TRANSACTION;
PRAGMA foreign_keys = on;
2,数据库维护工具 SQLiteStudio
3,实体类Model 创建
///
/// UserInfo:实体类(属性说明自动提取数据库字段的描述信息)
///
[Serializable]
public partial class UserInfo
{
public UserInfo()
{ }
#region Model
private string _id;
private string _username;
private string _pwd;
private string _tel;
private string _gender;
private string _email;
private string _idcard;
///
///
///
public string ID
{
set { _id = value; }
get { return _id; }
}
///
///
///
public string UserName
{
set { _username = value; }
get { return _username; }
}
///
///
///
public string Pwd
{
set { _pwd = value; }
get { return _pwd; }
}
///
///
///
public string Tel
{
set { _tel = value; }
get { return _tel; }
}
///
///
///
public string Gender
{
set { _gender = value; }
get { return _gender; }
}
///
///
///
public string Email
{
set { _email = value; }
get { return _email; }
}
///
///
///
public string IdCard
{
set { _idcard = value; }
get { return _idcard; }
}
#endregion Model
}
4,数据访问层DAL 创建
///
/// 数据访问类:UserInfo
///
public partial class UserInfo
{
public UserInfo()
{ }
#region BasicMethod
///
/// 得到最大ID
///
public int GetMaxId()
{
return DbHelperSQLite.GetMaxID("ID", "UserInfo");
}
///
/// 是否存在该记录
///
public bool Exists(int ID)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("select count(1) from UserInfo");
strSql.Append(" where ID=@ID ");
SQLiteParameter[] parameters = {
new SQLiteParameter("@ID", DbType.String,25) };
parameters[0].Value = ID;
return DbHelperSQLite.Exists(strSql.ToString(), parameters);
}
///
/// 增加一条数据
///
public bool Add(Model.UserInfo model)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("insert into UserInfo(");
strSql.Append("UserName,Pwd,Tel,Gender,Email,Idcard)");
strSql.Append(" values (");
strSql.Append("@UserName,@Pwd,@Tel,@Gender,@Email,@Idcard)");
SQLiteParameter[] parameters = {
new SQLiteParameter("@Id", DbType.String,25),
new SQLiteParameter("@UserName", DbType.String,50),
new SQLiteParameter("@Pwd", DbType.String,25),
new SQLiteParameter("@Tel", DbType.String,25),
new SQLiteParameter("@Gender", DbType.String,25),
new SQLiteParameter("@Email", DbType.String,50),
new SQLiteParameter("@Idcard", DbType.String,50)};
parameters[0].Value = model.ID;
parameters[1].Value = model.UserName;
parameters[2].Value = model.Pwd;
parameters[3].Value = model.Tel;
parameters[4].Value = model.Gender;
parameters[5].Value = model.Email;
parameters[6].Value = model.IdCard;
int rows = DbHelperSQLite.ExecuteSql(strSql.ToString(), parameters);
if (rows > 0)
{
return true;
}
else
{
return false;
}
}
///
/// 更新一条数据
///
public bool Update(Model.UserInfo model)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("update UserInfo set ");
strSql.Append("UserName=@UserName,");
strSql.Append("Pwd=@Pwd,");
strSql.Append("Tel=@Tel");
strSql.Append("Gender=@Gender");
strSql.Append("Email=@Email");
strSql.Append("IdCard=@IdCard");
strSql.Append(" where ID=@ID ");
SQLiteParameter[] parameters = {
new SQLiteParameter("@UserName", DbType.String,50),
new SQLiteParameter("@Pwd", DbType.String,25),
new SQLiteParameter("@Tel", DbType.String,25),
new SQLiteParameter("@Gender", DbType.String,25),
new SQLiteParameter("@Email", DbType.String,50),
new SQLiteParameter("@IdCard", DbType.String,50),
new SQLiteParameter("@ID", DbType.String,25)};
parameters[0].Value = model.UserName;
parameters[1].Value = model.Pwd;
parameters[2].Value = model.Tel;
parameters[3].Value = model.Gender;
parameters[4].Value = model.Email;
parameters[5].Value = model.IdCard;
parameters[6].Value = model.ID;
int rows = DbHelperSQLite.ExecuteSql(strSql.ToString(), parameters);
if (rows > 0)
{
return true;
}
else
{
return false;
}
}
///
/// 删除一条数据
///
public bool Delete(int ID)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("delete from UserInfo ");
strSql.Append(" where ID=@ID ");
SQLiteParameter[] parameters = {
new SQLiteParameter("@ID", DbType.String,25) };
parameters[0].Value = ID;
int rows = DbHelperSQLite.ExecuteSql(strSql.ToString(), parameters);
if (rows > 0)
{
return true;
}
else
{
return false;
}
}
///
/// 批量删除数据
///
public bool DeleteList(string IDlist)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("delete from UserInfo ");
strSql.Append(" where ID in (" + IDlist + ") ");
int rows = DbHelperSQLite.ExecuteSql(strSql.ToString());
if (rows > 0)
{
return true;
}
else
{
return false;
}
}
///
/// 得到一个对象实体
///
public Model.UserInfo GetModel(int ID)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("select ID,UserName,Pwd,Tel,Gender,Email,Idcard from UserInfo ");
strSql.Append(" where ID=@ID ");
SQLiteParameter[] parameters = {
new SQLiteParameter("@ID", DbType.String,25) };
parameters[0].Value = ID;
Model.UserInfo model = new Model.UserInfo();
DataSet ds = DbHelperSQLite.Query(strSql.ToString(), parameters);
if (ds.Tables[0].Rows.Count > 0)
{
return DataRowToModel(ds.Tables[0].Rows[0]);
}
else
{
return null;
}
}
///
/// 得到一个对象实体
///
public Model.UserInfo DataRowToModel(DataRow row)
{
Model.UserInfo model = new Model.UserInfo();
if (row != null)
{
if (row["ID"] != null && row["ID"].ToString() != "")
{
model.ID = row["ID"].ToString();
}
if (row["UserName"] != null)
{
model.UserName = row["UserName"].ToString();
}
if (row["Pwd"] != null)
{
model.Pwd = row["Pwd"].ToString();
}
if (row["Tel"] != null && row["Tel"].ToString() != "")
{
model.Tel = row["Tel"].ToString();
}
if (row["Gender"] != null)
{
model.Gender = row["Gender"].ToString();
}
if (row["Email"] != null)
{
model.Email = row["Email"].ToString();
}
if (row["Idcard"] != null)
{
model.IdCard = row["Idcard"].ToString();
}
}
return model;
}
///
/// 获得数据列表
///
public DataSet GetList(string strWhere)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("select ID,UserName,Pwd,Tel,Gender,Email,Idcard ");
strSql.Append(" FROM UserInfo ");
if (strWhere.Trim() != "")
{
strSql.Append(" where " + strWhere);
}
return DbHelperSQLite.Query(strSql.ToString());
}
///
/// 获取记录总数
///
public int GetRecordCount(string strWhere)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("select count(1) FROM UserInfo ");
if (strWhere.Trim() != "")
{
strSql.Append(" where " + strWhere);
}
object obj = DbHelperSQLite.GetSingle(strSql.ToString());
if (obj == null)
{
return 0;
}
else
{
return Convert.ToInt32(obj);
}
}
///
/// 分页获取数据列表
///
public DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("SELECT * FROM ( ");
strSql.Append(" SELECT ROW_NUMBER() OVER (");
if (!string.IsNullOrEmpty(orderby.Trim()))
{
strSql.Append("order by T." + orderby);
}
else
{
strSql.Append("order by T.ID desc");
}
strSql.Append(")AS Row, T.* from UserInfo T ");
if (!string.IsNullOrEmpty(strWhere.Trim()))
{
strSql.Append(" WHERE " + strWhere);
}
strSql.Append(" ) TT");
strSql.AppendFormat(" WHERE TT.Row between {0} and {1}", startIndex, endIndex);
return DbHelperSQLite.Query(strSql.ToString());
}
#endregion BasicMethod
}
5,业务逻辑层BLL 创建
public partial class UserInfo
{
private readonly DAL.UserInfo dal = new DAL.UserInfo();
public UserInfo()
{ }
#region BasicMethod
///
/// 得到最大ID
///
public int GetMaxId()
{
return dal.GetMaxId();
}
///
/// 是否存在该记录
///
public bool Exists(int ID)
{
return dal.Exists(ID);
}
///
/// 增加一条数据
///
public bool Add(Model.UserInfo model)
{
return dal.Add(model);
}
///
/// 更新一条数据
///
public bool Update(Model.UserInfo model)
{
return dal.Update(model);
}
///
/// 删除一条数据
///
public bool Delete(int ID)
{
return dal.Delete(ID);
}
///
/// 删除一条数据
///
public bool DeleteList(string IDlist)
{
return dal.DeleteList(IDlist);
}
///
/// 得到一个对象实体
///
public Model.UserInfo GetModel(int ID)
{
return dal.GetModel(ID);
}
/
/ 得到一个对象实体,从缓存中
/
//public Model.UserInfo GetModelByCache(int ID)
//{
// string CacheKey = "UserInfoModel-" + ID;
// object objModel = Common.DataCache.GetCache(CacheKey);
// if (objModel == null)
// {
// try
// {
// objModel = dal.GetModel(ID);
// if (objModel != null)
// {
// int ModelCache = Maticsoft.Common.ConfigHelper.GetConfigInt("ModelCache");
// Maticsoft.Common.DataCache.SetCache(CacheKey, objModel, DateTime.Now.AddMinutes(ModelCache), TimeSpan.Zero);
// }
// }
// catch { }
// }
// return (Maticsoft.Model.UserInfo)objModel;
//}
///
/// 获得数据列表
///
public DataSet GetList(string strWhere)
{
return dal.GetList(strWhere);
}
///
/// 获得数据列表
///
public List
{
DataSet ds = dal.GetList(strWhere);
return DataTableToList(ds.Tables[0]);
}
///
/// 获得数据列表
///
public List
{
List
int rowsCount = dt.Rows.Count;
if (rowsCount > 0)
{
Model.UserInfo model;
for (int n = 0; n < rowsCount; n++)
{
model = dal.DataRowToModel(dt.Rows[n]);
if (model != null)
{
modelList.Add(model);
}
}
}
return modelList;
}
///
/// 获得数据列表
///
public DataSet GetAllList()
{
return GetList("");
}
///
/// 分页获取数据列表
///
public int GetRecordCount(string strWhere)
{
return dal.GetRecordCount(strWhere);
}
///
/// 分页获取数据列表
///
public DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex)
{
return dal.GetListByPage(strWhere, orderby, startIndex, endIndex);
}
///
/// 分页获取数据列表
///
//public DataSet GetList(int PageSize,int PageIndex,string strWhere)
//{
//return dal.GetList(PageSize,PageIndex,strWhere);
//}
#endregion BasicMethod
#region ExtensionMethod
#endregion ExtensionMethod
}
6,数据库操作帮助类
///
/// 数据访问基础类(基于SQLite)
/// 可以用户可以修改满足自己项目的需要。
///
public abstract class DbHelperSQLite
{
//数据库连接字符串(web.config来配置),可以动态更改connectionString支持多数据库.
public static string connectionString = CreateConnectionString();
public DbHelperSQLite()
{
}
private static string CreateConnectionString()
{
string dbName = ConfigurationManager.AppSettings["SQLiteDB"];
string sqlLitePath = "data source=" + System.Environment.CurrentDirectory + "\\" + dbName + ";version=3";
return sqlLitePath;
}
#region 公用方法
public static int GetMaxID(string FieldName, string TableName)
{
string strsql = "select max(" + FieldName + ")+1 from " + TableName;
object obj = GetSingle(strsql);
if (obj == null)
{
return 1;
}
else
{
return int.Parse(obj.ToString());
}
}
public static bool Exists(string strSql)
{
object obj = GetSingle(strSql);
int cmdresult;
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
cmdresult = 0;
}
else
{
cmdresult = int.Parse(obj.ToString());
}
if (cmdresult == 0)
{
return false;
}
else
{
return true;
}
}
public static bool Exists(string strSql, params SQLiteParameter[] cmdParms)
{
object obj = GetSingle(strSql, cmdParms);
int cmdresult;
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
cmdresult = 0;
}
else
{
cmdresult = int.Parse(obj.ToString());
}
if (cmdresult == 0)
{
return false;
}
else
{
return true;
}
}
#endregion
#region 执行简单SQL语句
///
/// 执行SQL语句,返回影响的记录数
///
/// SQL语句
/// 影响的记录数
public static int ExecuteSql(string SQLString)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
{
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
connection.Close();
throw new Exception(E.Message);
}
}
}
}
///
/// 执行多条SQL语句,实现数据库事务。
///
/// 多条SQL语句
public static void ExecuteSqlTran(ArrayList SQLStringList)
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = conn;
SQLiteTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
for (int n = 0; n < SQLStringList.Count; n++)
{
string strsql = SQLStringList[n].ToString();
if (strsql.Trim().Length > 1)
{
cmd.CommandText = strsql;
cmd.ExecuteNonQuery();
}
}
tx.Commit();
}
catch (System.Data.SQLite.SQLiteException E)
{
tx.Rollback();
throw new Exception(E.Message);
}
}
}
///
/// 执行带一个存储过程参数的的SQL语句。
///
/// SQL语句
/// 参数内容,比如一个字段是格式复杂的文章,有特殊符号,可以通过这个方式添加
/// 影响的记录数
public static int ExecuteSql(string SQLString, string content)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand(SQLString, connection);
SQLiteParameter myParameter = new SQLiteParameter("@content", DbType.String);
myParameter.Value = content;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
///
/// 向数据库里插入图像格式的字段(和上面情况类似的另一种实例)
///
/// SQL语句
/// 图像字节,数据库的字段类型为image的情况
/// 影响的记录数
public static int ExecuteSqlInsertImg(string strSQL, byte[] fs)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand(strSQL, connection);
SQLiteParameter myParameter = new SQLiteParameter("@fs", DbType.Binary);
myParameter.Value = fs;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
///
/// 执行一条计算查询结果语句,返回查询结果(object)。
///
/// 计算查询结果语句
/// 查询结果(object)
public static object GetSingle(string SQLString)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
{
try
{
connection.Open();
object obj = cmd.ExecuteScalar();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SQLite.SQLiteException e)
{
connection.Close();
throw new Exception(e.Message);
}
}
}
}
///
/// 执行查询语句,返回SQLiteDataReader
///
/// 查询语句
/// SQLiteDataReader
public static SQLiteDataReader ExecuteReader(string strSQL)
{
SQLiteConnection connection = new SQLiteConnection(connectionString);
SQLiteCommand cmd = new SQLiteCommand(strSQL, connection);
try
{
connection.Open();
SQLiteDataReader myReader = cmd.ExecuteReader();
return myReader;
}
catch (System.Data.SQLite.SQLiteException e)
{
throw new Exception(e.Message);
}
}
///
/// 执行查询语句,返回DataSet
///
/// 查询语句
/// DataSet
public static DataSet Query(string SQLString)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection);
command.Fill(ds, "ds");
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
#endregion
#region 执行带参数的SQL语句
///
/// 执行SQL语句,返回影响的记录数
///
/// SQL语句
/// 影响的记录数
public static int ExecuteSql(string SQLString, params SQLiteParameter[] cmdParms)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand())
{
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
int rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return rows;
}
catch (System.Data.SQLite.SQLiteException E)
{
throw new Exception(E.Message);
}
}
}
}
///
/// 执行多条SQL语句,实现数据库事务。
///
/// SQL语句的哈希表(key为sql语句,value是该语句的SQLiteParameter[])
public static void ExecuteSqlTran(Hashtable SQLStringList)
{
using (SQLiteConnection conn = new SQLiteConnection(connectionString))
{
conn.Open();
using (SQLiteTransaction trans = conn.BeginTransaction())
{
SQLiteCommand cmd = new SQLiteCommand();
try
{
//循环
foreach (DictionaryEntry myDE in SQLStringList)
{
string cmdText = myDE.Key.ToString();
SQLiteParameter[] cmdParms = (SQLiteParameter[])myDE.Value;
PrepareCommand(cmd, conn, trans, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
trans.Commit();
}
}
catch
{
trans.Rollback();
throw;
}
}
}
}
///
/// 执行一条计算查询结果语句,返回查询结果(object)。
///
/// 计算查询结果语句
/// 查询结果(object)
public static object GetSingle(string SQLString, params SQLiteParameter[] cmdParms)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
using (SQLiteCommand cmd = new SQLiteCommand())
{
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
object obj = cmd.ExecuteScalar();
cmd.Parameters.Clear();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SQLite.SQLiteException e)
{
throw new Exception(e.Message);
}
}
}
}
///
/// 执行查询语句,返回SQLiteDataReader
///
/// 查询语句
/// SQLiteDataReader
public static SQLiteDataReader ExecuteReader(string SQLString, params SQLiteParameter[] cmdParms)
{
SQLiteConnection connection = new SQLiteConnection(connectionString);
SQLiteCommand cmd = new SQLiteCommand();
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
SQLiteDataReader myReader = cmd.ExecuteReader();
cmd.Parameters.Clear();
return myReader;
}
catch (System.Data.SQLite.SQLiteException e)
{
throw new Exception(e.Message);
}
}
///
/// 执行查询语句,返回DataSet
///
/// 查询语句
/// DataSet
public static DataSet Query(string SQLString, params SQLiteParameter[] cmdParms)
{
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
SQLiteCommand cmd = new SQLiteCommand();
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
using (SQLiteDataAdapter da = new SQLiteDataAdapter(cmd))
{
DataSet ds = new DataSet();
try
{
da.Fill(ds, "ds");
cmd.Parameters.Clear();
}
catch (System.Data.SQLite.SQLiteException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
}
private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, SQLiteTransaction trans, string cmdText, SQLiteParameter[] cmdParms)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = CommandType.Text;//cmdType;
if (cmdParms != null)
{
foreach (SQLiteParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
#endregion
7,UI层调用
//连接sqlite进行身份认证登录
string strUserName = txtUserName.Text;
string strUserPwd = TxtUserPwd.Text;
string strwhere = " UserName = '" + strUserName + "' and Pwd = '" + strUserPwd + "'";
int count = bll.GetRecordCount(strwhere);
if (count > 0)
{
App.frmMain = new FrmMain();
App.qx = 1; //标记一下用户
this.Close(); //关闭登陆窗口
}
else
{
MessageBoxEx.Show("用户不存在,请联系管理员!", "登录认证", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
8,登录成功后进入主窗体
9,源码分享,教学ppt分享
人脸识别与管理系统开发之登录窗体实现-基于sqlite验证(第五章)-C#文档类资源-CSDN下载
10,写在最后
时间对待所有人都是公平的,是努力让每段人生不同。努力,能成全更多小小的梦想,能让你遇见更多可能的自己,能让你在回首时说一句问心无愧。生活会回报真正努力的你。