diff --git a/.gitignore b/.gitignore
index 46f42f8..2b057a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,3 @@
-CMakeLists.txt.user
-CMakeCache.txt
-CMakeFiles
-CMakeScripts
-Testing
-Makefile
-cmake_install.cmake
-install_manifest.txt
-compile_commands.json
-CTestTestfile.cmake
-_deps
+Source/DuplicateFileCheck/bin
+Source/DuplicateFileCheck/obj
+Source/.vs
\ No newline at end of file
diff --git a/README.md b/README.md
index aa4b75a..a786d1c 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,13 @@
# DuplicateFileCheck
-Duplicate File Check 重复文件检查
+
+> Duplicate File Check 重复文件检查
+
+## 执行命令方式
+
+> DuplicateFileCheck.exe -p C:\Github\CSharpCodes C:\Github\JingShiZiJi -w true -l C:\Temp
+
+```
+-p 后边跟的是需要扫描的路径。
+-w 后边true 则输出扫描结果到日志文件。
+-l 后边跟的是一个目录用于保存计算结果 如果路径不存在会自动创建。
+```
diff --git a/Source/DuplicateFileCheck.sln b/Source/DuplicateFileCheck.sln
new file mode 100644
index 0000000..9767540
--- /dev/null
+++ b/Source/DuplicateFileCheck.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32602.291
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DuplicateFileCheck", "DuplicateFileCheck\DuplicateFileCheck.csproj", "{94588FF7-7A19-41A5-8931-9F596097CE70}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {94588FF7-7A19-41A5-8931-9F596097CE70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94588FF7-7A19-41A5-8931-9F596097CE70}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94588FF7-7A19-41A5-8931-9F596097CE70}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94588FF7-7A19-41A5-8931-9F596097CE70}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F3E4F503-7B0D-45E1-BCE6-962DB780EC11}
+ EndGlobalSection
+EndGlobal
diff --git a/Source/DuplicateFileCheck/DuplicateFileCheck.csproj b/Source/DuplicateFileCheck/DuplicateFileCheck.csproj
new file mode 100644
index 0000000..931eeee
--- /dev/null
+++ b/Source/DuplicateFileCheck/DuplicateFileCheck.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ netcoreapp3.1
+ DEVGIS.DuplicateFileCheck
+ DEVGIS
+ DEVGIS
+ www.devgis.com
+
+
+
diff --git a/Source/DuplicateFileCheck/MyFileInfo.cs b/Source/DuplicateFileCheck/MyFileInfo.cs
new file mode 100644
index 0000000..d8556b7
--- /dev/null
+++ b/Source/DuplicateFileCheck/MyFileInfo.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace DEVGIS.DuplicateFileCheck
+{
+ public class MyFileInfo
+ {
+ public string Key
+ {
+ get;
+ set;
+ }
+
+ public string Name
+ {
+ get;
+ set;
+ }
+
+ public List DuplicateFiles
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/Source/DuplicateFileCheck/Program.cs b/Source/DuplicateFileCheck/Program.cs
new file mode 100644
index 0000000..6bf06fa
--- /dev/null
+++ b/Source/DuplicateFileCheck/Program.cs
@@ -0,0 +1,171 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading;
+
+namespace DEVGIS.DuplicateFileCheck
+{
+ class Program
+ {
+ static Dictionary dictMyFileInfos = null;
+ static bool writLog = true;
+ static string logPath = string.Empty;
+ static List paths = new List {};
+ static void Main(string[] args)
+ {
+ writLog = false;
+ logPath = string.Empty;
+ paths = new List();
+ //-p paths
+ //-l lpath .outputlogpath
+ //-w true false true output log
+ if (args != null && args.Length > 0)
+ {
+ for (int i = 0; i < args.Length; i++)
+ {
+ switch (args[i].ToLower())
+ {
+ case "-p":
+ for (int j = i + 1; j < args.Length; j++)
+ {
+ if (!args[j].StartsWith("-") && Directory.Exists(args[j]))
+ {
+ paths.Add(args[j]);
+ }
+ else
+ {
+ break;
+ }
+ }
+ break;
+ case "-w":
+ try
+ {
+ if ("true".Equals(args[i + 1].ToLower()))
+ {
+ writLog = true;
+ }
+ else
+ {
+ writLog = false;
+ }
+ }
+ catch
+ { }
+ break;
+ case "-l":
+ try
+ {
+ string lp = args[i + 1];
+ if (!Directory.Exists(lp))
+ {
+ Directory.CreateDirectory(lp);
+ }
+
+ logPath = lp;
+ }
+ catch
+ { }
+ break;
+ break;
+ }
+ }
+ }
+ Start();
+ }
+
+ private static void Start()
+ {
+ DateTime time1 = DateTime.Now;
+ Console.WriteLine($"{time1.ToString()}:Started!");
+ dictMyFileInfos = new Dictionary();
+ logPath = Path.Combine(logPath, time1.ToString("yyyyMMddHHmmss") + ".log");
+
+ foreach (string path in paths)
+ {
+ VisitPath(path);
+ }
+ DateTime time2 = DateTime.Now;
+ Console.WriteLine($"{time2.ToString()}:Completed!");
+ Console.WriteLine($"TotalCount:{dictMyFileInfos.Count}");
+ Console.WriteLine("Result-------------------------------------------------------------------------------");
+ int sameindex = 0;
+ StringBuilder sb = new StringBuilder();
+ foreach (var value in dictMyFileInfos.Values)
+ {
+ if (value.DuplicateFiles != null)
+ {
+ sameindex++;
+ string s = sameindex + ":" + value.Name;
+ foreach (var d in value.DuplicateFiles)
+ {
+ s += " And " + d.Name;
+ }
+ Console.WriteLine(s);
+ sb.AppendLine(s);
+ }
+ }
+ Console.WriteLine("Result-------------------------------------------------------------------------------");
+ sb.AppendLine($"TotalDuplicateCounts:{sameindex}");
+ sb.AppendLine($"TotalUsedSeconds:{(time2 - time1).TotalSeconds}");
+ Console.WriteLine($"Done! File name is {logPath}");
+ Console.WriteLine("Press any key to exit!");
+ File.WriteAllText(logPath, sb.ToString());
+ Console.Read();
+ }
+ private static void ShowLog(string message)
+ {
+
+ }
+ private static void VisitPath(string Path)
+ {
+ Console.WriteLine($"{DateTime.Now.ToString()}:Visiting {Path}");
+ foreach (var file in Directory.GetFiles(Path))
+ {
+ var myfileinfo = GetMyFileInfo(file);
+ if (dictMyFileInfos.ContainsKey(myfileinfo.Key))
+ {
+ if (dictMyFileInfos[myfileinfo.Key].DuplicateFiles == null)
+ {
+ dictMyFileInfos[myfileinfo.Key].DuplicateFiles = new List();
+ }
+ dictMyFileInfos[myfileinfo.Key].DuplicateFiles.Add(myfileinfo);
+ }
+ else
+ {
+ dictMyFileInfos.Add(myfileinfo.Key, myfileinfo);
+ }
+ }
+
+ //visit the paths
+ foreach (var dir in Directory.GetDirectories(Path))
+ {
+ VisitPath(dir);
+ }
+ }
+
+ private static MyFileInfo GetMyFileInfo(string FileName)
+ {
+ if (File.Exists(FileName))
+ {
+ return new MyFileInfo { Key= GetMD5WithFilePath (FileName),Name= FileName };
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ static MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
+ static public string GetMD5WithFilePath(string filePath)
+ {
+ FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ byte[] hash_byte = md5.ComputeHash(file);
+ string str = System.BitConverter.ToString(hash_byte);
+ str = str.Replace("-", "");
+ return str;
+ }
+ }
+}
diff --git a/Source/DuplicateFileCheck/Properties/launchSettings.json b/Source/DuplicateFileCheck/Properties/launchSettings.json
new file mode 100644
index 0000000..b916591
--- /dev/null
+++ b/Source/DuplicateFileCheck/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "DuplicateFileCheck": {
+ "commandName": "Project",
+ "commandLineArgs": "-p C:\\Github\\CSharpCodes C:\\Github\\JingShiZiJi -w true -l C:\\Temp"
+ }
+ }
+}
\ No newline at end of file