Browse Source

修改更新功能

yuzhengyang 8 years ago
parent
commit
44434961e4

BIN
Fork.Net/Dlls/Fork.Net/Y.Utils.dll


+ 1 - 1
Fork.Net/Oreo.VersionBuilder/Commons/P.cs

@@ -18,7 +18,7 @@ namespace Oreo.VersionBuilder.Commons
         static void InitLog()
         {
             R.Log = new Log();
-            R.Log.SetWriteFile(true, "Oreo.CleverDog.Log");
+            R.Log.SetWriteFile(true, "Oreo.VersionBuilder.Log");
             R.Log.LogLevel = LogLevel.All;
         }
     }

+ 12 - 4
Fork.Net/Oreo.VersionUpdate/Commons/P.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using Y.Utils.IOUtils.LogUtils;
+using Y.Utils.IOUtils.TxtUtils;
 
 namespace Oreo.VersionUpdate.Commons
 {
@@ -11,13 +12,20 @@ namespace Oreo.VersionUpdate.Commons
     {
         public static void Init()
         {
+            InitSettings();
+
             InitLog();
         }
-
+        static void InitSettings()
+        {
+            IniTool.GetStringValue(R.Files.Settings, "Version", "Number", R.Settings.Version.Number);
+            R.LogLevel = (LogLevel)IniTool.GetIntValue(R.Files.Settings, "Log", "Level");
+        }
         static void InitLog()
-        { 
-            R.Log.SetWriteFile(true, "Oreo.CleverDog.Log");
-            R.Log.LogLevel = LogLevel.All;
+        {
+            R.Log.SetWriteFile(true, "Oreo.VersionUpdate.Log");
+            R.Log.LogLevel = R.LogLevel;
         }
+       
     }
 }

+ 24 - 1
Fork.Net/Oreo.VersionUpdate/Commons/R.cs

@@ -1,21 +1,44 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows.Forms;
 using Y.Utils.IOUtils.LogUtils;
 
 namespace Oreo.VersionUpdate.Commons
 {
     public class R
     {
+        internal static string AppName = "Oreo.VersionUpdate";
+        internal static DateTime StartTime = DateTime.Now;
+        internal static string MachineName = Environment.MachineName;
+        internal static Module Module = Assembly.GetExecutingAssembly().GetModules()[0];
+        internal static string AesKey = "12345678901234567890123456789012";
         public static Log Log = new Log();
+        public static LogLevel LogLevel = LogLevel.None;
 
+        public static class Paths
+        {
+            public static string App = AppDomain.CurrentDomain.BaseDirectory;
+            public static string Temp = App + "Temp\\";
+        }
+        public static class Files
+        {
+            public static string App = Application.ExecutablePath;
+            public static string Settings = Paths.App + "\\upd.ini";
+            public static string Whatsnew = Paths.App + "\\Whatsnew.txt";
+        }
         public static class Settings
         {
+            public static class Version
+            {
+                public static string Number = "0.0.0.0";
+            }
             public static class FTP
             {
-                public static string Address = "ftp://192.168.3.56";
+                public static string Address = "192.168.3.56";
                 public static string Account = "Administrator";
                 public static string Password = "yuzhengyang";
             }

+ 6 - 4
Fork.Net/Oreo.VersionUpdate/Oreo.VersionUpdate.csproj

@@ -50,9 +50,6 @@
     <Reference Include="Y.Skin">
       <HintPath>..\Dlls\Fork.Net\Y.Skin.dll</HintPath>
     </Reference>
-    <Reference Include="Y.Utils">
-      <HintPath>..\Dlls\Fork.Net\Y.Utils.dll</HintPath>
-    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Commons\P.cs" />
@@ -92,7 +89,12 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <ProjectReference Include="..\Y.Utils\Y.Utils.csproj">
+      <Project>{5b8eeec7-aeb5-407d-9dc1-1c59e53f78d5}</Project>
+      <Name>Y.Utils</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 115 - 2
Fork.Net/Oreo.VersionUpdate/Views/MainForm.Designer.cs

@@ -28,20 +28,133 @@
         /// </summary>
         private void InitializeComponent()
         {
+            this.label2 = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.LbVersionNumber = new System.Windows.Forms.Label();
+            this.LbPluginName = new System.Windows.Forms.Label();
+            this.LbUpdateDetail = new System.Windows.Forms.Label();
+            this.label9 = new System.Windows.Forms.Label();
+            this.LbCodeName = new System.Windows.Forms.Label();
+            this.progressBar1 = new System.Windows.Forms.ProgressBar();
             this.SuspendLayout();
             // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.ForeColor = System.Drawing.Color.White;
+            this.label2.Location = new System.Drawing.Point(12, 32);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(65, 12);
+            this.label2.TabIndex = 1;
+            this.label2.Text = "更新插件:";
+            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.ForeColor = System.Drawing.Color.White;
+            this.label3.Location = new System.Drawing.Point(236, 9);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(65, 12);
+            this.label3.TabIndex = 2;
+            this.label3.Text = "新版本号:";
+            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // LbVersionNumber
+            // 
+            this.LbVersionNumber.Cursor = System.Windows.Forms.Cursors.Hand;
+            this.LbVersionNumber.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+            this.LbVersionNumber.ForeColor = System.Drawing.Color.White;
+            this.LbVersionNumber.Location = new System.Drawing.Point(305, 9);
+            this.LbVersionNumber.Name = "LbVersionNumber";
+            this.LbVersionNumber.Size = new System.Drawing.Size(102, 12);
+            this.LbVersionNumber.TabIndex = 4;
+            this.LbVersionNumber.Text = "1.0.0.0";
+            this.LbVersionNumber.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            this.LbVersionNumber.Click += new System.EventHandler(this.LbVersionNumber_Click);
+            // 
+            // LbPluginName
+            // 
+            this.LbPluginName.ForeColor = System.Drawing.Color.White;
+            this.LbPluginName.Location = new System.Drawing.Point(81, 32);
+            this.LbPluginName.Name = "LbPluginName";
+            this.LbPluginName.Size = new System.Drawing.Size(326, 12);
+            this.LbPluginName.TabIndex = 5;
+            this.LbPluginName.Text = "无";
+            this.LbPluginName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // LbUpdateDetail
+            // 
+            this.LbUpdateDetail.ForeColor = System.Drawing.Color.White;
+            this.LbUpdateDetail.Location = new System.Drawing.Point(14, 93);
+            this.LbUpdateDetail.Name = "LbUpdateDetail";
+            this.LbUpdateDetail.Size = new System.Drawing.Size(395, 31);
+            this.LbUpdateDetail.TabIndex = 7;
+            this.LbUpdateDetail.Text = "准备更新……";
+            // 
+            // label9
+            // 
+            this.label9.AutoSize = true;
+            this.label9.ForeColor = System.Drawing.Color.White;
+            this.label9.Location = new System.Drawing.Point(12, 9);
+            this.label9.Name = "label9";
+            this.label9.Size = new System.Drawing.Size(65, 12);
+            this.label9.TabIndex = 8;
+            this.label9.Text = "更新代号:";
+            this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // LbCodeName
+            // 
+            this.LbCodeName.ForeColor = System.Drawing.Color.White;
+            this.LbCodeName.Location = new System.Drawing.Point(81, 9);
+            this.LbCodeName.Name = "LbCodeName";
+            this.LbCodeName.Size = new System.Drawing.Size(149, 12);
+            this.LbCodeName.TabIndex = 9;
+            this.LbCodeName.Text = "扬帆起航";
+            this.LbCodeName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+            // 
+            // progressBar1
+            // 
+            this.progressBar1.Location = new System.Drawing.Point(14, 61);
+            this.progressBar1.Maximum = 1000;
+            this.progressBar1.Name = "progressBar1";
+            this.progressBar1.Size = new System.Drawing.Size(395, 23);
+            this.progressBar1.TabIndex = 10;
+            // 
             // MainForm
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(284, 261);
+            this.BackColor = System.Drawing.SystemColors.Highlight;
+            this.ClientSize = new System.Drawing.Size(425, 135);
+            this.Controls.Add(this.progressBar1);
+            this.Controls.Add(this.LbCodeName);
+            this.Controls.Add(this.label9);
+            this.Controls.Add(this.LbUpdateDetail);
+            this.Controls.Add(this.LbPluginName);
+            this.Controls.Add(this.LbVersionNumber);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.label2);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
             this.Name = "MainForm";
-            this.Text = "MainForm";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+            this.Text = "正在准备升级……";
             this.Load += new System.EventHandler(this.MainForm_Load);
             this.ResumeLayout(false);
+            this.PerformLayout();
 
         }
 
         #endregion
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label LbVersionNumber;
+        private System.Windows.Forms.Label LbPluginName;
+        private System.Windows.Forms.Label LbUpdateDetail;
+        private System.Windows.Forms.Label label9;
+        private System.Windows.Forms.Label LbCodeName;
+        private System.Windows.Forms.ProgressBar progressBar1;
     }
 }

+ 248 - 8
Fork.Net/Oreo.VersionUpdate/Views/MainForm.cs

@@ -5,23 +5,37 @@ using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
 using System.Drawing;
+using System.IO;
 using System.Linq;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using System.Windows.Forms;
 using Y.Utils.DataUtils.Collections;
+using Y.Utils.DataUtils.JsonUtils;
+using Y.Utils.IOUtils.FileUtils;
+using Y.Utils.IOUtils.PathUtils;
+using Y.Utils.IOUtils.TxtUtils;
+using Y.Utils.NetUtils.FTPUtils;
+using Y.Utils.WindowsUtils.ProcessUtils;
 
 namespace Oreo.VersionUpdate.Views
 {
     public partial class MainForm : Form
     {
+        const int DETAIL_SHOWTIME = 1000;
+
+        string VersionNumber = "";
+        string VersionDesc = "";
+        string TempFile = "Temp";
+
         public MainForm()
         {
             InitializeComponent();
         }
         private void MainForm_Load(object sender, EventArgs e)
         {
-
+            StartUpdate();
         }
         private void StartUpdate()
         {
@@ -36,8 +50,27 @@ namespace Oreo.VersionUpdate.Views
         }
         private void StartUpdateStandard()
         {
-            R.Log.i("读取标准更新版本号");
+            R.Log.i("读取本地标准更新版本号");
             string versionNumber = GetStandardVersionNumber();
+            R.Log.i("读取当前标准版本 " + versionNumber + ",准备请求服务器新版本");
+            VersionModel standardNewVersion = GetStandardNewVersion(versionNumber);
+            if (standardNewVersion != null)
+            {
+                R.Log.i("有新的更新,版本号 " + standardNewVersion.VersionNumber);
+                bool flag = Update(standardNewVersion);
+                if (flag)
+                {
+                    R.Log.i(versionNumber + " 更新成功,当前版本" + standardNewVersion.VersionNumber);
+                }
+                else
+                {
+                    R.Log.w(versionNumber + " 更新失败");
+                }
+            }
+            else
+            {
+                R.Log.i("当前标准版本为最新,不需要更新");
+            }
         }
         private void StartUpdatePlugin()
         {
@@ -63,6 +96,10 @@ namespace Oreo.VersionUpdate.Views
                             R.Log.w(x.Name + " 更新失败");
                         }
                     }
+                    else
+                    {
+                        R.Log.i("当前插件版本为最新版本,不需要更新");
+                    }
                 });
             }
             else
