同步工具

svn更新 git更新 打开文件夹 同步文件夹

using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

namespace winFormTest
{using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

namespace winFormTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>         svn更新         </summary>
        private void btn1_Click(object sender, EventArgs e)
        {
            GitSvnPath.StartSvnProc("update", @"G:\aoe2020", false);
        }
        /// <summary>         git更新         </summary>
        private void btn2_Click(object sender, EventArgs e)
        {
            GitSvnPath.StartGitProc("pull", @"C: \Users\Administrator\Desktop\TT0\svn");//pull拉取,commit提交,puch向远程推送
        }
        /// <summary>         打开文件夹         </summary>
        private void btn3_Click(object sender, EventArgs e)
        {
            GitSvnPath.OpenExplorer(@"C:\Users\Administrator\Desktop\TT0\svn");
        }
        /// <summary>         同步文件夹         </summary>  
        private void btn4_Click(object sender, EventArgs e)
        {
            ClientSyncHelper.AddIgnore(".git", ".gitattributes", "README.md");
            ClientSyncHelper.StartSyncFolderContext(@"C:\Users\Administrator\Desktop\TT0\svn", @"C:\Users\Administrator\Desktop\TT0\git", "a目录", true);//svn的内容同步到git      
            MessageBox.Show("成功");      //AssetDatabase.Refresh();
        }
    }


    public static class GitSvnPath
    {
        /// <summary>
        /// 开始运行SVN
        /// </summary>
        /// <param name="cmd">指令</param>
        /// <param name="path">路径</param>
        /// <param name="closeOnEnd">指令之后是否关闭</param>
        public static void StartSvnProc(string cmd, string path, bool closeOnEnd = false)
        {
            var tortoiseProcPath = GetTortoiseProcSvnPath();
            if (string.IsNullOrEmpty(tortoiseProcPath))
            {
                MessageBox.Show("TortoiseProc未找到");
                return;
            }
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = tortoiseProcPath;
            startInfo.Arguments = $"/command:{cmd} /path:\"{path}\" /closeonend:{(closeOnEnd ? 2 : 0)}";

            Process svnUpProcess = new Process();
            svnUpProcess.StartInfo = startInfo;
            svnUpProcess.Start();
        }

        //去 注册表 拿 svn安装目录
        private static string GetTortoiseProcSvnPath()
        {
            try
            {
                RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
                var path = key.OpenSubKey("SOFTWARE").OpenSubKey("TortoiseSVN").GetValue("ProcPath").ToString();
                return path;
            }
            catch (Exception)
            {
                string[] vols = { "C", "D", "E", "F", "G", "H" };
                string[] dirs = {
                @"Program Files",
                @"Program Files (x86)",
            };

                foreach (var vol in vols)
                    foreach (var dir in dirs)
                    {
                        string file = $"{vol}:\\{dir}\\TortoiseSVN\\bin\\TortoiseProc.exe";
                        if (File.Exists(file))
                            return file;
                    }
                return null;
            }
        }
        public static void StartGitProc(string cmd, string path)
        {
            string gitProcPath = GetTortoiseGitProcPath();
            if (string.IsNullOrEmpty(gitProcPath))
            {
                MessageBox.Show("TortoiseGitProc未找到");
                return;
            }

            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = gitProcPath;
            startInfo.Arguments = $"/command:{cmd} /path:\"{path}\"/closeonend:2";

            Process svnUpProcess = new Process();
            svnUpProcess.StartInfo = startInfo;
            svnUpProcess.Start();
            svnUpProcess.WaitForExit();

            if (svnUpProcess.ExitCode > 0)
                MessageBox.Show("提示", $"svn update exit with code:{svnUpProcess.ExitCode}");
        }
        public static string GetTortoiseGitProcPath()
        {
            try
            {
                RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
                var path = key.OpenSubKey("SOFTWARE").OpenSubKey("TortoiseGit").GetValue("ProcPath").ToString();
                return path;
            }
            catch (Exception)
            {
                return null;
            }
        }
        public static void OpenExplorer(string path)
        {
            if (!Directory.Exists(path)) return;

            path = path.Replace("/", "\\");

            Process p = new Process();
            p.StartInfo = new ProcessStartInfo()
            {
                FileName = "explorer.exe",
                Arguments = path,
            };
            p.Start();
        }
    }

    public static class ClientSyncHelper
    {
        private static List<string> copyFileList = new List<string>();
        private static List<string> delFileList = new List<string>();
        private static List<string> addFolderList = new List<string>();
        private static List<string> delFolderList = new List<string>();

        private static Dictionary<string, string> srcMd5 = new Dictionary<string, string>();
        private static Dictionary<string, string> targetMd5 = new Dictionary<string, string>();

        private static List<string> ignoreList = new List<string>();
        static public void AddIgnore(params string[] strs)
        {
            foreach (var str in strs)
                if (!ignoreList.Contains(str))
                    ignoreList.Add(str);
        }

        private static bool IsIgnore(string path, bool isSyncMeta)
        {
            if (isSyncMeta == false && path.EndsWith(".meta"))
                return true;

            foreach (string s in ignoreList)
            {
                if (path.Contains(s))
                    return true;
            }

            return false;
        }

        //增加忽略文件夹,要增加meta文件忽略逻辑
        /// <summary>
        /// 开始同步
        /// </summary>
        /// <param name="SrcClient">源</param>
        /// <param name="TargetClient">目标    使目标和源一样</param>
        /// <param name="subPath">子目录</param>
        /// <param name="isSyncMeta">是否忽略meta文件</param>
        public static void StartSyncFolderContext(string SrcClient, string TargetClient, string subPath, bool isSyncMeta = true)
        {
            copyFileList.Clear();
            delFileList.Clear();
            addFolderList.Clear();
            delFolderList.Clear();

            srcMd5.Clear();
            targetMd5.Clear();

            //将相对路径,转成绝对路径,否则是有相对路径可能在下面的运算中出错.
            SrcClient = Path.GetFullPath(SrcClient).Replace("\\", "/");
            TargetClient = Path.GetFullPath(TargetClient).Replace("\\", "/");

            CollectFoldersRule(SrcClient, TargetClient, subPath, isSyncMeta);

            CollectSyncContext(SrcClient, TargetClient, subPath, isSyncMeta);

            // 为了减少一些gc,所以全部文件md5信息收集完毕之后,才在这外面进行
            foreach (string key in srcMd5.Keys)
            {
                if (targetMd5.ContainsKey(key) == false)
                {
                    copyFileList.Add(key);
                    continue;
                }

                if (srcMd5[key] != targetMd5[key])
                {
                    copyFileList.Add(key);
                    continue;
                }
            }

            foreach (string key in targetMd5.Keys)
            {
                if (srcMd5.ContainsKey(key) == false)
                {
                    delFileList.Add(key);
                }
            }


            // 删除文件
            foreach (string delFile in delFileList)
            {
                File.Delete($"{TargetClient}/{delFile}");
            }

            // 复制文件
            foreach (string copyFile in copyFileList)
            {
                var targetFilePath = $"{TargetClient}/{copyFile}";
                var targetPath = Path.GetDirectoryName(targetFilePath);

                if (!Directory.Exists(targetPath))
                    Directory.CreateDirectory(targetPath);

                if (File.Exists(targetFilePath))
                    File.Delete(targetFilePath);
                File.Copy($"{SrcClient}/{copyFile}", targetFilePath);
            }

            // 最后RefreshAsset,清理对应数据
            copyFileList.Clear();
            delFileList.Clear();
            addFolderList.Clear();
            delFolderList.Clear();

            srcMd5.Clear();
            targetMd5.Clear();
            ignoreList.Clear();
        }

        private static void CollectSyncContext(string SrcClient, string TargetClient, string subPath, bool isSyncMeta)
        {
            string srcPath = $"{SrcClient}/{subPath}";
            string targetPath = $"{TargetClient}/{subPath}";

            if (IsIgnore(srcPath, isSyncMeta) || IsIgnore(targetPath, isSyncMeta))
                return;

            bool isSrcExist = Directory.Exists(srcPath);
            bool isTargetExist = Directory.Exists(targetPath);

            if (isSrcExist == false && isTargetExist == false)
                return;

            // 递归遍历子文件夹
            foreach (string dir in Directory.GetDirectories(srcPath))
            {
                string subFolder = dir.Replace("\\", "/").Substring(SrcClient.Length + 1);
                CollectSyncContext(SrcClient, TargetClient, subFolder, isSyncMeta);
            }

            // 遍历当前文件夹下的所有文件
            List<string> srcFiles = new List<string>();
            if (Directory.Exists(srcPath))
                srcFiles.AddRange(Directory.GetFiles(srcPath));

            List<string> targetFiles = new List<string>();
            if (Directory.Exists(targetPath))
                targetFiles.AddRange(Directory.GetFiles(targetPath));

            //FileStream fileStream;
            string filePath;
            foreach (string file in srcFiles)
            {
                filePath = file.Replace("\\", "/");
                if (IsIgnore(file, isSyncMeta))
                    continue;

                using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
                {
                    srcMd5.Add(file.Replace("\\", "/").Substring(SrcClient.Length + 1), CalcMD5(fileStream));
                    fileStream.Close();
                }
            }

            foreach (string file in targetFiles)
            {
                filePath = file.Replace("\\", "/");
                if (IsIgnore(file, isSyncMeta))
                    continue;

                using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
                {
                    targetMd5.Add(file.Replace("\\", "/").Substring(TargetClient.Length + 1), CalcMD5(fileStream));
                    fileStream.Close();
                }
            }
        }

        static StringBuilder sb = new StringBuilder();
        public static string CalcMD5(FileStream fs)
        {
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] hashvalue = provider.ComputeHash(fs);
            sb.Clear();
            for (int i = 0; i < hashvalue.Length; ++i)
            {
                sb.Append(hashvalue[i].ToString("x2"));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 先提取出需要增加和删除的文件夹
        /// </summary>
        public static void CollectFoldersRule(string SrcClient, string TargetClient, string subPath, bool isSyncMeta = true)
        {
            string srcPath = subPath == "" ? SrcClient : $"{SrcClient}/{subPath}";
            string targetPath = subPath == "" ? TargetClient : $"{TargetClient}/{subPath}";

            List<string> srcDireList = new List<string>();
            List<string> targetDireList = new List<string>();
            GetFoldersByRecursion(srcPath, ref srcDireList);
            GetFoldersByRecursion(targetPath, ref targetDireList);

            foreach (var dir in srcDireList)
            {
                if (IsIgnore(dir, isSyncMeta))
                    continue;

                string subFolder = dir.Replace("\\", "/").Substring(srcPath.Length + 1);
                bool isTargetExist = Directory.Exists($"{targetPath}/{subFolder}");
                if (isTargetExist == false)
                {
                    addFolderList.Add(dir);
                }
            }

            foreach (var dir in targetDireList)
            {
                if (IsIgnore(dir, isSyncMeta))
                    continue;

                string subFolder = dir.Replace("\\", "/").Substring(targetPath.Length + 1);
                bool isSrcExist = Directory.Exists($"{srcPath}/{subFolder}");
                if (!isSrcExist)
                {
                    delFolderList.Add(dir);
                }
            }

            // 删除文件夹
            foreach (string delPath in delFolderList)
            {
                string path = delPath.Replace("\\", "/");
                FileHelper.DeleteDirectory(path, true);
            }

            // 复制文件夹
            foreach (string addPath in addFolderList)
            {
                string subFolder = addPath.Replace("\\", "/").Substring(srcPath.Length + 1);
                FileHelper.CopyDirectory(addPath, $"{targetPath}/{subFolder}");
            }
        }

        /// <summary>
        /// 递归获取文件夹目录
        /// </summary>
        public static void GetFoldersByRecursion(string sourcePath, ref List<string> folderList)
        {
            if (Directory.Exists(sourcePath))//判断源文件夹是否存在
            {
                string[] tmp = Directory.GetDirectories(sourcePath);//获取源文件夹中的目录,存入字符串
                                                                    //循环遍历
                for (int i = 0; i < tmp.Length; i++)
                {
                    string path = tmp[i].Replace("\\", "/");
                    folderList.Add(path);
                    if ((Directory.GetDirectories(path)).Length == 0)
                    {
                        continue;
                    }
                    //递归开始.......
                    GetFoldersByRecursion(path, ref folderList);
                }
            }
        }
    }


    public class FileHelper
    {
        static FileHelper()
        {
        }
        public static void CopyDirectory(string direcSource, string direcTarget)
        {
            if (!Directory.Exists(direcTarget))
                Directory.CreateDirectory(direcTarget);

            DirectoryInfo direcInfo = new DirectoryInfo(direcSource);
            FileInfo[] files = direcInfo.GetFiles();
            foreach (FileInfo file in files)
            {
                var tar = Path.Combine(direcTarget, file.Name);
                if (File.Exists(tar))
                    File.Delete(tar);
                file.CopyTo(tar);
            }

            DirectoryInfo[] direcInfoArr = direcInfo.GetDirectories();
            foreach (DirectoryInfo dir in direcInfoArr)
                CopyDirectory(Path.Combine(direcSource, dir.Name), Path.Combine(direcTarget, dir.Name));
        }

        public static void DeleteDirectory(string path, bool delete_myself = false)
        {
            DirectoryInfo dir = new DirectoryInfo(path);
            if (dir.Exists)
            {
                foreach (DirectoryInfo child in dir.GetDirectories())
                {
                    try
                    {
                        DeleteDirectory(child.FullName, true);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(string.Format("Delete Directory Failed: path->{0}, error->{1}", child.FullName, e.Message));
                    }
                }
                foreach (FileInfo child in dir.GetFiles())
                {
                    try
                    {
                        child.Delete();
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(string.Format("Delete File Failed: path->{0}, error->{1}", child.FullName, e.Message));
                    }
                }
                if (delete_myself)
                {
                    dir.Delete(true);
                }
            }
        }

        public static string[] FindFileBySuffix(string search_path, string suffix)
        {
            List<string> result = new List<string>();
            foreach (string dir in Directory.GetDirectories(search_path))
            {
                FindFileBySuffix(dir, suffix, ref result);
            }
            foreach (string file in Directory.GetFiles(search_path))
            {
                if (file.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
                {
                    string str = file.Replace("\\", "/");
                    result.Add(str);
                }
            }
            return result.ToArray();
        }

        public static void FindFileBySuffix(string search_path, string suffix, ref List<string> result)
        {
            foreach (string dir in Directory.GetDirectories(search_path))
            {
                FindFileBySuffix(dir, suffix, ref result);
            }
            foreach (string file in Directory.GetFiles(search_path))
            {
                if (file.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
                {
                    string str = file.Replace("\\", "/");
                    result.Add(str);
                }
            }
        }

        public static void DeleteEmptyDirectory(string path)
        {
            DirectoryInfo dir_info = new DirectoryInfo(path);
            foreach (var dir in dir_info.GetDirectories())
            {
                if (dir.GetFileSystemInfos().Length == 0)
                {
                    dir.Delete();
                }
                else
                {
                    DeleteEmptyDirectory(dir.FullName);
                }
            }
        }

        public static bool ExistInParentFolder(string startDir, string dirName)
        {
            DirectoryInfo info = new DirectoryInfo(startDir);
            while (info != null)
            {
                if (Directory.Exists(Path.Combine(info.FullName, dirName)))
                    return true;
                info = info.Parent;
            }
            return false;
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值