权限管理系统系列之登录、升级模块

目录

权限管理系统系列之序言  

权限管理系统系列之WCF通信

       之前写了两篇关于权限管理系统的博客了,由于这段时间有事比较忙就暂停了,今天继续编写权限管理系统之登陆和升级模块,登陆和升级也是每个系统之必须的模块,对于一个Winform程序,在登陆之前必须要先进行程序的升级,所以先介绍升级模块。

升级模块

表结构如下:

权限管理系统系列之登录、升级模块_第1张图片

 插入数据表数据如下:

权限管理系统系列之登录、升级模块_第2张图片

       一般程序升级可能有好几种,比如说有根本版本号比较升级、根据DLL生成时间比较等等,而我介绍的是根据版本号进行升级。我们需要在服务端将DLL文件的 版本写入到数据表中,这样供每个客户端去比较版本号,就是每次打开客户端之前进行检测版本号,如果版本号相等则不升级,如果不相等则进行升级操作。

服务端实现逻辑如下:

 1         /// 
 2         /// 更新客户端程序集信息  3 ///   4 public static void UpdateAssembleInfo()  5  {  6 DbHelper dbhelper = new DbHelper(AppServer.dbName);  7 string sql = "select * from t_fw_assemble_list t";  8 DataTable dt = dbhelper.Query(sql);  9 DirectoryInfo dirInfo = new DirectoryInfo(Application.StartupPath); 10 FileVersionInfo fvi = null; 11 string updateSql = "update t_fw_assemble_list set s_versionno= '{0}',t_timestamp=getdate() where s_type='{1}' and s_filename='{2}'"; 12 string fName = string.Empty; 13  GetAllFiles(dirInfo); 14 bool isAddLog = true; 15 StreamReader sr = null; 16 for (int i = 0; i < dt.Rows.Count; i++) 17  { 18 fName = dt.Rows[i]["S_FILENAME"].ToString(); 19 if (fileNameDic.ContainsKey(fName)) 20  { 21 if (dt.Rows[i]["L_UPDATE"].ToString() == "2") 22  { 23 sr = new StreamReader(Application.StartupPath + "\\" + fName); 24 string fileContext = sr.ReadToEnd(); 25  sr.Close(); 26  sr.Dispose(); 27 sql = string.Format(updateSql, Common.Util.MD5Encrypt.MD5EncryptDES(fileContext), dt.Rows[i]["S_TYPE"], fName); 28  dbhelper.ExecuteSql(sql); 29 isAddLog = false; 30  } 31 else 32  { 33 fvi = FileVersionInfo.GetVersionInfo(fileNameDic[fName]); 34 if (!dt.Rows[i]["S_VERSIONNO"].ToString().Equals(fvi.FileVersion)) 35  { 36 sql = string.Format(updateSql, fvi.FileVersion, dt.Rows[i]["S_TYPE"], fName); 37  dbhelper.ExecuteSql(sql); 38 isAddLog = false; 39  } 40  } 41 if (!isAddLog) 42  { 43 isAddLog = AddLog(); 44  } 45  } 46  } 47 }

以上代码主要是写入版本到数据库里,每次服务端启动首先执行这段代码。