@@ -79,27 +116,225 @@ namespace Oreo.VersionUpdate.Views
         }
         private string GetStandardVersionNumber()
         {
-            string rs = "";
+            string rs = R.Settings.Version.Number;
             return rs;
         }
         #endregion
         #region 读取网络数据操作
+        private VersionModel GetStandardNewVersion(string vn)
+        {
+            VersionModel rs = JsonTool.ToObjFromFile<VersionModel>(@"D:\CoCo\GitHub\Fork\Fork.Net\Oreo.VersionBuilder\bin\Debug\VersionFile\0527112916.version");
+            return rs;
+        }
         private VersionModel GetPluginNewVersion(PluginModel pm)
         {
-            VersionModel rs = null;
+            VersionModel rs = JsonTool.ToObjFromFile<VersionModel>(@"D:\CoCo\GitHub\Fork\Fork.Net\Oreo.VersionBuilder\bin\Debug\VersionFile\0527112916.version");
             return rs;
         }
         #endregion
         #region 更新操作
         private bool Update(VersionModel vm)
         {
+            VersionNumber = vm.VersionNumber;
+            VersionDesc = vm.VersionDesc;
+            TempFile = Guid.NewGuid().ToString();
+            if (DirTool.Create(R.Paths.Temp + TempFile))
+            {
+                R.Log.i("创建临时存放文件目录 " + R.Paths.Temp + TempFile);
+
+                R.Log.i("将版本信息显示到 UI");
+                UILoadVersion(vm);
+                UpdateBefore(vm);
+
+                if (UpdateDownload(vm))
+                {
+                    R.Log.i("文件已下载成功");
+                    if (UpdateInstead(vm))
+                    {
+                        R.Log.i("文件已替换,准备执行清理任务");
+                        UpdateClean(vm);
+
+
+                        R.Log.i("配置文件信息更新完毕,准备写入新版本配置和描述信息");
+                        UpdateConfig(vm);
+                        UpdateWhatsnew(vm);
+                        UpdateAfter(vm);
+                        return true;
+                    }
+                    else
+                    {
+                        R.Log.w("文件替换失败,当前更新失败");
+                    }
+                }
+                else
+                {
+                    R.Log.w("文件下载失败,当前更新失败");
+                }
+            }
+            else
+            {
+                R.Log.i("创建临时存放文件目录 " + R.Paths.Temp + TempFile + " 失败,中止更新");
+            }
+            return false;
+        }
+        private void UpdateBefore(VersionModel vm)
+        {
+            if (ListTool.HasElements(vm.BeforeUpdateKillProcess))
+            {
+                foreach (var p in vm.BeforeUpdateKillProcess)
+                {
+                    if (!string.IsNullOrWhiteSpace(p))
+                        ProcessTool.KillProcess(p);
+                }
+            }
+            if (ListTool.HasElements(vm.BeforeUpdateStartProcess))
+            {
+                foreach (var p in vm.BeforeUpdateStartProcess)
+                {
+                    if (!string.IsNullOrWhiteSpace(p))
+                        ProcessTool.StartProcess(p);
+                }
+            }
+        }
+        private bool UpdateDownload(VersionModel vm)
+        {
+            FileCodeTool fcode = new FileCodeTool();
+            var downFile = vm.FileList.Where(x => x.IsClean == false);
+            if (vm != null && ListTool.HasElements(downFile))
+            {
+                foreach (var file in vm.FileList)
+                {
+                    R.Log.v("当前处理文件:" + file.ServerFile);
+                    string serverFile = DirTool.Combine(vm.ServerPath, file.ServerFile);
+                    string tempFile = DirTool.Combine(R.Paths.Temp, TempFile, file.ServerFile);//下载到目标位置(带文件名)
+                    string localFile = DirTool.IsDriver(file.LocalFile) ? file.LocalFile : DirTool.Combine(R.Paths.App, file.LocalFile);//旧文件位置
+                    if (fcode.GetMD5(localFile) != file.FileMD5)
+                    {
+                        UIUpdateDetail("准备下载:" + Path.GetFileName(file.ServerFile));
+                        R.Log.v("MD5码不相同,准备下载");
+                        FtpHelper ftp = new FtpHelper(R.Settings.FTP.Address, R.Settings.FTP.Account, R.Settings.FTP.Password);
+                        if (!ftp.Download(serverFile, tempFile))
+                            if (!ftp.Download(serverFile, tempFile))
+                                if (!ftp.Download(serverFile, tempFile))
+                                {
+                                    R.Log.v("更新文件无法被下载,请检查网络重试");
+                                    return false;
+                                }
+                    }
+                    else
+                    {
+                        UIUpdateDetail("文件已存在:" + Path.GetFileName(file.ServerFile));
+                    }
+                }
+                return true;
+            }
             return false;
         }
