发现电脑里以前编写的下载程序。。。
做个记录,那时做的挺匆忙的,没用委托,通过公开出窗体来修改下载进度,做的比较乱... ==!!
程序具体功能(流程):
1.检测系统托盘图标内的进程名是否符合要求 (xp时可以,win7部分机器可以,该功能无意义)
2.抓取页面,进行正则匹配下载的文件地址(可以改成自己想要的任何情况)
3.开多线程下载(建立多个文件)
4.合并文件
5.下载完毕后,发送ipmsg
---下面是部分代码,个人认为有参考价值---
1.检测系统托盘图标内的进程名
1 #region P/Invoke 2 3 [DllImport("User32.dll", EntryPoint = "FindWindow")] 4 private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 5 6 [DllImport("User32.dll", EntryPoint = "FindWindowEx")] 7 private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, 8 string lpClassName, string lpWindowName); 9 10 //[DllImport("User32.dll", EntryPoint = "GetClientRect")] 11 //static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); 12 13 [DllImport("user32.dll", EntryPoint = "PostMessageA")] 14 private static extern int PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); 15 16 #endregion 17 18 private void btnFind_Click(object sender, EventArgs e) 19 { 20 SysTrayWnd.TrayItemData[] trayItems = SysTrayWnd.GetTrayWndDetail(); 21 this.dataGridView1.Columns.Clear(); 22 this.dataGridView1.Columns.Add("colTrayItemWinHandle", "窗口句柄"); 23 this.dataGridView1.Columns.Add("colTrayItemProcHandle", "进程句柄"); 24 this.dataGridView1.Columns.Add("colTrayItemPID", "进程ID"); 25 this.dataGridView1.Columns.Add("colTrayItemProcImagePath", "进程映象路径"); 26 this.dataGridView1.Columns.Add("colTrayItemIconTipText", "托盘图标提示内容"); 27 this.dataGridView1.Columns.Add("colTrayItemIconHandle", "托盘图标句柄"); 28 //this.dataGridView1.Columns.Add("colTrayItemIcon", "托盘图标"); 29 this.dataGridView1.Columns.Add(new DataGridViewImageColumn()); 30 this.dataGridView1.Columns[6].HeaderText = "托盘图标"; 31 this.dataGridView1.Columns[6].Name = "colTrayItemIcon"; 32 this.dataGridView1.Columns.Add("test", "test"); 33 34 this.dataGridView1.Rows.Add(trayItems.Length); 35 int iRowIndex = 0; 36 foreach (SysTrayWnd.TrayItemData trayItem in trayItems) 37 { 38 //窗口句柄 39 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemWinHandle"].Value = trayItem.hWnd.ToString("X").ToUpper(); 40 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemWinHandle"].ToolTipText = trayItem.hWnd.ToString(); 41 //进程句柄 42 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcHandle"].Value = trayItem.hProcess.ToString("X").ToUpper(); 43 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcHandle"].ToolTipText = trayItem.hProcess.ToString(); 44 //进程ID 45 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemPID"].Value = trayItem.dwProcessID.ToString(); 46 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemPID"].ToolTipText = trayItem.dwProcessID.ToString(); 47 //进程映象路径 48 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcImagePath"].Value = trayItem.lpProcImagePath; 49 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcImagePath"].ToolTipText = trayItem.lpProcImagePath; 50 //托盘图标提示内容 51 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconTipText"].Value = trayItem.lpTrayToolTip; 52 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconTipText"].ToolTipText = trayItem.lpTrayToolTip; 53 //托盘图标句柄 54 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconHandle"].Value = trayItem.hIcon.ToString("X").ToUpper(); 55 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconHandle"].ToolTipText = trayItem.hIcon.ToString(); 56 //托盘图标 ; 57 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIcon"].ValueType = typeof(byte[]); 58 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIcon"].Value = Icon.FromHandle(trayItem.hIcon); 59 this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconHandle"].ToolTipText = trayItem.hIcon.ToString(); 60 //test 61 System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(trayItem.dwProcessID); 62 this.dataGridView1.Rows[iRowIndex].Cells["test"].Value = p.ProcessName; 63 64 iRowIndex++; 65 } 66 67 doAboutHostCheck(trayItems); 68 } 69 70 private void doAboutHostCheck(SysTrayWnd.TrayItemData[] trayItems) 71 { 72 73 foreach (SysTrayWnd.TrayItemData trayItem in trayItems) 74 { 75 System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(trayItem.dwProcessID); 76 if (hostCheckPName.Equals(p.ProcessName)) 77 { 78 t.Stop(); 79 setFormValue("hostCheck错误发生,开始联网查找解决方案", null, null); 80 doDownload(); 81 break; 82 } 83 } 84 }
2.抓取页面,进行正则匹配下载的文件地址
3.开多线程下载(建立多个文件)
4.合并文件
1 // 变量定义 2 private Thread thread1 = null; 3 public string downFolder = @"\\10.164.2.44\software\norton\"; 4 public string webUrl = "http://www.symantec.com/security_response/definitions/download/detail.jsp?gid=savce"; 5 public string regPatten = "http://definitions.symantec.com/([^\"]*)v([^\"]*)32.exe"; 6 7 // 下载参数初期化 8 private void btnStart_Click(object sender, EventArgs e) 9 { 10 // 多线程下载停止flg 11 constant.stopDL = false; 12 // 从画面读取参数 13 webUrl = txtUrl.Text; 14 regPatten = txtReg.Text; 15 downFolder = txtFolder.Text.EndsWith("\\") ? txtFolder.Text : txtFolder.Text+"\\"; 16 gapTime = long.Parse(txtGap.Text); 17 18 t1.Tick += new EventHandler(t1_Tick); 19 t1.Interval = 10000; 20 21 t.Interval = (int)gapTime; 22 // 定义线程 23 thread1 = new Thread(new ThreadStart(doDownLoadThread)); 24 t.Tick += new EventHandler(t_Tick); 25 t.Start(); 26 t_Tick(null, new EventArgs()); 27 // 可以直接调用 doDownload 方法 28 } 29 30 // 下载方法入口 31 // 使用WebBrowser控件打开页面 32 private void doDownload() 33 { 34 string url = webUrl; 35 WebBrowser wb = new WebBrowser(); 36 // 忽略js脚本错误 37 wb.ScriptErrorsSuppressed = true; 38 // 打开网页 39 wb.Navigate(url); 40 setFormValue("正在打开网页", null, null); 41 // 页面加载完了事件绑定 42 wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); 43 } 44 45 // WebBrowser控件页面加载完了事件 46 void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 47 { 48 constant.innerHtml = ((WebBrowser)sender).Document.Body.InnerHtml; 49 thread1.Start(); 50 } 51 52 // 下载主线程 53 public void doDownLoadThread() 54 { 55 setFormValue("打开完成,开始查找文件地址", null, null); 56 // 正则匹配 57 MatchCollection mts = Regex.Matches(constant.innerHtml, regPatten, RegexOptions.Multiline | RegexOptions.IgnoreCase); 58 // 一般一个,可以不用循环,判断一下是否有就行了 59 foreach (Match item in mts) 60 { 61 setFormValue("下载文件:" + item.Value, null, null); 62 string fileName = item.Value.Split('/')[(item.Value.Split('/').Length - 1)]; 63 // 开始多线程下载 64 multiThreadDownLoad MTDL = new multiThreadDownLoad(); 65 MTDL.doDownLoadFile(item.Value, fileName, this); 66 // 只下载第一个 67 break; 68 } 69 } 70 71 // 开始多线程下载类 72 public class multiThreadDownLoad 73 { 74 // 文件总大小 75 public static long showAllBytes = 0; 76 // 线程个数 77 public static int threadCount = 10; 78 // 线程状态 79 public static List<bool> threadSts = new List<bool>(); 80 // 线程池 81 public static List<Thread> threadLst = new List<Thread>(); 82 private List<oneThread> oneThLst = new List<oneThread>(); 83 public static List<long[]> threadStEnLst = new List<long[]>(); 84 // 下载进度 85 public static long currentDownloaded = 0; 86 // 下载停止flg 87 public static bool stopDownloadFlg = false; 88 // 临时文件夹路径 89 public static string tmpFolder = @"hostcheckTmp\"; 90 // 最终文件路径 91 public static string finalFile = ""; 92 93 public static string tempFloder = ""; 94 // winform窗体 95 public static Form1 frm; 96 97 // 多线程下载入口 98 public bool doDownLoadFile(string url, string name, Form1 frm1) 99 { 100 // 初期化数据 101 bool result = true; 102 frm = frm1; 103 int thCount = 1; 104 threadCount = int.TryParse(frm.txtThreads.Text, out thCount) ? thCount : 1; 105 finalFile = frm1.downFolder + name; 106 string mainFolder = frm1.downFolder.EndsWith("\\") ? frm1.downFolder : frm1.downFolder + "\\"; 107 string tmpFolder0 = mainFolder + tmpFolder; 108 tempFloder = tmpFolder0; 109 try 110 { 111 // 获取文件总大小 112 System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); 113 System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse(); 114 long totalBytes = myrp.ContentLength; 115 Myrq.Abort(); 116 showAllBytes = totalBytes; 117 // 判断文件是否存在,并处理 118 if (File.Exists(frm1.downFolder + name)) 119 { 120 frm1.setFormValue("已经存在文件", 100, 100); 121 } 122 else 123 { 124 // 文件不存在,创建临时目录 125 if (!Directory.Exists(tmpFolder0)) 126 { 127 Directory.CreateDirectory(tmpFolder0); 128 } 129 // 计算每个线程的目标下载量与下载开始位置 130 long eachBytes = totalBytes / threadCount; 131 long startPos = 0; 132 for (int i = 0; i < threadCount; i++) 133 { 134 if (threadCount != (i + 1)) 135 { 136 // 普通线程对象 137 oneThLst.Add(new oneThread(eachBytes * i, eachBytes - 1, new string[] { tmpFolder0, i.ToString(), url })); 138 } 139 else 140 { 141 // 最后一个线程对象 142 oneThLst.Add(new oneThread(eachBytes * i, eachBytes + (int)(totalBytes % threadCount) - 1, new string[] { tmpFolder0, i.ToString(), url })); 143 } 144 // 加入线程列表,并启动下载 145 threadLst.Add(new Thread(new ThreadStart(oneThLst[i].doDownloadThread))); 146 threadSts.Add(false); 147 } 148 149 for (int i = 0; i < threadLst.Count; i++) 150 { 151 // 后台运行 152 threadLst[i].IsBackground = true; 153 threadLst[i].Start(); 154 } 155 // 开启合并线程的监控 156 Thread combThread = new Thread(new ThreadStart(combFiles)); 157 combThread.IsBackground = true; 158 combThread.Start(); 159 } 160 } 161 catch (Exception e) 162 { 163 result = false; 164 } 165 return result; 166 } 167 168 // 合并文件 169 public void combFiles() 170 { 171 // 检查线程状态 172 bool alive = false; 173 do 174 { 175 alive = false; 176 foreach (bool sts in threadSts) 177 { 178 if (!sts) { alive = true; } 179 } 180 if (!alive) 181 { 182 // 人为停止时 183 if (constant.stopDL) 184 { 185 try 186 { 187 Directory.Delete(tempFloder, false); 188 } 189 catch (Exception) { } 190 frm.setFormValue("已经停止", 100, 100); 191 } 192 // 下载结束时 193 else 194 { 195 if (!File.Exists(finalFile)) 196 { 197 frm.setFormValue("开始合并文件", 100, 100); 198 File.Copy(tempFloder + "tmp0", finalFile); 199 File.Delete(tempFloder + "tmp0"); 200 FileStream AddStream = new FileStream(finalFile, FileMode.Append); 201 BinaryWriter AddWriter = new BinaryWriter(AddStream); 202 for (int i = 1; i < threadLst.Count; i++) 203 { 204 FileStream TempStream = new FileStream(tempFloder + "tmp" + i.ToString(), FileMode.Open); 205 BinaryReader TempReader = new BinaryReader(TempStream); 206 AddWriter.Write(TempReader.ReadBytes((int)TempStream.Length)); 207 TempReader.Close(); 208 TempStream.Close(); 209 File.Delete(tempFloder + "tmp" + i.ToString()); 210 } 211 AddWriter.Close(); 212 AddStream.Close(); 213 Directory.Delete(tempFloder, false); 214 215 frm.setFormValue("下载完成", 100, 100); 216 // 启动ipmsg发送消息 217 Thread thIpmsg = new Thread(new ThreadStart(sendIpmsg)); 218 thIpmsg.IsBackground = true; 219 thIpmsg.Start(); 220 } 221 } 222 } 223 else 224 { 225 Thread.Sleep(1000); 226 } 227 } while (alive || constant.stopDL); 228 } 229 230 // 下载线程类 231 232 class oneThread 233 { 234 // 需要下载的文件地址,开始位置,数据量,临时目录等 235 public long startPosP; 236 public long eachBytesP; 237 //new string[]{tmpFolder0,i.ToString(),url,threadStEnLst[i][0].ToString(),threadStEnLst[i][1].ToString() 238 239 public string tmpFolder0; 240 public string i; 241 public string url; 242 public long allByte; 243 244 // 构造函数,初期化变量 245 public oneThread(long startPos, long eachBytes, object getList) 246 { 247 startPosP = startPos; 248 allByte = eachBytes; 249 tmpFolder0 = ((string[])getList)[0]; 250 i = ((string[])getList)[1]; 251 url = ((string[])getList)[2]; 252 } 253 254 // 下载方法 255 public void doDownloadThread() 256 { 257 try 258 { 259 if (!File.Exists(tmpFolder0 + "tmp" + i.ToString())) 260 { 261 // 创建文件 262 System.IO.Stream so = new System.IO.FileStream(tmpFolder0 + "tmp" + i.ToString(), System.IO.FileMode.Create); 263 // 创建网络链接 264 System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); 265 // 设置数据接收开始位置,结束位置 266 Myrq.AddRange((int)startPosP, (int)(startPosP + allByte)); 267 // 以1024byte为单位读取下载 268 System.IO.Stream st = ((System.Net.HttpWebResponse)Myrq.GetResponse()).GetResponseStream(); 269 long totalBytes = ((System.Net.HttpWebResponse)Myrq.GetResponse()).ContentLength; 270 long totalDownloadedByte = 0; 271 byte[] by = new byte[1024]; 272 int osize = st.Read(by, 0, (int)by.Length); 273 while (osize > 0 && !constant.stopDL) 274 { 275 totalDownloadedByte = osize + totalDownloadedByte; 276 so.Write(by, 0, osize); 277 osize = st.Read(by, 0, (int)by.Length); 278 // 更新总下载进度 279 multiThreadDownLoad.currentDownloaded += osize; 280 multiThreadDownLoad.frm.setFormValue("下载文件:" + multiThreadDownLoad.currentDownloaded / 1024 + "/" + multiThreadDownLoad.showAllBytes / 1024, (int)(multiThreadDownLoad.currentDownloaded / 1024), (int)(multiThreadDownLoad.showAllBytes / 1024)); 281 } 282 so.Close(); 283 st.Close(); 284 Myrq.Abort(); 285 if (constant.stopDL) { 286 File.Delete(tmpFolder0 + "tmp" + i.ToString()); 287 } 288 multiThreadDownLoad.threadSts[int.Parse(i)] = true; 289 } 290 } 291 catch (Exception e) 292 { 293 multiThreadDownLoad.threadSts[int.Parse(i)] = true; 294 } 295 } 296 }
5.下载完毕后,发送ipmsg
1 // 发送ipmsg方法入口 2 public void sendIpmsg() { 3 // 配置文件读取目标ip 4 string[] ipList = ConfigurationManager.AppSettings["ipList"].Split(','); 5 for (int i = 0; i < ipList.Length; i++) 6 { 7 UdpClient client = new UdpClient(1988); 8 IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ipList[i]), 2425); 9 byte[] bytes = Encoding.Default.GetBytes(string.Concat(new object[] { "1:", DateTime.Now.Ticks, ":", "HostCheck", ":", "HostCheck", ":", 0x20, ":", "downloadComplete[" + finalFile + "]" })); 10 client.Send(bytes, bytes.Length, endPoint); 11 Thread.Sleep(1000); 12 client.Close(); 13 client = null; 14 } 15 16 }
6.一般服务器只允许开启2个线程进行下载
需在配置文件里使用下面配置
1 <system.net> 2 <connectionManagement> 3 <add address="*" maxconnection="最大连接数"/> 4 </connectionManagement> 5 </system.net>
----
CSND参考代码下载: