在软件安装的时候,常常要验证软件的有效性,这时候发行产品的时候会附带一个USB Key,主程序运行的时候检查这个Key的合法性,如果通过验证,那么启动主程序。
下面的代码提供了实现该方法的途径:
- /// <summary>
- /// USB 操作相关
- /// </summary>
- public class UsbUtility
- {
- const string Key_File_Name = "Usb.key";
- /// <summary>
- /// 获取优盘唯一序列号,可能需要以管理员身份运行程序
- /// </summary>
- /// <returns></returns>
- public static string GetUSBId()
- {
- ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher("Select * From Win32_USBHub");
- string id = "";
- foreach (ManagementObject wmi_USB in wmiSearcher.Get())
- {
- string strPath = wmi_USB.Path.RelativePath;
- string[] strArr = strPath.Split('/"');
- string strTemp = strArr[1];
- //VID_ 是真正的优盘标示
- if (strTemp.StartsWith("USBVID_"))
- id += strTemp + ";";
- }
- return id.TrimEnd(';');
- }
- /// <summary>
- /// 获取当前UsbKey,根据当前附加的序列号,生成 "序列号,UsbId"格式的字符串,并返回加密后的结果
- /// 如果没有找到设备,那么返回空字符串
- /// 如果返回值为空,请检查 message 的值。
- /// </summary>
- /// <param name="sourceNumber">要附加的序列号</param>
- /// <param name="message">生成的操作信息</param>
- /// <returns>当前加密后的UsbKey字符串</returns>
- public static string GetCurrentUsbKey(string sourceNumber,out string message)
- {
- string strUsbId = GetUSBId();
- if (strUsbId != "")
- {
- if (strUsbId.Split(';').Length == 1)
- {
- CheckCode cc = new CheckCode();
- message = "OK";
- string strTemp = sourceNumber+","+strUsbId ;
- return cc.Encode(strTemp);
- }
- else
- {
- message = "当前有多个U盘,请拨除其它U盘。";
- return "";
- }
- }
- message = "未找到U盘或者U盘没有物理序列号。";
- return "";
- }
- /// <summary>
- /// 将一个新的UsbKey写到当前U盘上
- /// </summary>
- /// <param name="sourceNumber">U盘所在盘符</param>
- /// <param name="sourceNumber">要附加的序列号</param>
- /// <param name="message">生成的操作信息</param>
- /// <returns></returns>
- public static bool WriteUsbKeyFile(string driveName, string sourceNumber,out string message)
- {
- string strCurrentUsbKey = GetCurrentUsbKey(sourceNumber, out message);
- if (strCurrentUsbKey != "")
- {
- if (driveName.EndsWith("//"))
- driveName += "//";
- string strCurrKeyFileName = driveName + Key_File_Name;
- try
- {
- using (StreamWriter writer = File.CreateText(strCurrKeyFileName))
- {
- writer.Write(strCurrentUsbKey);
- writer.Flush();
- }
- message = "OK";
- return true;
- }
- catch (Exception ex)
- {
- message = ex.Message;
- }
- }
- return false;
- }
- /// <summary>
- /// 读取UsbKey文件的内容,返回内容格式为 "序列号,UsbId"格式的字符串
- /// 如果未能正确读取文件,返回空字符。
- /// </summary>
- /// <param name="driveName">U盘所在盘符</param>
- /// <param name="message">操作的消息</param>
- /// <returns>UsbKey文件的内容</returns>
- public static string ReadUsbKeyFile(string driveName, out string message)
- {
- if (driveName.EndsWith("//"))
- driveName += "//";
- string strCurrKeyFileName = driveName + Key_File_Name;
- message = "";
- try
- {
- string strResult = "";
- using (StreamReader reader = File.OpenText(strCurrKeyFileName))
- {
- strResult = reader.ReadToEnd();
- }
- if (strResult != "")
- {
- message = "OK";
- CheckCode cc = new CheckCode();
- return cc.Decode(strResult);
- }
- else
- {
- message = "未能正确读取文件,文件内容可能为空!";
- }
- }
- catch (Exception ex)
- {
- message = ex.Message;
- }
- return "";
- }
- }
- /// <summary>
- /// 检查编码情况
- /// </summary>
- class CheckCode
- {
- const string KEY_64 = "fasfgew";
- const string IV_64 = "JDLJMAMI"; //注意了,是8个字符,64位
- /// <summary>
- /// 加密
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- public string Encode(string data)
- {
- byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
- byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);
- DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
- int i = cryptoProvider.KeySize;
- MemoryStream ms = new MemoryStream();
- CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);
- StreamWriter sw = new StreamWriter(cst);
- sw.Write(data);
- sw.Flush();
- cst.FlushFinalBlock();
- sw.Flush();
- return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
- }
- /// <summary>
- /// 解密
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- public string Decode(string data)
- {
- byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
- byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);
- byte[] byEnc;
- try
- {
- byEnc = Convert.FromBase64String(data);
- }
- catch
- {
- return null;
- }
- DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
- MemoryStream ms = new MemoryStream(byEnc);
- CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
- StreamReader sr = new StreamReader(cst);
- return sr.ReadToEnd();
- }
- }
- private void btnMakeUsbKey_Click(object sender, EventArgs e)
- {
- string strMessage = "";
- MakeProductNumbers();
- if (UsbUtility.WriteUsbKeyFile(CurrentUSBDriveName, ProductNumbers, out strMessage))
- {
- MessageBox.Show("Usb Key File 生成成功!");
- }
- else
- {
- MessageBox.Show(strMessage);
- }
- }
- private void btnShowUsbKey_Click(object sender, EventArgs e)
- {
- string strMessage = "";
- string strText = UsbUtility.ReadUsbKeyFile(CurrentUSBDriveName, out strMessage);
- if (strText!="")
- {
- MessageBox.Show(strText,"查看USBKEY");
- }
- else
- {
- MessageBox.Show(strMessage,"Error");
- }
- }
- private string _CurrentUSBDriveName = "";
- /// <summary>
- /// 当前USB 驱动器号
- /// </summary>
- public string CurrentUSBDriveName
- {
- get
- {
- if (_CurrentUSBDriveName == "")
- {
- string[] strDrivers = Environment.GetLogicalDrives();
- _CurrentUSBDriveName = strDrivers[strDrivers.Length - 1];
- }
- return _CurrentUSBDriveName;
- }
- set
- {
- _CurrentUSBDriveName = value ;
- }
- }
在主窗体中(一定要在主窗体中,不能再用户控件中),加入下面的代码:
- public const int WM_DEVICECHANGE = 0x219;
- public const int DBT_DEVICEARRIVAL = 0x8000;
- public const int DBT_CONFIGCHANGECANCELED = 0x0019;
- public const int DBT_CONFIGCHANGED = 0x0018;
- public const int DBT_CUSTOMEVENT = 0x8006;
- public const int DBT_DEVICEQUERYREMOVE = 0x8001;
- public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
- public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
- public const int DBT_DEVICEREMOVEPENDING = 0x8003;
- public const int DBT_DEVICETYPESPECIFIC = 0x8005;
- public const int DBT_DEVNODES_CHANGED = 0x0007;
- public const int DBT_QUERYCHANGECONFIG = 0x0017;
- public const int DBT_USERDEFINED = 0xFFFF;
- protected override void WndProc(ref Message m)
- {
- try
- {
- if (m.Msg == WM_DEVICECHANGE)
- {
- switch (m.WParam.ToInt32())
- {
- case WM_DEVICECHANGE:
- break;
- case DBT_DEVICEARRIVAL://U盘插入
- DriveInfo[] s = DriveInfo.GetDrives();
- foreach (DriveInfo drive in s)
- {
- if (drive.DriveType == DriveType.Removable)
- {
- mpnUC.CurrentUSBDriveName = drive.Name.ToString();
- //
- MessageBox.Show("U盘已插入,盘符为:" + drive.Name.ToString() + "/r/n");
- break;
- }
- }
- break;
- case DBT_CONFIGCHANGECANCELED:
- break;
- case DBT_CONFIGCHANGED:
- break;
- case DBT_CUSTOMEVENT:
- break;
- case DBT_DEVICEQUERYREMOVE:
- break;
- case DBT_DEVICEQUERYREMOVEFAILED:
- break;
- case DBT_DEVICEREMOVECOMPLETE: //U盘卸载
- MessageBox.Show("U盘已卸载!");
- break;
- case DBT_DEVICEREMOVEPENDING:
- break;
- case DBT_DEVICETYPESPECIFIC:
- break;
- case DBT_DEVNODES_CHANGED:
- break;
- case DBT_QUERYCHANGECONFIG:
- break;
- case DBT_USERDEFINED:
- break;
- default:
- break;
- }
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- base.WndProc(ref m);
- }
mpnUC 是一个用户控件,我们设置了它的
CurrentUSBDriveName 属性。
OK,允许程序,我们就生成了一个USB Key 了。