Browse Source

添加CMD指令工具类,添加查看端口占用进程id,IP地址定位添加简易的地址相似判断,日志工具类为目录添加前缀

yuzhengyang 7 years ago
parent
commit
7c806fa2a6
25 changed files with 986 additions and 71 deletions
  1. BIN
      Fork.Net/.vs/Fork.Net/v15/Server/sqlite3/storage.ide
  2. BIN
      Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide
  3. BIN
      Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide-shm
  4. BIN
      Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide-wal
  5. 1 1
      Fork.Net/Azylee.Utils/Azylee.Core/AppUtils/AppLaunchTool.cs
  6. 2 0
      Fork.Net/Azylee.Utils/Azylee.Core/Azylee.Core.csproj
  7. 2 2
      Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/SimpleLogUtils/Log.cs
  8. 4 4
      Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/StatusLogUtils/StatusLog.cs
  9. 3 3
      Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/StatusLogUtils/StatusLogModel.cs
  10. 56 58
      Fork.Net/Azylee.Utils/Azylee.Core/ProcessUtils/ProcessTool.cs
  11. 88 0
      Fork.Net/Azylee.Utils/Azylee.Core/WindowsUtils/CMDUtils/CMDNetstatTool.cs
  12. 93 0
      Fork.Net/Azylee.Utils/Azylee.Core/WindowsUtils/CMDUtils/CMDProcessTool.cs
  13. 19 2
      Fork.Net/Azylee.Utils/Azylee.YeahWeb/BaiDuWebAPI/IPLocationAPI/IPLocationModel.cs
  14. 11 0
      Fork.Net/Fork.Net.sln
  15. 3 1
      Fork.Net/Test/Test.BaiDuWebAPI/Program.cs
  16. 131 0
      Fork.Net/Test/Test.CmdTool/Form1.Designer.cs
  17. 85 0
      Fork.Net/Test/Test.CmdTool/Form1.cs
  18. 123 0
      Fork.Net/Test/Test.CmdTool/Form1.resx
  19. 21 0
      Fork.Net/Test/Test.CmdTool/Program.cs
  20. 36 0
      Fork.Net/Test/Test.CmdTool/Properties/AssemblyInfo.cs
  21. 71 0
      Fork.Net/Test/Test.CmdTool/Properties/Resources.Designer.cs
  22. 117 0
      Fork.Net/Test/Test.CmdTool/Properties/Resources.resx
  23. 30 0
      Fork.Net/Test/Test.CmdTool/Properties/Settings.Designer.cs
  24. 7 0
      Fork.Net/Test/Test.CmdTool/Properties/Settings.settings
  25. 83 0
      Fork.Net/Test/Test.CmdTool/Test.CmdTool.csproj

BIN
Fork.Net/.vs/Fork.Net/v15/Server/sqlite3/storage.ide


BIN
Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide


BIN
Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide-shm


BIN
Fork.Net/.vs/Fork.Net/v15/sqlite3/storage.ide-wal


+ 1 - 1
Fork.Net/Azylee.Utils/Azylee.Core/AppUtils/AppLaunchTool.cs

@@ -62,7 +62,7 @@ namespace Azylee.Core.AppUtils
                     //准备启动
                     if (startfile != null)
                     {
-                        return ProcessTool.SimpleStart(startfile);
+                        return ProcessTool.Start(startfile);
                     }
                 }
             }

+ 2 - 0
Fork.Net/Azylee.Utils/Azylee.Core/Azylee.Core.csproj

@@ -91,6 +91,8 @@
     <Compile Include="WindowsUtils\APIUtils\PermissionAPI.cs" />
     <Compile Include="WindowsUtils\APIUtils\SystemSleepAPI.cs" />
     <Compile Include="WindowsUtils\APIUtils\WindowsAPI.cs" />
+    <Compile Include="WindowsUtils\CMDUtils\CMDNetstatTool.cs" />
+    <Compile Include="WindowsUtils\CMDUtils\CMDProcessTool.cs" />
     <Compile Include="WindowsUtils\InfoUtils\ComputerInfoTool.cs" />
     <Compile Include="WindowsUtils\InfoUtils\ComputerStatusTool.cs" />
     <Compile Include="WindowsUtils\InfoUtils\NetcardInfoTool.cs" />

+ 2 - 2
Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/SimpleLogUtils/Log.cs