服务端搞定我就来看看客户端了,客户端启动时调用以下方法实现:

 1                 bool isDownLoad = false;
 2                 if (args != null)  3  {  4 if (args.Length > 0)  5  {  6 for (int i = 0; i < args.Length; i++)  7  {  8 if (args[i] == "Update")  9  { 10 isDownLoad = true; 11 break; 12  } 13  } 14  } 15  } 16 if (isDownLoad) 17  { 18 //启动主界面 19 Application.Run(new LoginForm()); 20  } 21 else 22  { 23 //更新客户端程序集 24 if (UpdateAssembleData.UpdateAssembleInfo() > 0) 25  { 26 DownLoadForm dlf = new DownLoadForm(); 27 dlf.fileNameList = UpdateAssembleData.fileNameList; 28 //启动下载程序界面 29  Application.Run(dlf); 30  } 31 else 32  { 33 //启动主界面 34 Application.Run(new LoginForm()); 35  } 36 }

权限管理系统系列之登录、升级模块_第3张图片

更新时会弹出升级窗体,上面会显示升级的DLL文件,以及文件升级的进度条,升级完成启动新的程序,升级过程的核心代码:

  1         /// 
  2         /// 下载文件  3 ///   4 private void DownLoadFile()  5  {  6 if (fileNameList.Count > 0)  7  {  8 //CallService service = new CallService("GetFile");  9 int countLen = fileNameList.Count;  10 this.pbarDownLoad.Position = this.pbarDownLoad.Properties.Minimum;  11 double step = this.pbarDownLoad.Properties.Maximum / countLen;  12 string fName = string.Empty;  13 string upPath = Application.StartupPath + "\\Update\\";  14 if (!Directory.Exists(upPath))  15  {  16  Directory.CreateDirectory(upPath);  17  }  18  19 string sql = string.Empty;  20  FileStream fs;  21 bool isStartUpdate = false;  22 List<string> list = new List<string>();  23 List<string> getList = new List<string>();  24 //int fLen = 0;  25 long pageNum = 0;  26 for (int i = 0; i < countLen; i++)  27  {  28 bool isFirstPBLen = true;  29 isStartUpdate = false;  30 fName = fileNameList[i];  31 IAsyncResult iart = this.lblDownLoad.BeginInvoke(new SetLabelText(AsyncLabel), new object[] { "正在下载文件 " + fName });  32 this.lblDownLoad.EndInvoke(iart);  33 pageNum = 1;  34  list.Clear();  35  list.Add(fName);  36  list.Add(pageNum.ToString ());  37  38 //创建服务器下载的文件  39 string tmpPath = upPath + fName;  40 tmpPath = tmpPath.Substring(0, tmpPath.LastIndexOf('\\'));  41 if (!Directory .Exists (tmpPath))  42  {  43  Directory.CreateDirectory(tmpPath);  44  }  45 fs = new FileStream(upPath + fName, FileMode.Create, FileAccess.Write);  46  47 while (true)  48  {  49 Result result = FileData.DoGetFile(list);  50 if (!result.success)//DoGetFile  51  {  52 Comm.WriteLogAndShowMessageBox.Error(result.msg, "Client.Win.DownLoadForm.DownLoadFile()出错:" + result.msg);  53  StartUpdateApp(isStartUpdate);  54 break;  55  }  56 else  57  {  58 getList = JSON.Json2Objectstring>>(result.data); //service.GetResult>();  59 byte[] buffer = Convert.FromBase64String(getList[2]);  60  61 if (isFirstPBLen)  62  {  63 //初始化当前文件进度条  64 iart = this.pbarCurrDownLoad.BeginInvoke(new UpdateProcessBar(AsyncIni), new object[] { Convert.ToInt32 (getList[0]), this.pbarCurrDownLoad }); 65 this.pbarCurrDownLoad.EndInvoke(iart); 66 isFirstPBLen = false; 67 Thread.Sleep(100); 68 } 69 70 //接收服务器返回的二制数据 71 fs.Write(buffer, 0, buffer.Length); 72 pageNum ++; 73 list[1] = pageNum.ToString(); 74 AsyncProcessBar(this.pbarCurrDownLoad, 1); 75 if (buffer.Length < Convert.ToInt32(getList[1])) 76 { 77 break; 78 } 79 80 } 81 } 82 fs.Flush(); 83 fs.Close(); 84 //插入日志记录到服务器 85 86 Tools.WriteOptLogToDb(Tools.OPType.Update, "", fName, "从服务器更新文件" + fName); 87 //刷新进度条 88 if (this.pbarDownLoad.Position < this.pbarDownLoad.Properties.Maximum) 89 { 90 if (i == countLen - 1) 91 { 92 AsyncProcessBar(this.pbarDownLoad, step + 1); 93 } 94 else 95 { 96 AsyncProcessBar(this.pbarDownLoad, step); 97 } 98 } 99 isStartUpdate = true; 100 } 101 StartUpdateApp(isStartUpdate); 102 } 103 }

启动本地程序:

 1         /// 
 2         /// 启动更新程序并退出本程序  3 ///   4 private void StartUpdateApp(bool isStartUpdate)  5  {  6 if (isStartUpdate)  7  {  8 string filePath = Application.StartupPath + "\\Update\\Update.exe";  9 if (File.Exists (filePath)) 10  { 11 File.Copy(filePath, Application.StartupPath + "\\Update.exe" , true); 12  File.Delete(filePath); 13  } 14 15 Process.Start(Application.StartupPath + "\\Update.exe"); 16  } 17 //Environment.Exit(0); 18  Application.Exit(); 19  Process.GetCurrentProcess().Kill(); 20 }

以上基本上可以实现对程序的升级了。O(∩_∩)O哈哈~

登陆模块

用户表结构:

权限管理系统系列之登录、升级模块_第4张图片

 升级完成后就该启动登陆模块。登陆界面如下:

权限管理系统系列之登录、升级模块_第5张图片

相对而言登陆界面就超级简单了,用户名和密码两个文本框,两个按钮一个是登陆和一个取消按钮,最下面显示版权。

 

  1         #region 按钮
  2         //登录
  3         private void logButton_Click(object sender, EventArgs e)
  4         {
  5             if (locked)
  6             {
  7                 #region 解锁
  8                 try
  9                 {
 10                     if (pswTextBox.Text == context.Password)
 11                     {
 12                         this.Hide();
 13                         context.ParentForm.Enabled = true;
 14                         context.ParentForm.Show();
 15                         Form[] childrens = context.ParentForm.OwnedForms;
 16                         if (childrens != null)
 17                         {
 18                             foreach (Form item in childrens)
 19                             {
 20                                 if (item.IsDisposed)
 21                                     continue;
 22                                 if (!item.IsMdiChild && !"系统已锁定".Equals(item.Text))
 23                                 {
 24                                     item.Show();
 25                                 }
 26                             }
 27                         }
 28                         context.ParentForm.Activate();
 29                         this.DialogResult = DialogResult.OK;
 30                     }
 31                     else
 32                     {
 33                         Comm.MessageBox.Info("密码错误!");
 34                         pswTextBox.Text = ""; ;
 35                         pswTextBox.Focus();
 36                         return;
 37                     }
 38                 }
 39                 catch (Exception exMsg)
 40                 {
 41                     WriteLogAndShowMessageBox.Error("解锁出错:" + exMsg.Message, "解锁出错:" + exMsg.ToString());
 42                     pswTextBox.Text = ""; ;
 43                     pswTextBox.Focus();
 44                 }
 45                 #endregion 解锁
 46             }
 47             else
 48             {
 49                 #region 登录
 50                 try
 51                 {
 52                     if (string.IsNullOrWhiteSpace(nameTextBox.Text))
 53                     {
 54                         Comm.MessageBox.Info("请输入账号");
 55                         nameTextBox.Focus();
 56                         return;
 57                     }
 58                     if (string.IsNullOrWhiteSpace(pswTextBox.Text))
 59                     {
 60                         Comm.MessageBox.Info("请输入密码");
 61                         pswTextBox.Focus();
 62                         return;
 63                     }
 64                     string name = nameTextBox.Text;
 65                     string password = pswTextBox.Text;
 66                     string despsw = Encrypt.EncryptDES(password, Const.EncryptKey);
 67 
 68                     Result result = LoginData.Login(name, despsw);
 69                     if (!result.success)
 70                     {
 71                         Comm.MessageBox.Info(result.msg);
 72                         if (result.msg.Contains("账号不存在"))
 73                         {
 74                             nameTextBox.Text = "";
 75                             nameTextBox.Focus();
 76                         }
 77                         else if (result.msg.Contains("密码错误"))
 78                         {
 79                             pswTextBox.Text = "";
 80                             pswTextBox.Focus();
 81                         }
 82                         else
 83                         {
 84                             nameTextBox.Text = "";
 85                             pswTextBox.Text = "";
 86                             nameTextBox.Focus();
 87                         }
 88                         return;
 89                     }
 90                     else
 91                     {
 92                         t_fw_user user = new t_fw_user();
 93                         user.s_usercode = name;
 94                         user.s_password = password;
 95                         string resData = JSON.Json2Object<string>(result.data);
 96                         user.s_username = resData;
 97                         //user.Mode = int.Parse(resData[1]);
 98                         //user.UserCode2 = resData[2];
 99                         this.Hide();
100                         MainForm mainform = new MainForm(user);
101                         mainform.Show();
102                         mainform.Text = systemName;
103                         nameTextBox.Text = "";
104                         pswTextBox.Text = "";
105                         Log.Info(name + " 用户登录成功!");
106                         Tools.WriteOptLogToDb(Tools.OPType.Login, "", "用户:" + name + "登录", "用户登录");
107                     }
108                 }
109                 catch (Exception exMsg)
110                 {
111                     WriteLogAndShowMessageBox.Error("登录出错:" + exMsg.Message, "登录出错:" + exMsg.ToString());
112                     nameTextBox.Text = "";
113                     pswTextBox.Text = "";
114                     nameTextBox.Focus();
115                 }
116                 #endregion 登录
117             }
118         }

 

以上即可实现用户的登陆,密码采用DES加密,DES加密和解密方法如下:

 1     /// 
 2     /// Description of Encrypt.
 3     /// 
 4     public static class Encrypt
 5     {
 6         //默认密钥向量
 7         private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
 8         /// 
 9         /// DES加密字符串
10         /// 
11         /// 待加密的字符串
12         /// 加密密钥,要求为8位
13         /// 加密成功返回加密后的字符串,失败返回源串
14         public static string EncryptDES(string encryptString, string encryptKey)
15         {
16             if (!string.IsNullOrEmpty(encryptString))
17             {
18                 try
19                 {
20                     byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
21                     byte[] rgbIV = Keys;
22                     byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
23                     DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
24                     MemoryStream mStream = new MemoryStream();
25                     CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
26                     cStream.Write(inputByteArray, 0, inputByteArray.Length);
27                     cStream.FlushFinalBlock();
28                     return Convert.ToBase64String(mStream.ToArray());
29                 }
30                 catch
31                 {
32                     return encryptString;
33                 }
34             }
35             else
36             {
37                 return string.Empty;
38             }
39         }
40         
41         /// 
42         /// DES解密字符串
43         /// 
44         /// 待解密的字符串
45         /// 解密密钥,要求为8位,和加密密钥相同
46         /// 解密成功返回解密后的字符串,失败返源串
47         public static string DecryptDES(string decryptString, string decryptKey)
48         {
49             try
50             {
51                 byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
52                 byte[] rgbIV = Keys;
53                 byte[] inputByteArray = Convert.FromBase64String(decryptString);
54                 DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
55                 MemoryStream mStream = new MemoryStream();
56                 CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
57                 cStream.Write(inputByteArray, 0, inputByteArray.Length);
58                 cStream.FlushFinalBlock();
59                 return Encoding.UTF8.GetString(mStream.ToArray());
60             }
61             catch
62             {
63                 return decryptString;
64             }
65         }
66     }

现在应该所有的程序密码都进行了加密了吧!之前好像CSDN把所有的密码都泄露出来了,好像那时还是明文的,这好像还是去年的事情吧!

以上简单介绍了升级和登陆模块,也许做好这块的功能是一个项目起到至关重要的作用。

 

你可能感兴趣的:(权限管理系统系列之登录、升级模块)