+        private bool UpdateInstead(VersionModel vm)
+        {
+            var insteadFile = vm.FileList.Where(x => x.IsClean == false);
+            foreach (var file in insteadFile)
+            {
+                string tempFile = DirTool.Combine(R.Paths.Temp, TempFile, file.ServerFile);//下载到目标位置(带文件名)
+                string localFile = DirTool.IsDriver(file.LocalFile) ? file.LocalFile : DirTool.Combine(R.Paths.App, file.LocalFile);//旧文件位置
+
+                if (File.Exists(tempFile))
+                {
+                    try
+                    {
+                        DirTool.Create(DirTool.GetFilePath(localFile));
+                        File.Copy(tempFile, localFile, true);
+                        UIUpdateDetail("正在更新:" + file.LocalFile);
+                    }
+                    catch (Exception e)
+                    {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        private void UpdateClean(VersionModel vm)
+        {
+            //清理临时文件夹
+            if (Directory.Exists(R.Paths.Temp))
+            {
+                try { Directory.Delete(R.Paths.Temp, true); } catch { }
+                UIUpdateDetail("正在清理临时文件夹:Temp");
+            }
+            //清理指定文件
+            var cleanFile = vm.FileList.Where(x => x.IsClean == true);
+            foreach (var file in cleanFile)
+            {
+                string fff = DirTool.IsDriver(file.LocalFile) ? file.LocalFile : R.Paths.App + file.LocalFile;
+                if (File.Exists(fff))
+                {
+                    try { File.Delete(fff); } catch { }
+                    UIUpdateDetail("正在清理指定位置文件:" + fff);
+                }
+            }
+        }
+        private void UpdateConfig(VersionModel vm)
+        {
+            if (string.IsNullOrWhiteSpace(vm.PluginName) || string.IsNullOrWhiteSpace(vm.PluginEntry))
+            {
+                //标准版本更改设置
+                IniTool.WriteValue(R.Files.Settings, "Version", "Number", vm.VersionNumber);
+                UIUpdateDetail("修改主版本号:" + vm.VersionNumber);
+            }
+            else
+            {
+                //插件版本更改设置
+                UIUpdateDetail("修改插件版本号:" + vm.PluginName + " " + vm.VersionNumber);
+            }
+        }
+        private void UpdateWhatsnew(VersionModel vm)
+        {
+            TxtTool.Append(R.Files.Whatsnew, string.Format("{0} {1} {2}",
+                    vm.CodeName, vm.VersionNumber, (vm.PluginName == "" ? "" : "For:" + vm.PluginName)));
+            TxtTool.Append(R.Files.Whatsnew, vm.VersionDesc);
+            TxtTool.Append(R.Files.Whatsnew, new string('=', 50));
+            UIUpdateDetail("添加新版本特性说明 Whatsnew.txt");
+        }
+        private void UpdateAfter(VersionModel vm)
+        {
+            if (ListTool.HasElements(vm.AfterUpdateKillProcess))
+            {
+                foreach (var p in vm.AfterUpdateKillProcess)
+                {
+                    if (!string.IsNullOrWhiteSpace(p))
+                        ProcessTool.KillProcess(p);
+                }
+            }
+            if (ListTool.HasElements(vm.AfterUpdateStartProcess))
+            {
+                foreach (var p in vm.AfterUpdateStartProcess)
+                {
+                    if (!string.IsNullOrWhiteSpace(p))
+                        ProcessTool.StartProcess(p);
+                }
+            }
+            UIUpdateDetail("当前更新完成");
+        }
         #endregion
         #region UI操作
-        /// <summary>
-        /// 退出程序
-        /// </summary>
+        void UIUpdateDetail(string s)
+        {
+            Invoke(new Action(() =>
+            {
+                LbUpdateDetail.Text = s;
+            }));
+            Thread.Sleep(DETAIL_SHOWTIME);
+        }
+        void UILoadVersion(VersionModel vm)
+        {
+            Invoke(new Action(() =>
+            {
+                LbCodeName.Text = vm.CodeName;
+                LbPluginName.Text = vm.PluginName;
+                LbUpdateDetail.Text = "配置已加载,准备更新……";
+            }));
+        }
         void UIClose()
         {
             Invoke(new Action(() =>
@@ -109,6 +344,11 @@ namespace Oreo.VersionUpdate.Views
         }
         #endregion
 
-
+        #region 控件事件
+        private void LbVersionNumber_Click(object sender, EventArgs e)
+        {
+            MessageBox.Show(VersionDesc, VersionNumber + " 新特性");
+        }
+        #endregion
     }
 }

+ 58 - 1
Fork.Net/Y.Utils/IOUtils/PathUtils/DirTool.cs

@@ -6,6 +6,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Text;
 using Y.Utils.DataUtils.Collections;
 
 namespace Y.Utils.IOUtils.PathUtils
@@ -17,7 +18,13 @@ namespace Y.Utils.IOUtils.PathUtils
             if (Directory.Exists(path))
                 return true;
             else
-                try { Directory.CreateDirectory(path); return true; } catch (Exception e) { }
+                try
+                {
+                    Directory.CreateDirectory(path); return true;
+                }
+                catch (Exception e)
+                {
+                }
             return false;
         }
         public static string Parent(string path)
@@ -52,5 +59,55 @@ namespace Y.Utils.IOUtils.PathUtils
             }
             return null;
         }
+        public static bool IsDriver(string path)
+        {
+            if (path != null && path.Length >= 2)
+            {
+                if (path.Substring(1, 1) == ":")
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+        /// <summary>
+        /// 获取文件所在的目录
+        /// </summary>
+        /// <param name="filePath"></param>
+        /// <returns></returns>
+        public static string GetFilePath(string filePath)
+        {
+            string result = "";
+            if (!string.IsNullOrWhiteSpace(filePath))
+            {
+                string fileName = Path.GetFileName(filePath);
+                result = filePath.Substring(0, filePath.Length - fileName.Length);
+            }
+            return result;
+        }
+        public static string Combine(params string[] paths)
+        {
+            if (ListTool.HasElements(paths))
+            {
+                if (paths.Length > 1)
+                {
+                    StringBuilder result = new StringBuilder();
+                    foreach (var path in paths)
+                    {
+                        result.Append(path);
+                    }
+                    while (result.ToString().IndexOf("\\\\") >= 0)
+                    {
+                        result.Replace("\\\\", "\\");
+                    }
+                    return result.ToString();
+                }
+                else
+                {
+                    return paths[0];
+                }
+            }
+            return "";
+        }
     }
 }

+ 13 - 0
Fork.Net/Y.Utils/IOUtils/TxtUtils/IniTool.cs

@@ -390,6 +390,19 @@ namespace Y.Utils.IOUtils.TxtUtils
             string flag = GetStringValue(iniFile, section, key, "");
             return flag.ToLower() == "true" ? true : false;
         }