@@ -1,7 +1,7 @@
 //************************************************************************
 //      https://github.com/yuzhengyang
 //      author:     yuzhengyang
-//      date:       2017.3.29 - 2017.7.6
+//      date:       2017.3.29 - 2018.4.27
 //      desc:       日志功能
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
@@ -45,7 +45,7 @@ namespace Azylee.Core.LogUtils.SimpleLogUtils
         //输出的 Log 格式
         const string LOG_FORMAT = "{0}  {1}  {2}";
         const string TIME_FORMAT = "HH:mm:ss.fff";
-        const string LOG_PATH = "log";
+        const string LOG_PATH = "azylee.log";
 
         private int CACHE_DAYS = 30;//缓存天数
         private object LogFileLock = new object();//写日志文件锁

+ 4 - 4
Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/StatusLogUtils/StatusLog.cs

@@ -1,7 +1,7 @@
 //************************************************************************
 //      https://github.com/yuzhengyang
 //      author:     yuzhengyang
-//      date:       2018.4.17 - 2018.4.17
+//      date:       2018.4.17 - 2018.4.27
 //      desc:       程序运行状态日志
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
@@ -43,7 +43,7 @@ namespace Azylee.Core.LogUtils.StatusLogUtils
         #endregion
 
         #region 基础属性
-        const string LOG_PATH = @"log";//存储路径
+        const string LOG_PATH = @"azylee.log";//存储路径
 
         private int CACHE_DAYS = 30;//缓存天数
         private string LogPath = AppDomain.CurrentDomain.BaseDirectory + LOG_PATH;//存储路径
