using CCWin; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SufeiUtil; using SXLibrary; using System; using System.Collections.Generic; using System.Data.Common; using System.Data.SQLite; using System.IO; using System.Net; using System.Threading; using System.Windows.Forms; namespace MOKA_Factory_Tools { public partial class Download : Skin_Color { public string RequireHost;//请求的服务器地址 public string DownloadLink;//key包的下载地址 public string DownloadSize;//key包的大小 public string Ordername;//订单号 public string Ordernumber;//订单数量 public string Orderclient;//客户机型 public string OrderPID;//PID public string OrderSV;//软件版本 public string packet_md5;//key包的MD5校验 public bool[] threadendTag;//判断各线程是否接收完文件 public string[] filenameList;//各线程下载的小文件名列表 public int[] filestartpos;//各线程开始读取文件的位置 public int[] filesize;//小文件大小 public string url;//请求链接 public bool union;//判断文件是否合并完成 public int thread;//线程数 public int typeNow;//生成类型(-1:普通预绑定下载,0:EEPROM,1:FireTV) public SQLiteConnection errorDBNow; public int wholesize; public MidList midlistnow; public WhiteBalanceList whiteBalanceListnow; public string filename; public Download(System.Data.SQLite.SQLiteConnection errorDB, MidAddress MidAddress1,int type, MidList midList, WhiteBalanceList whiteBalanceList) { InitializeComponent(); skinLabel1.Text = LResource.DownloadKeys; this.Text = LResource.Download; Control.CheckForIllegalCrossThreadCalls = false; DownloadLink = MidAddress1.purl; DownloadSize = MidAddress1.psize; Ordername = MidAddress1.order; packet_md5 = MidAddress1.pmd5; Ordernumber = MidAddress1.number; Orderclient = MidAddress1.ctype; OrderPID = MidAddress1.pid; OrderSV = MidAddress1.version; RequireHost = MidAddress1.host; errorDBNow = errorDB; typeNow = type; midlistnow = midList; whiteBalanceListnow = whiteBalanceList; filename = Path.GetFileName(DownloadLink); } private void skinButton1_Click(object sender, EventArgs e) { this.Dispose(); this.Close(); } public void StartDownload() { url = DownloadLink; HttpWebRequest request; long filesizew = 0; try { request = (HttpWebRequest)HttpWebRequest.Create(url);//建立一个HTTP请求 HttpWebResponse response = request.GetResponse() as HttpWebResponse; filesizew = response.ContentLength;//得到文件总大小 response.Close(); request.Abort();//取消请求 } catch (Exception ex) { MessageBox.Show(LResource.Error + ": " + ex.Message, LResource.Error); Log.WriteErrorLog("\r\nCreate Http require error:"+ ex.Message); CommonMethod.ReportErrormsg("Fail to init download process", ex.Message + "\r\ndownload link:" + url, errorDBNow); return; } thread = 1;//单线程 threadendTag = new bool[thread]; filenameList = new string[thread]; filestartpos = new int[thread]; filesize = new int[thread]; int filethread = (int)filesizew / thread; int filethreade = filethread + (int)filesizew % thread; string filePath = AppDomain.CurrentDomain.BaseDirectory + "\\download"; //文件大小切割 for (int i = 0; i < thread; i++) { threadendTag[i] = false; filenameList[i] = filePath + "\\" + filename;//+ "-" + i.ToString() if (i < thread - 1) { filestartpos[i] = filethread * i; filesize[i] = filethread - 1; } else { filestartpos[i] = filethread * i; filesize[i] = filethreade - 1; } } Thread[] threadk = new Thread[thread]; HttpFile[] httpfile = new HttpFile[thread]; //各进程开始下载 for (int j = 0; j < thread; j++) { httpfile[j] = new HttpFile(this, j); threadk[j] = new Thread(new ThreadStart(httpfile[j].ReceiveFile)); threadk[j].Start(); } } private void Download_Shown(object sender, EventArgs e) { StartDownload(); } private void Download_FormClosed(object sender, FormClosedEventArgs e) { this.Dispose(); this.Close(); } } public class HttpFile { public Download formm;//声明一个窗体类 public int threadIndex;//进程标识 public string filenamea;//下载的小文件名 public string strUrl;//请求的链接 public FileStream fs; public HttpWebRequest request; public HttpWebResponse response; public Stream ns; public byte[] nbytes;//接收缓冲区 public int nreadsize;//接收字节数 public HttpFile(Download form, int thread) { formm = form; threadIndex = thread; } ~HttpFile() { formm.Dispose(); } public int GetThread { get { return threadIndex; } } public int GetFilesize { get { return formm.filesize[threadIndex]; } } public void ReceiveFile()//线程开始接收文件 { filenamea = formm.filenameList[threadIndex]; strUrl = formm.DownloadLink; ns = null; nbytes = new byte[1024]; nreadsize = 0; //formm.recevMsg.Items.Add("线程" + threadIndex.ToString() + "开始接收:" + "文件大小" + Math.Ceiling(formm.filesize[threadIndex] / 1024.0f) + "KB"); formm.ProgressBar1.Maximum = Convert.ToInt32(Math.Ceiling(formm.filesize[threadIndex] / 1024.0f)); fs = new FileStream(filenamea, FileMode.Create); string dbPath = AppDomain.CurrentDomain.BaseDirectory + "\\Keys\\" + formm.Ordername + ".db"; try { request = (HttpWebRequest)WebRequest.Create(strUrl); request.KeepAlive = false; //request.ProtocolVersion = HttpVersion.Version10; request.Proxy = WebRequest.DefaultWebProxy;//不使用代理,减少自动搜索代理的过程,提升性能 //要接收文件的字节范围 //request.AddRange(formm.filestartpos[threadIndex], formm.filestartpos[threadIndex] + formm.filesize[threadIndex]); request.Timeout = 5 * 60 * 1000; System.Net.ServicePointManager.DefaultConnectionLimit = 200; //ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"; response = request.GetResponse() as HttpWebResponse; ns = response.GetResponseStream(); int preocess = 0; long recSize = 0; do { nreadsize = ns.Read(nbytes, 0, nbytes.Length); if (nreadsize == 0) continue; recSize += (long)nreadsize; fs.Write(nbytes, 0, nreadsize); fs.Flush(); preocess += (int)Math.Ceiling(nreadsize / 1024.0f); if (preocess <= formm.ProgressBar1.Maximum) { formm.ProgressBar1.Value = preocess; } } while (recSize != response.ContentLength); fs.Close(); ns.Close(); response.Close(); GC.Collect(); Log.WriteGetKeyLog("Download key package success:" + formm.filename); if(!File.Exists(dbPath)) { if (SQLiteHelper.NewDbFile(dbPath)) { SQLiteHelper.NewTable(dbPath, "keys", "(sn varchar,keys varvhar,copy_date DATETIME,report_date DATETIME)"); SQLiteHelper.NewTable(dbPath, "mid", "(bid varchar,number varchar, pid varchar,ctype varvhar,version varvhar,host varchar,purl varvhar,psize varvhar,pmd5 varvhar,status varvhar,start_date DATETIME DEFAULT (datetime(CURRENT_TIMESTAMP,'localtime')),finish_date DATETIME,desc varvhar)"); SQLiteHelper.NewTable(dbPath, "report", "(url varchar,content varchar,gener_date DATETIME,report_date DATETIME)"); SQLiteHelper.NewTable(dbPath, "rokuCustomer", "(ordernum varchar,data varchar)"); SQLiteHelper.NewTable(dbPath, "whitebalance", "(ordernum varchar,hdmirgain varchar,hdmiggain varchar,hdmibgain varchar,nrgain varchar,nggain varchar,nbgain varchar,lrgain varchar,lggain varchar,lbgain varchar,updatetime DATETIME DEFAULT (datetime(CURRENT_TIMESTAMP,'localtime')))"); SQLiteHelper.NewTable(dbPath, "dsn", "(ordernum varchar,dsn varchar,updatetime DATETIME DEFAULT (datetime(CURRENT_TIMESTAMP,'localtime')))"); SQLiteHelper.AddOneLine(dbPath, new object[] { formm.Ordername, formm.Ordernumber, formm.OrderPID, formm.Orderclient, formm.OrderSV, formm.RequireHost, formm.DownloadLink, formm.DownloadSize, formm.packet_md5, "0" }); if (formm.midlistnow.rokuCustomer != null) { SQLiteHelper.AddRokuOneLine(dbPath, new object[] { formm.midlistnow.rokuCustomer.ordernum, JsonConvert.SerializeObject(formm.midlistnow.rokuCustomer).ToString() }); } if (formm.whiteBalanceListnow != null) { if (formm.whiteBalanceListnow.whiteBalanceInfo != null) { if (formm.whiteBalanceListnow.whiteBalanceInfo.isExemption != "1") { SQLiteHelper.AddwbOneLine(dbPath, new object[] { formm.whiteBalanceListnow.whiteBalanceInfo.ordernum, formm.whiteBalanceListnow.whiteBalanceInfo.hdmirgain, formm.whiteBalanceListnow.whiteBalanceInfo.hdmiggain, formm.whiteBalanceListnow.whiteBalanceInfo.hdmibgain, formm.whiteBalanceListnow.whiteBalanceInfo.nrgain, formm.whiteBalanceListnow.whiteBalanceInfo.nggain, formm.whiteBalanceListnow.whiteBalanceInfo.nbgain, formm.whiteBalanceListnow.whiteBalanceInfo.lrgain, formm.whiteBalanceListnow.whiteBalanceInfo.lggain, formm.whiteBalanceListnow.whiteBalanceInfo.lbgain } ); } } } if (formm.midlistnow.keytype.ContainsKey("DSN")) { SQLiteHelper.AdddsnOneLine(dbPath, new object[] { formm.Ordername, formm.midlistnow.keytype["DSN"] }); } } } } catch (Exception ex) { SQLiteHelper.UpdateStatus(dbPath, "0"); MessageBox.Show(ex.Message, LResource.Error) ; Log.WriteErrorLog("\r\nDownload error:" + ex.Message); CommonMethod.ReportErrormsg("Fail to download key package", ex.Message + "\r\ndownload link:" + formm.DownloadLink, formm.errorDBNow); fs.Close(); formm.Close(); GC.Collect(); return; } string keyinfo = ""; string downloadMD5 = GetMD5.GetMD5HashFromFile(filenamea); if (downloadMD5 == formm.packet_md5) { try { SQLiteHelper.UpdateTime(dbPath, formm.Ordername); List keyDatas = new List(); using (System.IO.StreamReader file = System.IO.File.OpenText(filenamea)) { using (JsonTextReader reader = new JsonTextReader(file)) { JArray o = (JArray)JToken.ReadFrom(reader); formm.ProgressBar1.Maximum = o.Count; int index = 0; formm.skinLabel1.Text = LResource.ParseKeys; foreach (var ss in o) //查找某个字段与值 { var sn = ((JObject)ss)["sn"]; var data = ((JObject)ss)["key"]; keyDatas.Add(new object[] { sn, data }); formm.ProgressBar1.Value = index; switch(formm.typeNow) { case -1: { break; } case 0: { if (!Countkey.CreateEEPROMKey(data.ToString(), formm.Ordername, out keyinfo, out string error)) { Log.WriteErrorLog("\r\nCreate EEPROM fail:\r\n" + error); MessageBox.Show(LResource.CreateEEPROMError + "\r\n" + error); formm.skinLabel1.Text = LResource.ParseKeysError; return; } break; } case 1: { if(!FireTVkey.CreateFireTVKeys(data.ToString(), formm.Ordername,out string error)) { Log.WriteErrorLog("\r\nCreate FireTV keys fail:\r\n" + error); MessageBox.Show( "生成FireTV订单离线key失败\r\n" + error); formm.skinLabel1.Text = LResource.ParseKeysError; return; } break; } } index++; } } } formm.skinLabel1.Text = LResource.ParseKeys; formm.skinLabel1.Text = LResource.InsertKeystoDB; if (formm.typeNow == 0) { MessageBox.Show("合成的Key类型有:" + keyinfo); } if (InsertKeys(dbPath, keyDatas)) { SQLiteHelper.UpdateStatus(dbPath, "1"); } else { MessageBox.Show(LResource.TransferDBFail); } } catch(Exception ex) { SQLiteHelper.UpdateStatus(dbPath, "0"); Log.WriteErrorLog(ex.Message); formm.Close(); GC.Collect(); return; } } else { SQLiteHelper.UpdateStatus(dbPath, "0"); MessageBox.Show("MD5 checking fail,please try again"+ downloadMD5); CommonMethod.ReportErrormsg("Key package MD5 checking fail", "MD5 checking error targetMD5:" + formm.packet_md5 + "\r\ndownload file MD5:" + downloadMD5, formm.errorDBNow); Log.WriteErrorLog("\r\nMD5 checking error targetMD5:" + formm.packet_md5 + "\r\ndownload file MD5:" + downloadMD5); } while (true) { /* GetAvailableThreads():检索由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。 而GetMaxThreads 检索可以同时处于活动状态的线程池请求的数目。 通过最大数目减可用数目就可以得到当前活动线程的数目,如果为零,那就说明没有活动线程,说明所有线程运行完毕。 */ ThreadPool.GetMaxThreads(out int maxWorkerThreads, out int portThreads); ThreadPool.GetAvailableThreads(out int workerThreads, out portThreads); if (maxWorkerThreads - workerThreads == 0) { Log.WriteGetKeyLog("Dowload thread Finished!"); break; } else { Thread.Sleep(500); Log.WriteGetKeyLog("Dowload thread unfinished!"); } } formm.Close(); } public bool InsertKeys(string dbPath, List keys) { try { SQLiteConnection sqliteConn = new SQLiteConnection("data source=" + dbPath); if (sqliteConn.State != System.Data.ConnectionState.Open) { sqliteConn.Open(); SQLiteCommand cmd = new SQLiteCommand(); cmd.Connection = sqliteConn; int index = 0; DbTransaction trans = sqliteConn.BeginTransaction(); foreach (var key in keys) { formm.ProgressBar1.Value = index; cmd.CommandText = string.Format("insert into keys(sn,keys) values('{0}','{1}')", key[0], key[1]); cmd.ExecuteNonQuery(); index++; } trans.Commit(); } sqliteConn.Close(); sqliteConn.Dispose(); return true; } catch (Exception ex) { Log.WriteErrorLog("\r\nFail to transfer key to DB:\r\n" + ex.Message); return false; } } } }