+
+        public static bool WriteValue(string iniFile, string section, string key, int value)
+        {
+            return WriteValue(iniFile, section, key, value);
+        }
+        public static int GetIntValue(string iniFile, string section, string key)
+        {
+            string flag = GetStringValue(iniFile, section, key, "0");
+            int result = 0;
+            int.TryParse(flag,out result);
+            return result;
+        }
+
         #endregion
 
         #endregion

+ 33 - 0
Fork.Net/Y.Utils/NetUtils/FTPUtils/FTPTool.cs

@@ -5,6 +5,7 @@
 using System;
 using System.IO;
 using System.Net;
+using Y.Utils.IOUtils.PathUtils;
 
 namespace Y.Utils.NetUtils.FTPUtils
 {
@@ -65,5 +66,37 @@ namespace Y.Utils.NetUtils.FTPUtils
             catch { }
             return false;
         }
+        public bool Download(string ftpFile, string localFile)
+        {
+            try
+            {
+                string localPath = DirTool.GetFilePath(localFile);
+                if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
+
+                string uri = Path.Combine(ftpURI, ftpFile);
+                FtpWebRequest ftp = GetRequest(uri);
+                ftp.Method = WebRequestMethods.Ftp.DownloadFile;
+                using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
+                {
+                    using (Stream responseStream = response.GetResponseStream())
+                    {
+                        using (FileStream fs = new FileStream(localFile, FileMode.CreateNew))
+                        {
+                            byte[] buffer = new byte[2048];
+                            int read = 0;
+                            do
+                            {
+                                read = responseStream.Read(buffer, 0, buffer.Length);
+                                fs.Write(buffer, 0, read);
+                            } while (!(read == 0));
+                            fs.Flush();
+                        }
+                    }
+                }
+                return true;
+            }
+            catch { }
+            return false;
+        }
     }
 }