@@ -136,8 +136,8 @@ namespace Azylee.Core.LogUtils.StatusLogUtils
                 StatusLogModel status = new StatusLogModel()
                 {
                     Time = Time,
-                    Long = Interval,
-                    AFK = WindowsAPI.GetLastInputTime(),
+                    Long = Interval / 1000,
+                    AFK = WindowsAPI.GetLastInputTime() / 1000,
                     CpuPer = (int)ComputerProcessor.NextValue(),
                     RamFree = (long)ComputerInfoTool.AvailablePhysicalMemory(),
                     SysDriveFree = ComputerInfoTool.GetSystemDriveAvailableSize(),

+ 3 - 3
Fork.Net/Azylee.Utils/Azylee.Core/LogUtils/StatusLogUtils/StatusLogModel.cs

@@ -13,15 +13,15 @@ namespace Azylee.Core.LogUtils.StatusLogUtils
     public class StatusLogModel
     {
         /// <summary>
-        /// 时间
+        /// 日期时间
         /// </summary>
         public DateTime Time { get; set; }
         /// <summary>
-        /// 统计时长
+        /// 统计时长(单位:秒)
         /// </summary>
         public int Long { get; set; }
         /// <summary>
-        /// 脱机时长
+        /// 脱机时长(单位:秒)
         /// </summary>
         public long AFK { get; set; }
         /// <summary>

+ 56 - 58
Fork.Net/Azylee.Utils/Azylee.Core/ProcessUtils/ProcessTool.cs

@@ -1,8 +1,8 @@
 //************************************************************************
 //      https://github.com/yuzhengyang
 //      author:     yuzhengyang
-//      date:       2017.10.12 - 2017.10.12
-//      desc:       启动进程工具
+//      date:       2017.10.12 - 2018.4.27
+//      desc:       进程工具
 //      Copyright (c) yuzhengyang. All rights reserved.
 //************************************************************************
 using Azylee.Core.DataUtils.CollectionUtils;
@@ -14,23 +14,12 @@ namespace Azylee.Core.ProcessUtils
 {
     public static class ProcessTool
     {
-        public static void StartProcess(string appFile)
-        {
-            try
-            {
-                if (File.Exists(appFile))
-                {
-                    Process p = new Process();
-                    p.StartInfo.FileName = appFile;
-                    //p.StartInfo.Arguments = "";
-                    p.StartInfo.UseShellExecute = true;
-                    p.Start();
-                    p.WaitForInputIdle(3000);
-                }
-            }
-            catch (Exception ex) { }
-        }
-        public static bool CheckProcessExists(string name)
+        /// <summary>
+        /// 判断进程是否存在
+        /// </summary>
+        /// <param name="name">进程名</param>
+        /// <returns></returns>
+        public static bool IsExists(string name)
         {
             Process[] processes = Process.GetProcessesByName(name);
             foreach (Process p in processes)
@@ -39,33 +28,30 @@ namespace Azylee.Core.ProcessUtils
             }
             return false;
         }
-        public static void KillProcess(string name)
-        {
-            try
-            {
-                Process[] processes = Process.GetProcessesByName(name);
-                foreach (Process p in processes)
-                {
-                    p.Kill();
-                    p.Close();
-                }
-            }
-            catch (Exception e) { }
-        }
-        public static void KillCurrentProcess()
+        /// <summary>
+        /// 启动程序
+        /// </summary>
+        /// <param name="file">文件路径</param>
+        /// <param name="args">启动参数</param>
+        /// <returns></returns>
+        public static bool Start(string file, string args = "")
         {
-            Process current = Process.GetCurrentProcess();
-            Process[] processes = Process.GetProcessesByName(current.ProcessName);
-            foreach (Process process in processes)
+            if (File.Exists(file))
             {
-                if (process.Id == current.Id)
+                try
                 {
-                    process.Kill();
+                    Process.Start(file, args);
+                    return true;
                 }
+                catch { }
             }
+            return false;
         }
-
-        public static bool Start(string file, string args = "")
+        /// <summary>
+         /// 启动进程(定制启动配置)
+         /// </summary>
+         /// <param name="args"></param>
+        public static bool StartCustom(string file, string args = "")
         {
             try
             {
@@ -73,7 +59,7 @@ namespace Azylee.Core.ProcessUtils
                 {
                     Process p = new Process();
                     p.StartInfo.FileName = file;
-                    p.StartInfo.Arguments = "";
+                    p.StartInfo.Arguments = args;
                     p.StartInfo.UseShellExecute = true;
                     p.Start();
                     p.WaitForInputIdle(3000);
@@ -83,38 +69,50 @@ namespace Azylee.Core.ProcessUtils
             catch (Exception ex) { }
             return false;
         }
-        public static bool SimpleStart(string file, string args = "")
+        /// <summary>
+        /// 停止进程
+        /// </summary>
+        /// <param name="name">进程名</param>
+        public static void Kill(string name)
         {
-            if (File.Exists(file))
+            try
             {
-                try
+                Process[] processes = Process.GetProcessesByName(name);
+                foreach (Process p in processes)
                 {
-                    Process.Start(file, args);
-                    return true;
+                    p.Kill();
+                    p.Close();
                 }
-                catch { }
             }
-            return false;
+            catch (Exception e) { }
         }
-        public static void Starts(string[] files)
+        /// <summary>
+        /// 停止当前进程
+        /// </summary>
+        public static void KillCurrentProcess()
         {
-            if (ListTool.HasElements(files))
+            Process current = Process.GetCurrentProcess();
+            Process[] processes = Process.GetProcessesByName(current.ProcessName);
+            foreach (Process process in processes)
             {
-                foreach (var f in files)
+                if (process.Id == current.Id)
                 {
-                    if (!string.IsNullOrWhiteSpace(f))
-                        StartProcess(f);
+                    process.Kill();
                 }
             }
         }
-        public static void Kills(string[] pro)
+        /// <summary>
+        /// 停止多个进程
+        /// </summary>
+        /// <param name="names"></param>
+        public static void Kills(string[] names)
         {
-            if (ListTool.HasElements(pro))
+            if (ListTool.HasElements(names))
             {
-                foreach (var p in pro)
+                foreach (var name in names)
                 {
-                    if (!string.IsNullOrWhiteSpace(p))
-                        KillProcess(p);
+                    if (!string.IsNullOrWhiteSpace(name))
+                        Kill(name);
                 }
             }
         }

+ 88 - 0
Fork.Net/Azylee.Utils/Azylee.Core/WindowsUtils/CMDUtils/CMDNetstatTool.cs

@@ -0,0 +1,88 @@
+//************************************************************************
+//      https://github.com/yuzhengyang
+//      author:     yuzhengyang
+//      date:       2018.4.27 - 2018.4.27
+//      desc:       CMD 网络工具
+//      Copyright (c) yuzhengyang. All rights reserved.
+//************************************************************************
+using Azylee.Core.DataUtils.CollectionUtils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Azylee.Core.WindowsUtils.CMDUtils
+{
+    public class CMDNetstatTool
+    {
+        /// <summary>
+        /// 根据端口号查询列表(item1:端口、item2:pid)
+        /// </summary>
+        /// <param name="port"></param>
+        /// <param name="fuzzy"></param>
+        /// <returns></returns>
+        public static List<Tuple<int, int>> FindByPort(int port, bool fuzzy = true)
+        {
+            var list = Find(port.ToString());
+            if (ListTool.HasElements(list))
+            {
+                try
+                {
+                    if (fuzzy)
+                    {
+                        return list.Where(x => x.Item1.ToString().Contains(port.ToString())).ToList();
+                    }
+                    else
+                    {
+                        return list.Where(x => x.Item1 == port).ToList();
+                    }
+                }
+                catch { }
+            }
+            return null;
+        }
+        /// <summary>
+        /// 查询列表(item1:端口、item2:pid)
+        /// </summary>
+        /// <param name="content">查询内容</param>
+        /// <returns></returns>
+        public static List<Tuple<int, int>> Find(string content)
+        {
+            List<Tuple<int, int>> result = null;
+            var list = CMDProcessTool.Execute($"netstat -ano|findstr \"{content}\"");
+            if (ListTool.HasElements(list))
+            {
+                result = new List<Tuple<int, int>>();
+                foreach (var item in list)
+                {
+                    if (!string.IsNullOrWhiteSpace(item) &&
+                       (item.StartsWith("TCP") || item.StartsWith("UDP")))
+                    {
+                        try
+                        {
+                            Regex regex = new Regex(@"\s+");
+                            string[] block = regex.Split(item);
+                            if (ListTool.HasElements(block) && block.Length >= 3)
+                            {
+                                string[] s = block[1].Split(':');
+                                if (ListTool.HasElements(s) && s.Length >= 2)
+                                {
+                                    int _port = int.Parse(s[s.Length - 1]);
+                                    int _pid = int.Parse(block[block.Length - 1]);
+                                    if (!result.Any(x => x.Item1 == _port && x.Item2 == _pid))
+                                    {
+                                        Tuple<int, int> _tuple = new Tuple<int, int>(_port, _pid);
+                                        result.Add(_tuple);
+                                    }
+                                }
+                            }
+                        }
+                        catch { }
+                    }
+                }
+            }
+            return result;
+        }
+    }
+}

+ 93 - 0
Fork.Net/Azylee.Utils/Azylee.Core/WindowsUtils/CMDUtils/CMDProcessTool.cs

@@ -0,0 +1,93 @@
+//************************************************************************
+//      https://github.com/yuzhengyang
+//      author:     yuzhengyang
+//      date:       2018.4.27 - 2018.4.27
+//      desc:       CMD 工具
+//      Copyright (c) yuzhengyang. All rights reserved.
+//************************************************************************
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Azylee.Core.WindowsUtils.CMDUtils
+{
+    public class CMDProcessTool
+    {
+        /// <summary>
+        /// 创建cmd的进程
+        /// </summary>
+        /// <returns></returns>
+        public static Process GetProcess()
+        {
+            Process p = new Process();
+            p.StartInfo.FileName = "cmd.exe";
+            p.StartInfo.UseShellExecute = false;
+            p.StartInfo.RedirectStandardError = true;
+            p.StartInfo.RedirectStandardInput = true;
+            p.StartInfo.RedirectStandardOutput = true;
+            p.StartInfo.CreateNoWindow = true;
+            return p;
+        }
+
+        /// <summary>
+        /// 开始运行CMD命令
+        /// </summary>
+        /// <param name="cmd"></param>
+        public static void StartExecute(string cmd)
+        { 
+            StreamReader reader = null;
+            Process process = null;
+            try
+            {
+                process = GetProcess();
+                process.Start();
+                process.StandardInput.WriteLine(cmd);
+                reader = process.StandardOutput;
+                do
+                {
+                    string line = reader.ReadLine();
+                } while (!reader.EndOfStream);
+                process.WaitForExit();
+            }
+            catch { }
+        }
+
+        /// <summary>
+        /// 一次性运行CMD并读取结果(建议执行返回数据较小的命令)
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <returns></returns>
+        public static List<string> Execute(string cmd)
+        {
+            List<string> result = null;
+            StreamReader reader = null;
+            Process process = null;
+            try
+            {
+                process = GetProcess();
+                process.Start();
+                process.StandardInput.WriteLine(cmd);
+                process.StandardInput.WriteLine("exit");
+                reader = process.StandardOutput;
+                result = new List<string>();
+                do
+                {
+                    string line = reader.ReadLine();
+                    result.Add(line.Trim());
+                } while (!reader.EndOfStream);
+                process.WaitForExit();
+            }
+            catch { }
+            finally
+            {
+                reader?.Close();
+                process?.Close();
+                process?.Dispose();
+            }
+            return result;
+        }
+    }
+}

+ 19 - 2
Fork.Net/Azylee.Utils/Azylee.YeahWeb/BaiDuWebAPI/IPLocationAPI/IPLocationModel.cs

@@ -22,13 +22,29 @@ namespace Azylee.YeahWeb.BaiDuWebAPI.IPLocationAPI
         /// <summary>
         /// 所在商圈信息
         /// </summary>
-        public string  Business { get; set; }
+        public string Business { get; set; }
         /// <summary>
         /// 结合POI的语义化结果描述
         /// </summary>
         public string SematicDescription { get; set; }
         public Component Component { get; set; }
         public FirstPOI FirstPOI { get; set; }
+        /// <summary>
+        /// 对比两个位置是否相似
+        /// </summary>
+        /// <param name="loc"></param>
+        /// <returns></returns>
+        public bool Like(IPLocationModel loc)
+        {
+            try
+            {
+                if (this != null && loc != null && FirstPOI != null && loc.FirstPOI != null)//模型不为空
+                    if (FirstPOI.Address == loc.FirstPOI.Address)//判断语义化地址相同
+                        return true;//判定为相同地点
+            }
+            catch { }
+            return false;
+        }
     }
     /// <summary>
     /// 地址组成
@@ -49,7 +65,8 @@ namespace Azylee.YeahWeb.BaiDuWebAPI.IPLocationAPI
     /// <summary>
     /// 首选信息点
     /// </summary>
-    public class FirstPOI {
+    public class FirstPOI
+    {
         public string Address { get; set; }
         public string Name { get; set; }
     }

+ 11 - 0
Fork.Net/Fork.Net.sln

@@ -83,6 +83,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.RaiseOtherApp", "Test\
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.BlackBox", "Test\Test.BlackBox\Test.BlackBox.csproj", "{6C69CF15-398D-4030-AA90-C617E52DC016}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.CmdTool", "Test\Test.CmdTool\Test.CmdTool.csproj", "{6F974809-DC4F-4490-B6D4-857036A234AB}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -371,6 +373,14 @@ Global
 		{6C69CF15-398D-4030-AA90-C617E52DC016}.Release|Any CPU.Build.0 = Release|Any CPU
 		{6C69CF15-398D-4030-AA90-C617E52DC016}.Release|x86.ActiveCfg = Release|Any CPU
 		{6C69CF15-398D-4030-AA90-C617E52DC016}.Release|x86.Build.0 = Release|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Debug|x86.Build.0 = Debug|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Release|x86.ActiveCfg = Release|Any CPU
+		{6F974809-DC4F-4490-B6D4-857036A234AB}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -410,6 +420,7 @@ Global
 		{3AB4B914-CCD0-48C9-8106-75A8FE542ACC} = {A89FC45A-A907-4487-8719-114530A62684}
 		{79FCD171-33AC-47BF-B8A7-C19D365D2983} = {A89FC45A-A907-4487-8719-114530A62684}
 		{6C69CF15-398D-4030-AA90-C617E52DC016} = {A89FC45A-A907-4487-8719-114530A62684}
+		{6F974809-DC4F-4490-B6D4-857036A234AB} = {A89FC45A-A907-4487-8719-114530A62684}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {5436696D-5F55-490A-AB40-050B54BE2AB4}

+ 3 - 1
Fork.Net/Test/Test.BaiDuWebAPI/Program.cs

@@ -10,7 +10,9 @@ namespace Test.BaiDuWebAPI
     {
         static void Main(string[] args)
         {
-            var loc = IPLocationTool.GetLocation();
+            var loc1 = IPLocationTool.GetLocation();
+            var loc2 = IPLocationTool.GetLocation();
+            bool cp = loc1.Like(loc2);
             Console.WriteLine("");
         }
     }

+ 131 - 0
Fork.Net/Test/Test.CmdTool/Form1.Designer.cs

@@ -0,0 +1,131 @@
+namespace Test.CmdTool
+{
+    partial class Form1
+    {
+        /// <summary>
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows 窗体设计器生成的代码
+
+        /// <summary>
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.BTFindPort = new System.Windows.Forms.Button();
+            this.TBPort = new System.Windows.Forms.TextBox();
+            this.TBRs = new System.Windows.Forms.TextBox();
+            this.BTKillApp = new System.Windows.Forms.Button();
+            this.BTStart = new System.Windows.Forms.Button();
+            this.TMStatus = new System.Windows.Forms.Timer(this.components);
+            this.LBStatus = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // BTFindPort
+            // 
+            this.BTFindPort.Location = new System.Drawing.Point(153, 46);
+            this.BTFindPort.Name = "BTFindPort";
+            this.BTFindPort.Size = new System.Drawing.Size(120, 23);
+            this.BTFindPort.TabIndex = 0;
+            this.BTFindPort.Text = "查询端口和PID";
+            this.BTFindPort.UseVisualStyleBackColor = true;
+            this.BTFindPort.Click += new System.EventHandler(this.BTFindPort_Click);
+            // 
+            // TBPort
+            // 
+            this.TBPort.Location = new System.Drawing.Point(36, 46);
+            this.TBPort.Name = "TBPort";
+            this.TBPort.Size = new System.Drawing.Size(100, 21);
+            this.TBPort.TabIndex = 1;
+            // 
+            // TBRs
+            // 
+            this.TBRs.Location = new System.Drawing.Point(25, 101);
+            this.TBRs.Multiline = true;
+            this.TBRs.Name = "TBRs";
+            this.TBRs.Size = new System.Drawing.Size(631, 253);
+            this.TBRs.TabIndex = 2;
+            // 
+            // BTKillApp
+            // 
+            this.BTKillApp.Location = new System.Drawing.Point(323, 46);
+            this.BTKillApp.Name = "BTKillApp";
+            this.BTKillApp.Size = new System.Drawing.Size(75, 23);
+            this.BTKillApp.TabIndex = 3;
+            this.BTKillApp.Text = "结束进程";
+            this.BTKillApp.UseVisualStyleBackColor = true;
+            this.BTKillApp.Click += new System.EventHandler(this.BTKillApp_Click);
+            // 
+            // BTStart
+            // 
+            this.BTStart.Location = new System.Drawing.Point(493, 46);
+            this.BTStart.Name = "BTStart";
+            this.BTStart.Size = new System.Drawing.Size(75, 23);
+            this.BTStart.TabIndex = 4;
+            this.BTStart.Text = "启动服务";
+            this.BTStart.UseVisualStyleBackColor = true;
+            this.BTStart.Click += new System.EventHandler(this.BTStart_Click);
+            // 
+            // TMStatus
+            // 
+            this.TMStatus.Enabled = true;
+            this.TMStatus.Interval = 1000;
+            this.TMStatus.Tick += new System.EventHandler(this.TMStatus_Tick);
+            // 
+            // LBStatus
+            // 
+            this.LBStatus.AutoSize = true;
+            this.LBStatus.Location = new System.Drawing.Point(25, 377);
+            this.LBStatus.Name = "LBStatus";
+            this.LBStatus.Size = new System.Drawing.Size(41, 12);
+            this.LBStatus.TabIndex = 5;
+            this.LBStatus.Text = "label1";
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(687, 396);
+            this.Controls.Add(this.LBStatus);
+            this.Controls.Add(this.BTStart);
+            this.Controls.Add(this.BTKillApp);
+            this.Controls.Add(this.TBRs);
+            this.Controls.Add(this.TBPort);
+            this.Controls.Add(this.BTFindPort);
+            this.Name = "Form1";
+            this.Text = "Form1";
+            this.Load += new System.EventHandler(this.Form1_Load);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button BTFindPort;
+        private System.Windows.Forms.TextBox TBPort;
+        private System.Windows.Forms.TextBox TBRs;
+        private System.Windows.Forms.Button BTKillApp;
+        private System.Windows.Forms.Button BTStart;
+        private System.Windows.Forms.Timer TMStatus;
+        private System.Windows.Forms.Label LBStatus;
+    }
+}
+

+ 85 - 0
Fork.Net/Test/Test.CmdTool/Form1.cs

@@ -0,0 +1,85 @@
+using Azylee.Core.AppUtils;
+using Azylee.Core.DataUtils.CollectionUtils;
+using Azylee.Core.ProcessUtils;
+using Azylee.Core.WindowsUtils.CMDUtils;
+using Azylee.Core.WindowsUtils.InfoUtils;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Test.CmdTool
+{
+    public partial class Form1 : Form
+    {
+        private PerformanceCounter ComCpu = ComputerStatusTool.Processor();//电脑CPU监控
+        private PerformanceCounter AppCpu = AppInfoTool.Processor();//程序CPU监控
+        public Form1()
+        {
+            InitializeComponent();
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+
+        }
+
+        private void BTFindPort_Click(object sender, EventArgs e)
+        {
+            if (!string.IsNullOrWhiteSpace(TBPort.Text))
+            {
+                var list = CMDNetstatTool.FindByPort(int.Parse(TBPort.Text));
+                if (ListTool.HasElements(list))
+                {
+                    list.ForEach(x =>
+                    {
+                        string name = "-";
+                        string file = "-";
+                        try
+                        {
+                            Process p = Process.GetProcessById(x.Item2);
+                            name = p?.ProcessName;
+                            file = p?.MainModule.FileName;
+                        }
+                        catch { }
+                        TBRs.AppendText($"{x.Item1}, {x.Item2}, {name}, {file}");
+                        TBRs.AppendText(Environment.NewLine);
+                    });
+                }
+            }
+        }
+
+        private void BTStart_Click(object sender, EventArgs e)
+        {
+            Task.Factory.StartNew(() =>
+            {
+                CMDProcessTool.StartExecute(@"java -jar D:\CoCo\Work\supplyPlatform\out\artifacts\noah_cloud_supply_platform_jar\noah-cloud-supply-platform.jar");
+            });
+        }
+
+        private void BTKillApp_Click(object sender, EventArgs e)
+        {
+            var list = CMDNetstatTool.FindByPort(int.Parse(TBPort.Text), false);
+            if (ListTool.HasElements(list) && list.Count == 1)
+            {
+                try
+                {
+                    Process p = Process.GetProcessById(list.First().Item2);
+                    p.Kill();
+                }
+                catch { }
+            }
+        }
+
+        private void TMStatus_Tick(object sender, EventArgs e)
+        {
+            LBStatus.Text = $"comcpu:{(int)ComCpu.NextValue()}, appcpu:{(int)AppCpu.NextValue()}, appram:{AppInfoTool.RAM()/1024}";
+        }
+    }
+}

+ 123 - 0
Fork.Net/Test/Test.CmdTool/Form1.resx

@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="TMStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>

+ 21 - 0
Fork.Net/Test/Test.CmdTool/Program.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Test.CmdTool
+{
+    static class Program
+    {
+        /// <summary>
+        /// 应用程序的主入口点。
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new Form1());
+        }
+    }
+}

+ 36 - 0
Fork.Net/Test/Test.CmdTool/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("Test.CmdTool")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Test.CmdTool")]
+[assembly: AssemblyCopyright("Copyright ©  2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("6f974809-dc4f-4490-b6d4-857036a234ab")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
Fork.Net/Test/Test.CmdTool/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Test.CmdTool.Properties
+{
+
+
+    /// <summary>
+    ///   强类型资源类,用于查找本地化字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   返回此类使用的缓存 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Test.CmdTool.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   覆盖当前线程的 CurrentUICulture 属性
+        ///   使用此强类型的资源类的资源查找。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
Fork.Net/Test/Test.CmdTool/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 30 - 0
Fork.Net/Test/Test.CmdTool/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Test.CmdTool.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
Fork.Net/Test/Test.CmdTool/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 83 - 0
Fork.Net/Test/Test.CmdTool/Test.CmdTool.csproj

@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{6F974809-DC4F-4490-B6D4-857036A234AB}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Test.CmdTool</RootNamespace>
+    <AssemblyName>Test.CmdTool</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Form1.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Form1.Designer.cs">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Form1.resx">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Azylee.Utils\Azylee.Core\Azylee.Core.csproj">
+      <Project>{88dc61fa-95f0-41b7-9d7d-ab0f3cbd169c}</Project>
+      <Name>Azylee.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>