using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Threading;
namespace WindowsApplication5
{
    public partial class updates : Form
    {
        private WebClient update = new WebClient();
        public updates()
        {
            InitializeComponent();
        }
        //上传文件基于FTP模式
        #region 上传文件
        public  void FtpUpFile(string ftpServerIP, string filename, ProgressBar Prog, string ftpUserID, string ftpPassword)
        {
            FileInfo fileInf = new FileInfo(filename);
            string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
            FtpWebRequest reqFTP;
            // 根据uri创建FtpWebRequest对象
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));
            // ftp用户名和密码
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
            // 默认为true,连接不会被关闭
            // 在一个命令之后被执行
            reqFTP.KeepAlive = false;
            // 指定执行什么命令
            reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
            // 指定数据传输类型
            reqFTP.UseBinary = true;
            // 上传文件时通知服务器文件的大小
            reqFTP.ContentLength = fileInf.Length;
            Prog.Maximum =(int)fileInf.Length/1024;
            // 缓冲大小设置为2kb
            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int contentLen;
            // 打开一个文件流 (System.IO.FileStream) 去读上传的文件
            FileStream fs = fileInf.OpenRead();
            try
            {
                // 把上传的文件写入流
                Stream strm = reqFTP.GetRequestStream();
                // 每次读文件流的2kb
                contentLen = fs.Read(buff, 0, buffLength);
                // 流内容没有结束
                while (contentLen != 0)
                {
                    // 把内容从file stream 写入 upload stream
                    strm.Write(buff, 0, contentLen);
                    Prog.Value +=2;
                    contentLen = fs.Read(buff, 0, buffLength);
                }
                // 关闭两个流
                strm.Close();
                fs.Close();
                //labelX1.Text = "程序上传完毕";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Upload Error");
                labelX1.Text = "上传程序失败!";
            }

        }
        #endregion
        //下载文件基于ftp模式
        #region 下载文件ftp
        public  void FtpDownFile(string ftpServerIP, string fileName, ProgressBar Prog, string ftpUserID,string  ftpPassword)
        {
            FtpWebRequest reqFTP;
            try
            {
                FileStream outputStream = new FileStream(Application.StartupPath + "\\update\\" + fileName, FileMode.Create);
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileName));
                //reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(@"ftp://222.223.155.104//wwwroot/DeskHelper.asp"));

                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                Prog.Maximum =(int) cl/1024;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    Prog.Value +=2 ;
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }
                labelX1.Text = "程序下载完毕";
                ftpStream.Close();
                outputStream.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                labelX1.Text = "下载程序失败!";
            }
        }
        #endregion
        //下载进度http下载模式
        #region 下载文件http 进度条以及断点续传
        public static  void HttpDownFile(string URL, string Filename, ProgressBar Prog)
        {
          
    
            //////////////////////////////////////
            string StrFileName = Application.StartupPath + @"//update//" + Filename; //根据实际情况设置
            string StrUrl = URL; //根据实际情况设置
            //打开上次下载的文件或新建文件
            long lStartPos = 0;
            System.IO.FileStream fs;
            if (System.IO.File.Exists(StrFileName))
            {
                fs = System.IO.File.OpenWrite(StrFileName);
                lStartPos = fs.Length;
                fs.Seek(lStartPos, System.IO.SeekOrigin.Current); //移动文件流中的当前指针
                //MessageBox.Show("..");
            }
            else
            {
                fs = new System.IO.FileStream(StrFileName, System.IO.FileMode.Create);
                lStartPos = 0;
            }
           
            //打开网络连接
            try
            {
                ////////
                System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
                System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                 long totalBytes;
                 if (myrp.ContentLength > 0)
                 {
                     totalBytes = myrp.ContentLength;
                 }
                 else
                 {
                     MessageBox.Show("连接服务器失败!请先确保网络连通再使用在线升级功能");
                     totalBytes = lStartPos;
                    
                 }
                ////////
                Prog.Maximum = (int)(totalBytes/512+1);
                Prog.Value = (int)(lStartPos/512);
                myrp.Close();
                //MessageBox.Show("..");
                ////////
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(StrUrl);
                //MessageBox.Show("..");
               // MessageBox.Show(".-1.");
                if (lStartPos >= 0 && lStartPos < totalBytes)
                {
                    //MessageBox.Show(".0.");
                    request.AddRange((int)lStartPos); //设置Range值
                    //向服务器请求,获得服务器回应数据流
                    System.IO.Stream ns = request.GetResponse().GetResponseStream();
                    byte[] nbytes = new byte[512];
                    int nReadSize = 0;
                    nReadSize = ns.Read(nbytes, 0, 512);
                    //MessageBox.Show(".1.");
                  
                    while (nReadSize > 0)
                    {
                        fs.Write(nbytes, 0, nReadSize);
                        nReadSize = ns.Read(nbytes, 0, 512);
                        Prog.Value=Prog.Value+1;
                    }
                    Prog.Value = Prog.Maximum;
                    fs.Close();
                    ns.Close();
                }
               
                //Console.WriteLine("下载完成");
            }
            catch (Exception ex)
            {
               
                MessageBox.Show("下载过程中出现错误:" + ex.Message);
                fs.Close();
               
            }
            //////////////////////////////////
            //  System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
            //  System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
            //  long totalBytes = myrp.ContentLength;
            //  Prog.Maximum = (int)totalBytes;
               
            //  long totalDownloadedByte = 0;
            //  System.IO.Stream st = myrp.GetResponseStream();
            //  System.IO.Stream so = new System.IO.FileStream(@"update//" + Filename, System.IO.FileMode.Create);
            //try
            //{
              
            //    byte[] by = new byte[1024];
            //    int osize = st.Read(by, 0, (int)by.Length);
            //    while (osize > 0)
            //    {
            //        totalDownloadedByte = osize + totalDownloadedByte;
            //        Application.DoEvents();
            //        so.Write(by, 0, osize);
            //        Prog.Value = (int)totalDownloadedByte;
            //        osize = st.Read(by, 0, (int)by.Length);
            //    }
            //    //labelX1.Text = "程序下载完毕";
            //    so.Close();
            //    st.Close();
               
            //    myrp.Close();
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message); //labelX1.Text = "下载程序失败!";
            //    so.Close();
            //    st.Close();
            //    myrp.Close();
               
            //}
        }
        #endregion
        private void update_Load(object sender, EventArgs e)
        {
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            progressBar1.Visible = false;
            buttonX2.Enabled = false;
            buttonX1.Visible = true;
            buttonX1.Enabled = true;
            buttonX1.Text = "更新";
            labelX1.Visible = false;
            textBoxX2.Visible = false;
            textBoxX1.Text = "http://p.thec.cn/andyhebear/DeskHelper.rar";
       
        }
        private void buttonX1_Click2(object sender, EventArgs e)
        {
            //
            Thread thread = new Thread(new ThreadStart(buttonX1_Click));
            thread.IsBackground = true;
            thread.Start();
            /* 解决跨线程访问问题:
             *1, 在Form Load事件中加入
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            是最简单的方式,但是代价是程序的不安全性
             * 正确方法是:
             * UI上的控件不是线程安全的,所以跨线程的操作UI控件需要通过Invoke的方式:
                private object m_SyncObjectForListBox = new object();
                private void UpdateListBox(ListBox control, string text)
                {
                if (control.InvokeRequired)
                {
                SetTextCallback d = new SetTextCallback(UpdateListBox);
                this.Invoke(d, new object[] { control, text });
                }
                else
                {
                lock (m_SyncObjectForListBox)
                {
                    control.Items.Add(text);
                }
            }
            }
             * 例如(据说也可以使用委托关键字 Delegate)
             * listBox1.Items.Add("主机" + textBox1.Text + "端口" + textBox2.Text + "开始监听....\r\n");
                改为调用上面的方法:
                UpdateListBox(listBox1, "主机" + textBox1.Text + "端口" + textBox2.Text + "开始监听....\r\n");
             */
        }
        private void buttonX1_Click()
        {
          
            labelX1.Visible = true;
           
            buttonX1.Enabled = false;
            labelX1.Text = "程序更新中……请不要关闭程序!";
            string URL = @textBoxX1.Text;
            int n = URL.LastIndexOf('/');
            string fileName = URL.Substring(n + 1, URL.Length - n - 1);
            string url = URL.Substring(0,n-1);
            //MessageBox.Show("..");
            if (!(Directory.Exists(Application.StartupPath + "\\update")))
            {
                Directory.CreateDirectory(Application.StartupPath + "\\update");
            }
           // MessageBox.Show("..");
            //string file1=Application.StartupPath+"\\update\\DeskHelper";
            //string file2 = Application.StartupPath + "\\" + fileName;
            try
            {
                //update.DownloadFile(URL, Application.StartupPath + "\\update\\" + fileName);
                //HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(URL);
               // HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();
                // progressBarX1.Maximum = myRes.ContentLength;
                // progressBarX1.Minimum = 0;
                //progressBarX1.Value;
               // labelX1.Visible = true;
                progressBar1.Visible = true;
               // string ftpUserID="andyhebear";
                //string ftpPassword="19821210";
               
                //FtpDownFile(url, fileName, progressBar1, ftpUserID, ftpPassword);
              
               
                HttpDownFile(URL, fileName, progressBar1); 
              
               // myRes.Close();
            }
            catch (WebException ex) { MessageBox.Show(ex.Message, "Error"); labelX1.Text = "下载程序失败!"; }
            try
            {
                if (File.Exists(Application.StartupPath + "\\update\\" + fileName))
                {
                    //
                   
                    //File.Move(Application.StartupPath + "\\update\\" + fileName, Application.StartupPath + "\\update\\DeskHelper.rar" );
                    Process UnWinrar = new Process();
                    UnWinrar.StartInfo.FileName = "WinRAR.exe";
                    UnWinrar.StartInfo.Arguments = "e -o+ \"" + Application.StartupPath + "\\update\\" + fileName + "\"" + " \"" + Application.StartupPath + "\\update" + "\"";
                    UnWinrar.Start();
                    MessageBox.Show("解压缩完成!");
                    //File.Copy(Application.StartupPath + "\\update\\" + "DeskHelper.exe", Application.StartupPath + "\\DeskHelper", true);
                    //File.Copy(Application.StartupPath + "\\update\\" + "DeskHelper.vshost.exe", Application.StartupPath + "\\DeskHelper.vshost.exe", true);
                    Process ProZhongwen = new Process();
                    ProZhongwen.StartInfo.FileName = Application.StartupPath + "\\update\\setup.exe";
                    ProZhongwen.Start();
                    labelX1.Text = "程序更新完毕";
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
         
            buttonX2.Enabled = true;
           
            //this.Close();
        }
        private void buttonX2_Click(object sender, EventArgs e)
        {
            this.Close();
            this.Dispose();
        }
        private void buttonX3_Click(object sender, EventArgs e)
        {
            textBoxX2.Visible = true;
            if (textBoxX2.Text == "Rains")
                textBoxX1.Visible = true;
            else
            { textBoxX1.Visible = false; }
        }
    }
}