Quellcode durchsuchen

mxg:联调后,Revit可正常执行

mengxiangge vor 6 Jahren
Ursprung
Commit
c3c2ca20e2
96 geänderte Dateien mit 6210 neuen und 1432 gelöschten Zeilen
  1. 20 0
      .gitignore
  2. 30 0
      Client/Class1.cs
  3. 162 0
      Client/Client.csproj
  4. 64 0
      Client/ClientApp.cs
  5. 89 0
      Client/ClientInfo.cs
  6. 20 0
      Client/IRevitCommandExcutor.cs
  7. 113 0
      Client/MessageHandler.cs
  8. 36 0
      Client/Properties/AssemblyInfo.cs
  9. 25 0
      Client/Readme.txt
  10. 41 0
      Client/Start/CustomMessage.cs
  11. 87 0
      Client/Start/RevitCmdExecutor.cs
  12. 31 0
      Client/Start/ServiceMBIClientHandler.cs
  13. 195 0
      Client/TaskHandler.cs
  14. 67 0
      Client/app.config
  15. 69 0
      Client/packages.config
  16. 110 0
      ClientTests/ClientTests.csproj
  17. 36 0
      ClientTests/Properties/AssemblyInfo.cs
  18. 32 0
      ClientTests/Start/RevitCmdExecutorTests.cs
  19. 67 0
      ClientTests/app.config
  20. 6 0
      ClientTests/packages.config
  21. BIN
      Dlls/SAGA.RevitAPI.dll
  22. 150 0
      HttpDownload/DownloadTask.cs
  23. 51 0
      HttpDownload/HttpDownload.csproj
  24. 281 0
      HttpDownload/HttpDownloader.cs
  25. 184 0
      HttpDownload/LimitedConcurrencyLevelTaskScheduler.cs
  26. 36 0
      HttpDownload/Properties/AssemblyInfo.cs
  27. 128 0
      HttpDownload/TaskDownloadManager.cs
  28. 13 0
      NettyClient/ClientWrapper.cs
  29. 181 0
      NettyClient/NettyClient.csproj
  30. 6 0
      NettyClient/NettyClient.csproj.user
  31. 36 0
      NettyClient/Properties/AssemblyInfo.cs
  32. 82 0
      NettyClient/SimpleMessageHandler.cs
  33. 109 0
      NettyClient/TaskNettyClient.cs
  34. 75 0
      NettyClient/app.config
  35. 72 0
      NettyClient/packages.config
  36. 224 0
      NettyClient/proto/MessageProto - 复制.cs
  37. 224 0
      NettyClient/proto/MessageProto.cs
  38. 20 0
      NettyClient/proto/MessageUtil.cs
  39. 74 0
      SAGA.Revit/App.config
  40. 9 0
      SAGA.Revit/App.xaml
  41. 17 0
      SAGA.Revit/App.xaml.cs
  42. 17 0
      SAGA.Revit/MainWindow.xaml
  43. 42 0
      SAGA.Revit/MainWindow.xaml.cs
  44. 55 0
      SAGA.Revit/Properties/AssemblyInfo.cs
  45. 71 0
      SAGA.Revit/Properties/Resources.Designer.cs
  46. 117 0
      SAGA.Revit/Properties/Resources.resx
  47. 30 0
      SAGA.Revit/Properties/Settings.Designer.cs
  48. 7 0
      SAGA.Revit/Properties/Settings.settings
  49. 44 0
      SAGA.Revit/RevitInfo/RevitProductExt.cs
  50. 309 0
      SAGA.Revit/RevitInfo/RevitStartHelper.cs
  51. 23 0
      SAGA.Revit/RevitInfo/RevitVersionExt.cs
  52. 373 0
      SAGA.Revit/SAGA.Revit.csproj
  53. BIN
      SAGA.Revit/三维.jpg
  54. 1 1
      SAGA.RevitMenu/Addin/RevitProductExt.cs
  55. 1 1
      SAGA.RevitMenu/Addin/RevitStartHelper.cs
  56. 1 1
      SAGA.RevitMenu/Addin/RevitVersionExt.cs
  57. 0 234
      SAGA.RevitMenu/ChangeProduct.cs
  58. 0 21
      SAGA.RevitMenu/ChangeProductCmd.cs
  59. 1 1
      SAGA.RevitMenu/Configuration/MenuConfig.cs
  60. 0 187
      SAGA.RevitMenu/Globals.cs
  61. 39 136
      SAGA.RevitMenu/MenuApp.cs
  62. 130 1
      SAGA.RevitMenu/SAGA.RevitMenu.csproj
  63. 1 1
      SAGA.RevitMenu/SAGA.RevitMenu.csproj.user
  64. 0 217
      SAGA.RevitMenu/ScreenMenu.cs
  65. 0 27
      SAGA.RevitMenu/SetMenuCmd.cs
  66. 0 552
      SAGA.RevitMenu/SetMenuForm.cs
  67. 0 26
      SAGA.RevitMenu/TSZHideScreenMenuCmd.cs
  68. 0 24
      SAGA.RevitMenu/TSZShowScreenMenuCmd.cs
  69. 71 0
      SAGA.RevitMenu/app.config
  70. 50 0
      SAGA.RevitMenu/packages.config
  71. 25 0
      ServiceMBI.Modes/IServiceCommand.cs
  72. 36 0
      ServiceMBI.Modes/Properties/AssemblyInfo.cs
  73. 48 0
      ServiceMBI.Modes/ServiceMBI.Modes.csproj
  74. 38 0
      ServiceMBI.Modes/ServiceMBIBuiltInParameter.cs
  75. 256 0
      ServiceMBI.sln
  76. 40 0
      ServiceMBI/Commands/BaseCommandArgs.cs
  77. 58 0
      ServiceMBI/Commands/BaseServiceCommand.cs
  78. 42 0
      ServiceMBI/Commands/DataCheckCommand.cs
  79. 30 0
      ServiceMBI/Commands/DataCheckCommandArgs.cs
  80. 1 1
      ServiceMBI/Command.cs
  81. 17 1
      ServiceMBI/ServiceMBI.csproj
  82. 44 0
      TaskDatabase/Mappings/TaskModel.hbm.xml
  83. 35 0
      TaskDatabase/Models/TaskModel.cs
  84. 42 0
      TaskDatabase/NHibernateHelper.cs
  85. 36 0
      TaskDatabase/Properties/AssemblyInfo.cs
  86. 93 0
      TaskDatabase/TaskDatabase.csproj
  87. 209 0
      TaskDatabase/TaskService.cs
  88. 11 0
      TaskDatabase/hibernate.cfg.xml
  89. 10 0
      TaskDatabase/packages.config
  90. 30 0
      testDll/Class1.cs
  91. 36 0
      testDll/Properties/AssemblyInfo.cs
  92. 61 0
      testDll/SimpleMessageHandler.cs
  93. 109 0
      testDll/TaskNettyClient.cs
  94. 19 0
      testDll/app.config
  95. 67 0
      testDll/packages.config
  96. 162 0
      testDll/testDll.csproj

+ 20 - 0
.gitignore

@@ -3,3 +3,23 @@
 ################################################################################
 
 /SAGA.RevitMenu/obj
+/OutputDll
+/ServiceMBI/obj/Debug
+/.vs/ServiceMBI/v15/sqlite3
+/Client/bin/Debug
+/Client/obj/Debug
+/.vs/ServiceMBI/v15
+/ClientTests/bin/Debug
+/ClientTests/obj/Debug
+/HttpDownload/bin/Debug
+/HttpDownload/obj/Debug
+/NettyClient/bin/Debug
+/NettyClient/obj/Debug
+/packages
+/SAGA.Revit/obj/Debug
+/SAGA.Revit/obj/RR17
+/ServiceMBI.Modes/obj/Debug
+/TaskDatabase/bin/Debug
+/TaskDatabase/obj/Debug
+/testDll/bin/Debug
+/testDll/obj/Debug

+ 30 - 0
Client/Class1.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Client.Start;
+using NettyClient;
+
+namespace testDll
+{
+    public class Class1
+    {
+        public static void Main()
+        {
+            MessageBox.Show("start");
+            try
+            {
+                ServiceMBIClientHandler.Start();
+            }
+            catch (Exception ex)
+            {
+
+                MessageBox.Show(ex.Message);
+            }
+
+            MessageBox.Show("end");
+        }
+    }
+}

+ 162 - 0
Client/Client.csproj

@@ -0,0 +1,162 @@
+<?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>{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Client</RootNamespace>
+    <AssemblyName>Client</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="DotNetty.Buffers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Buffers.0.6.0\lib\net45\DotNetty.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Common, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Common.0.6.0\lib\net45\DotNetty.Common.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Transport, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Transport.0.6.0\lib\net45\DotNetty.Transport.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration.Binder, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Options, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Primitives, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.DotNetUtils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Dlls\SAGA.DotNetUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression.FileSystem" />
+    <Reference Include="System.Management" />
+    <Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Class1.cs" />
+    <Compile Include="ClientApp.cs" />
+    <Compile Include="ClientInfo.cs" />
+    <Compile Include="IRevitCommandExcutor.cs" />
+    <Compile Include="MessageHandler.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Start\CustomMessage.cs" />
+    <Compile Include="Start\RevitCmdExecutor.cs" />
+    <Compile Include="Start\ServiceMBIClientHandler.cs" />
+    <Compile Include="TaskHandler.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HttpDownload\HttpDownload.csproj">
+      <Project>{9f423033-98a9-4b6b-9bb1-f1aa8c648a02}</Project>
+      <Name>HttpDownload</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\NettyClient\NettyClient.csproj">
+      <Project>{7a08d4e8-a171-47bd-a527-bc9ba1833305}</Project>
+      <Name>NettyClient</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\ServiceMBI.Modes\ServiceMBI.Modes.csproj">
+      <Project>{676f1602-6f8a-44c7-bb81-2172d963ac1a}</Project>
+      <Name>ServiceMBI.Modes</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\TaskDatabase\TaskDatabase.csproj">
+      <Project>{ade36aa5-fca8-4e5b-a27e-2360884404b3}</Project>
+      <Name>TaskDatabase</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Readme.txt" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 64 - 0
Client/ClientApp.cs

@@ -0,0 +1,64 @@
+using HttpDownload;
+using NettyClient;
+using System.Threading;
+using TaskDatabase;
+
+namespace Client
+{
+    public class ClientApp
+    {
+        TaskNettyClient client;                    // 网络传输客户端
+        SimpleMessageHandler simpleHandler;        // 网络传输处理
+        TaskService taskService;                   // 持久化任务
+        TaskDownloadManager taskDownloadManager;   // 下载任务文件(Http)
+        MessageHandler messageHandler;             // 处理客户端收到的消息
+        TaskHandler taskHandler;                   // 处理服务端发送的任务(监视下载状况等待)
+        int maxTaskCount;                          // 能处理的最大任务数量, 影响是否拒绝服务器分发的任务
+        string defaultFileDir;                     // 默认文件目录
+        IRevitCommandExcutor revitCommandExcutor;  
+        public ClientApp(string ip, int port, string dir, int maxTaskCount, IRevitCommandExcutor revitCommandExcutor, int maxDownTaskCount=5) {
+            client = new TaskNettyClient(ip, port);
+            taskService = new TaskService();
+            taskDownloadManager = new TaskDownloadManager(maxDownTaskCount);
+            this.maxTaskCount = maxTaskCount;
+            defaultFileDir = dir;
+            this.revitCommandExcutor = revitCommandExcutor;
+        }
+
+        public void Start() {
+            
+            simpleHandler = new SimpleMessageHandler();
+            if (messageHandler == null)
+            {
+                taskHandler = new TaskHandler(simpleHandler, taskService, taskDownloadManager, defaultFileDir, revitCommandExcutor);
+                taskHandler.SyncAllTask();
+                messageHandler = new MessageHandler(simpleHandler, maxTaskCount, taskHandler);
+                messageHandler.ResumeAllTasks();
+                ThreadPool.QueueUserWorkItem(messageHandler.HandleMessage);
+                ThreadPool.QueueUserWorkItem(taskHandler.RunTasks);
+            }
+            else
+            {
+                messageHandler.setSimpleMessageHandler(simpleHandler);
+                taskHandler.setSimpleMessageHandler(simpleHandler);
+            }
+            client.RunClientAsync(simpleHandler).Wait();
+        }
+
+        public void Close() {
+            client.CloseAsync().Wait();
+        }
+
+        public void PauseAllTask() {
+            taskDownloadManager.pauseAllTasks();
+            messageHandler.PauseAllTasks();
+        }
+        public void ResumeAllTask()
+        {
+            taskDownloadManager.resumeAllTasks();
+            messageHandler.ResumeAllTasks();
+        }
+    }
+
+    
+}

+ 89 - 0
Client/ClientInfo.cs

@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Management;
+using System.Net;
+
+namespace Client
+{
+    public class ClientInfo
+    {
+        public string MacAddr { get; set; }
+        public string Ipv4 { get; set; }
+        public string Name { get; set; }
+    }
+    public class ClientInfoUtil {
+        /// <summary>  
+        /// 获取本机MAC地址  
+        /// </summary>  
+        /// <returns>本机MAC地址</returns>  
+        public static string GetMacAddress()
+        {
+            try
+            {
+                string strMac = string.Empty;
+                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
+                ManagementObjectCollection moc = mc.GetInstances();
+                foreach (ManagementObject mo in moc)
+                {
+                    if ((bool)mo["IPEnabled"] == true)
+                    {
+                        strMac = mo["MacAddress"].ToString();
+                    }
+                }
+                moc = null;
+                mc = null;
+                return strMac;
+            }
+            catch
+            {
+                return "unknown";
+            }
+        }
+        /// <summary>  
+        /// 操作系统的登录用户名  
+        /// </summary>  
+        /// <returns>系统的登录用户名</returns>  
+        public static string GetUserName()
+        {
+            try
+            {
+                string strUserName = string.Empty;
+                ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
+                ManagementObjectCollection moc = mc.GetInstances();
+                foreach (ManagementObject mo in moc)
+                {
+                    strUserName = mo["UserName"].ToString();
+                }
+                moc = null;
+                mc = null;
+                return strUserName;
+            }
+            catch
+            {
+                return "unknown";
+            }
+        }
+        /// <summary>  
+        /// 获取客户端内网IPv4地址  
+        /// </summary>  
+        /// <returns>客户端内网IPv4地址</returns>  
+        public static string GetClientLocalIPv4Address()
+        {
+            string strLocalIP = string.Empty;
+            try
+            {
+                IPHostEntry ipHost = Dns.Resolve(Dns.GetHostName());
+                IPAddress ipAddress = ipHost.AddressList[0];
+                strLocalIP = ipAddress.ToString();
+                return strLocalIP;
+            }
+            catch
+            {
+                return "unknown";
+            }
+        }
+    }
+}

+ 20 - 0
Client/IRevitCommandExcutor.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Client
+{
+    public interface IRevitCommandExcutor
+    {
+        /// <summary>
+        /// 执行Revit命令
+        /// </summary>
+        /// <param name="revitCmd">被执行的Revit命令</param>
+        /// <param name="param">执行命令的参数</param>
+        /// <param name="filePathList">用到的文件的路径</param>
+        /// <returns>任务执行结果返回json格式字符串</returns>
+        string ExecuteCmd(string revitCmd, string param, HashSet<string> filePathList);
+    }
+}

+ 113 - 0
Client/MessageHandler.cs

@@ -0,0 +1,113 @@
+using Cn.Sagacloud.Proto;
+using NettyClient;
+using NettyClient.proto;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Client
+{
+    class MessageHandler
+    {
+        private SimpleMessageHandler simpleHandler;
+        private TaskHandler taskHandler;
+        private bool isPauseTask = false;
+        private int maxTaskCount;
+        public MessageHandler(SimpleMessageHandler simpleHandler, int maxTaskCount, TaskHandler taskHandler) {
+            this.simpleHandler = simpleHandler;
+            this.maxTaskCount = maxTaskCount;
+            this.taskHandler = taskHandler;
+        }
+        public void setSimpleMessageHandler(SimpleMessageHandler simpleHandler) {
+            this.simpleHandler = simpleHandler;
+        }
+        public void HandleMessage(object obj) {
+            while (true) {
+                Message message;
+                bool hasMsg = SimpleMessageHandler.messageQueue.TryDequeue(out message);
+                if (!hasMsg) {
+                    Thread.Sleep(500);
+                    continue;
+                }
+                Command command = Command.Useless;
+                try
+                {
+                     command = (Command)Enum.Parse(typeof(Command), message.Cmd);
+                }
+                catch { command = Command.Useless; }
+                Message retMsg;
+                switch (command) {
+                    case Command.SendTask:
+                        // 1. 检测是否接受该任务 
+                        if (checkIsAcceptTask(message.TaskId))
+                        {
+                            // 2. 如果接受, 保存任务到数据库, 并同步该任务到内存, 并交由任务执行线程开始执行
+                            bool isSuccess = taskHandler.addOneTask(message.TaskId, message.Content);
+                            if (isSuccess)
+                            {
+                                retMsg = MessageUtil.generateMessage(Command.AcceptTask.ToString(), message.TaskId, "");
+                                simpleHandler.WriteMessage(retMsg);
+                            }
+                        }
+                        else {
+                            // 3. 如果拒绝, 直接返回拒绝消息
+                            retMsg = MessageUtil.generateMessage(Command.RefuseTask.ToString(), message.TaskId, "");
+                            simpleHandler.WriteMessage(retMsg);
+                        }
+                        break;
+                    case Command.ClientInfo: // 服务端要求客户端返回客户端信息
+                        ClientInfo info = new ClientInfo();
+                        info.Ipv4 = ClientInfoUtil.GetClientLocalIPv4Address();
+                        info.MacAddr = ClientInfoUtil.GetMacAddress();
+                        info.Name = ClientInfoUtil.GetUserName();
+                        retMsg = MessageUtil.generateMessage(Command.ClientInfo.ToString(), 0, JsonConvert.SerializeObject(info, Formatting.None));
+                        simpleHandler.WriteMessage(retMsg);
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        private bool checkIsAcceptTask(int taskId)
+        {
+            //一. isPauseTask == true的时候拒绝任务, 二. 如果已存在该任务, 则拒绝, 三. 如果当前任务数达到maxTaskCount, 拒绝
+            if (isPauseTask)
+                return false;
+            if (taskHandler.isContainTask(taskId)) {
+                return false;
+            }
+            if (taskHandler.taskModels.Count >= maxTaskCount)
+                return false;
+            return true;
+
+
+        }
+
+        internal void PauseAllTasks()
+        {
+            isPauseTask = true;
+        }
+
+        internal void ResumeAllTasks()
+        {
+            isPauseTask = false;
+        }
+    }
+
+    enum Command
+    {
+        SendTask,
+        RefuseTask,
+        AcceptTask,
+        DownloadError,
+        CommandError,
+        TaskSuccess,
+        ClientInfo,
+        Useless
+    }
+}

+ 36 - 0
Client/Properties/AssemblyInfo.cs

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

+ 25 - 0
Client/Readme.txt

@@ -0,0 +1,25 @@
+用到的dll
+DotNetty.Transport (>= 0.6.0)
+DotNetty.Buffers (>= 0.6.0)
+DotNetty.Common (>= 0.6.0)
+Microsoft.Extensions.Logging (1.1.0)
+Microsoft.Extensions.Logging.Abstractions(1.1.0)
+
+DotNetty.Codecs.Protobuf
+DotNetty.Codecs
+
+Google.Protobuf 3.2.0(最新版本3.7.0)
+
+数据库
+
+Mysql.Data 8.0
+NHibernate  5.2.5
+
+
+
+JSON
+newtonsoft.json
+
+
+直接运行Client会报错。
+启动Revit可以通信。

+ 41 - 0
Client/Start/CustomMessage.cs

@@ -0,0 +1,41 @@
+/* ==============================================================================
+ * 功能描述:自定义消息
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/12 11:55:31
+ * ==============================================================================*/
+
+namespace Client.Start
+{
+    /// <summary>
+    /// DotMessage
+    /// </summary>
+    class CustomMessage
+    {
+        public CustomMessage(bool mResult, string mResultMsg)
+        {
+            m_Result = mResult;
+            m_ResultMsg = mResultMsg;
+        }
+        private bool m_Result;
+        /// <summary>
+        /// 状态,暂定为bool类型
+        /// </summary>
+        public bool Result
+        {
+            get { return m_Result; }
+            set { m_Result = value; }
+        }
+
+        private string m_ResultMsg;
+        /// <summary>
+        /// 消息提示
+        /// </summary>
+        public string ResultMsg
+        {
+            get { return m_ResultMsg; }
+            set { m_ResultMsg = value; }
+        }
+
+
+    }
+}

+ 87 - 0
Client/Start/RevitCmdExecutor.cs

@@ -0,0 +1,87 @@
+/* ==============================================================================
+ * 功能描述:RevitCmdExecutor  
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/16 11:46:37
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Newtonsoft.Json.Linq;
+using System.Windows.Forms;
+using SAGA.DotNetUtils;
+using ServiceMBI.Modes;
+
+namespace Client.Start
+{
+    /// <summary>
+    /// RevitCmdExecutor
+    /// </summary>
+    public class RevitCmdExecutor : IRevitCommandExcutor
+    {
+        public string ExecuteCmd(string revitCmd, string param, HashSet<string> filePathList)
+        {
+            //由revitCmd生成实体类
+            //实体类传入参数、参考楼层列表
+            //执行方法,返回执行结果 
+            Console.WriteLine("准备执行命令");
+            IServiceCommand command = GetServiceCommand(revitCmd);
+            if (command == null) return $"命令 {revitCmd} 解析异常";
+            CustomMessage addMessage = null;
+            string combineParam = AddFilePathParam(param, filePathList, ref addMessage);
+            if (addMessage?.Result == false) return addMessage.ResultMsg;
+            string msg = "";
+            command.Execute(combineParam, ref msg);
+            return msg;
+        }
+        /// <summary>
+        /// 由Command的字符串转化为相应的命令
+        /// </summary>
+        /// <param name="revitCmd"></param>
+        /// <returns></returns>
+        private IServiceCommand GetServiceCommand(string revitCmd)
+        {
+            IServiceCommand command = null;
+
+            string dllName = "ServiceMBI.dll";
+            string className = "ServiceMBI.Commands." + revitCmd;
+
+            string path = Path.Combine(AppBaseInfo.DllRunPath, dllName);
+            Console.WriteLine(path);
+            if (File.Exists(path))
+            {
+                Assembly tempAsembly = Assembly.LoadFrom(path);
+                command = (tempAsembly.CreateInstance(className)) as IServiceCommand;
+            }
+
+            return command;
+        }
+        /// <summary>
+        /// 将ReferFloors参数,添加至参数列表中
+        /// </summary>
+        /// <param name="param"></param>
+        /// <param name="filePathList"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        private string AddFilePathParam(string param, HashSet<string> filePathList, ref CustomMessage message)
+        {
+            string floorskey = ServiceMBIBuiltInParameter.ReferFloors;
+            message = new CustomMessage(true, "Add Success");
+            try
+            {
+                JObject jObject = JObject.Parse(param);
+                jObject.Add(floorskey, new JArray((filePathList ?? new HashSet<string>()).ToArray()));
+                return jObject.ToString();
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+                message = new CustomMessage(false, "添加ReferFloors参数异常");
+            }
+
+            return null;
+        }
+    }
+}

+ 31 - 0
Client/Start/ServiceMBIClientHandler.cs

@@ -0,0 +1,31 @@
+/* ==============================================================================
+ * 功能描述:ServiceMBIClientHandler  
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/12 15:08:46
+ * ==============================================================================*/
+
+using System;
+using System.Windows.Forms;
+
+namespace Client.Start
+{
+    /// <summary>
+    /// ServiceMBIClientHandler
+    /// </summary>
+    public class ServiceMBIClientHandler
+    {
+        private static ClientApp m_Client;
+        public static void Start()
+        {
+            
+            m_Client = new ClientApp("172.16.0.183", 6666, "E:\\", 3, new RevitCmdExecutor(), 5);
+            m_Client.Start();
+            //Console.ReadKey();
+        }
+
+        public static void Stop()
+        {
+            m_Client?.Close();
+        }
+    }
+}

+ 195 - 0
Client/TaskHandler.cs

@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using HttpDownload;
+using NettyClient;
+using NettyClient.proto;
+using Newtonsoft.Json;
+using TaskDatabase;
+using TaskDatabase.Model;
+
+namespace Client
+{
+    class TaskHandler
+    {
+        private SimpleMessageHandler simpleHandler;
+        private TaskService taskService;
+        public IList<TaskModel> taskModels;
+        private TaskDownloadManager taskDownloadManager;
+        private string defaultFileDir;
+        IRevitCommandExcutor revitCommandExcutor;
+
+        public void RunTasks(object obj) {
+            while (true) {
+                try
+                {
+                    for (int i = taskModels.Count - 1; i > -1; --i) {
+                        TaskModel task = taskModels[i];
+                        TaskModel downloadException = null, commandException = null;
+                        bool isAllDownloaded = true;
+                        // 看当前任务依赖的文件下载状况
+                        foreach (DownloadTaskModel downloadTaskModel in task.DownloadTaskModelList) {
+                            DownloadTask download = taskDownloadManager.getDownloadTaskByDownloadTaskId(downloadTaskModel.Tid);
+                            if (download == null) // 如果还未加入下载队列
+                            {
+                                // 开始下载
+                                if (downloadTaskModel.Local_dir == null) {
+                                    downloadTaskModel.Local_dir = defaultFileDir + downloadTaskModel.Tid + ".rvt";
+                                } 
+                                download = taskDownloadManager.enqueueTask(task.Id, downloadTaskModel.Tid, downloadTaskModel.Task_url,
+                                    downloadTaskModel.Local_dir, downloadTaskModel.Task_md5, downloadTaskModel.Downloaded_bytes);
+                                taskDownloadManager.runTask(download);
+                                isAllDownloaded &= false;
+                            }
+                            else {
+                                // 如果该下载发生异常
+                                if (download.Status == DownloadStatus.ExceptionStopped) {
+                                    isAllDownloaded &= false;
+                                    downloadException = task;
+                                    break;
+                                }
+                                // 同步当前状态到数据库
+                                if (download.Status == DownloadStatus.Completed)
+                                {
+                                    downloadTaskModel.Finish_time = GetTimeStampSeconds();
+                                    isAllDownloaded &= true;
+                                }
+                                else {
+                                    isAllDownloaded &= false;
+                                }
+                                syncSingleDownTask(download, downloadTaskModel);
+                            }
+                        } // foreach end
+                        // 如果该下载任务下载失败
+                        if (downloadException != null)
+                        {
+                            task.Task_status = -1;
+                            taskService.UpdateTask(task);
+                            taskModels.RemoveAt(i);
+                            simpleHandler.WriteMessage(MessageUtil.generateMessage(Command.DownloadError.ToString(), task.Id, ""));
+                            continue;
+                        }
+                        // 如果该任务的所有下载文件均已完成, 开始执行Revit命令
+                        if (isAllDownloaded) {
+                            try
+                            {
+                                HashSet<string> fileSet = new HashSet<string>();
+                                foreach(var downloadModel in task.DownloadTaskModelList) {
+                                    fileSet.Add(downloadModel.Local_dir);
+                                }
+                                try
+                                {
+                                    string resultJson = revitCommandExcutor.ExecuteCmd(task.Task_cmd, task.Task_param, fileSet);
+                                    simpleHandler.WriteMessage(MessageUtil.generateMessage(Command.TaskSuccess.ToString(), task.Id, resultJson));
+                                    task.Task_status = 1;
+                                    task.Task_result_json = resultJson;
+                                    taskService.UpdateTask(task);
+                                    taskModels.RemoveAt(i);
+                                }
+                                catch(Exception ex) {
+                                    Console.WriteLine(ex.StackTrace);
+                                    commandException = task;
+                                }
+                            }
+                            catch(Exception ex) {
+                                Console.WriteLine(ex.StackTrace);
+                            }
+                        }
+                        if (commandException != null)
+                        {
+                            task.Task_status = -2;
+                            taskService.UpdateTask(task);
+                            taskModels.RemoveAt(i);
+                            simpleHandler.WriteMessage(MessageUtil.generateMessage(Command.CommandError.ToString(), task.Id, ""));
+                            continue;
+                        }
+                    }
+                    taskService.removeErrorTask();
+                }
+                catch (Exception ex){
+                    Console.WriteLine(ex.StackTrace);
+                }
+                Thread.Sleep(1000);
+                
+            }
+        }
+
+        private void syncSingleDownTask(DownloadTask downTask, DownloadTaskModel downloadModel)
+        {
+            bool changed = false;
+            if (downloadModel.Downloaded_bytes != downTask.BytesWritten)
+            {
+                downloadModel.Downloaded_bytes = downTask.BytesWritten;
+                changed = true;
+            }
+            if (downloadModel.File_bytes != downTask.totalFileSize)
+            {
+                downloadModel.File_bytes = downTask.totalFileSize;
+                changed = true;
+            }
+            if(changed)
+                taskService.UpdateDownload(downloadModel);
+        }
+
+        public void setSimpleMessageHandler(SimpleMessageHandler simpleHandler)
+        {
+            this.simpleHandler = simpleHandler;
+        }
+
+        private TaskHandler(SimpleMessageHandler simpleHandler, TaskService taskService)
+        {
+            this.simpleHandler = simpleHandler;
+            this.taskService = taskService;
+        }
+
+        public TaskHandler(SimpleMessageHandler simpleHandler, TaskService taskService, TaskDownloadManager taskDownloadManager, string defaultFileDir, IRevitCommandExcutor revitCommandExcutor) : this(simpleHandler, taskService)
+        {
+            this.taskDownloadManager = taskDownloadManager;
+            this.defaultFileDir = defaultFileDir;
+            this.revitCommandExcutor = revitCommandExcutor;
+        }
+
+        internal void SyncAllTask()
+        {
+            IList<TaskModel> tasks = taskService.GetTasksByStatus(0); // 任务状态 0 未执行完的任务, 1 执行完成  -1 下载出错  -2 revit命令执行异常
+            taskModels = tasks;
+        }
+        internal bool addOneTask(int taskId, string msgContent) {
+            try
+            {
+                TaskModel taskModel = JsonConvert.DeserializeObject<TaskModel>(msgContent);
+                taskService.AddTask(taskModel);
+                TaskModel task = taskService.GetTasksByTaskId(taskId)[0];
+                taskModels.Add(task);
+                foreach (DownloadTaskModel download in taskModel.DownloadTaskModelList) {
+                    download.Local_dir = defaultFileDir + download.Tid + ".rvt";
+                    taskService.UpdateDownload(download);
+                }
+                return true;
+            }
+            catch {
+                return false;
+            }
+        }
+
+        internal bool isContainTask(int taskId)
+        {
+            try
+            {
+                return taskService.isContainsTask(taskId);
+            }
+            catch (Exception ex){
+                Console.WriteLine(ex.StackTrace);
+                return true;
+            }
+        }
+
+        public static long GetTimeStampSeconds() {
+            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+            return (long)ts.TotalSeconds;
+        }
+    }
+}

+ 67 - 0
Client/app.config

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options.ConfigurationExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Transport" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Buffers" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Common" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Codecs" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 69 - 0
Client/packages.config

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="DotNetty.Buffers" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Common" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Transport" version="0.6.0" targetFramework="net461" />
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration.Abstractions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration.Binder" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Logging" version="1.1.1" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.1" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Options" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Primitives" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
+  <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
+  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net461" />
+  <package id="System.AppContext" version="4.3.0" targetFramework="net461" />
+  <package id="System.Buffers" version="4.4.0" targetFramework="net461" />
+  <package id="System.Collections" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
+  <package id="System.ComponentModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" />
+  <package id="System.Console" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Memory" version="4.5.1" targetFramework="net461" />
+  <package id="System.Net.Http" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
+  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net461" />
+  <package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net461" />
+  <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net461" />
+  <package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
+</packages>

+ 110 - 0
ClientTests/ClientTests.csproj

@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ClientTests</RootNamespace>
+    <AssemblyName>ClientTests</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
+    <IsCodedUITest>False</IsCodedUITest>
+    <TestProjectType>UnitTest</TestProjectType>
+    <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+  </ItemGroup>
+  <Choose>
+    <When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
+      <ItemGroup>
+        <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+      </ItemGroup>
+    </When>
+    <Otherwise />
+  </Choose>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Start\RevitCmdExecutorTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Client\Client.csproj">
+      <Project>{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}</Project>
+      <Name>Client</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Choose>
+    <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
+      <ItemGroup>
+        <Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+        <Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+        <Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+        <Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+          <Private>False</Private>
+        </Reference>
+      </ItemGroup>
+    </When>
+  </Choose>
+  <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.props'))" />
+    <Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.targets'))" />
+  </Target>
+  <Import Project="..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.1.18\build\net45\MSTest.TestAdapter.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.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 36 - 0
ClientTests/Properties/AssemblyInfo.cs

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

+ 32 - 0
ClientTests/Start/RevitCmdExecutorTests.cs

@@ -0,0 +1,32 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Client.Start;
+/* ==============================================================================
+* 功能描述:RevitCmdExecutorTests  
+* 创 建 者:Garrett
+* 创建日期:2019/4/16 14:40:52
+* ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+
+namespace Client.Start.Tests
+{
+    [TestClass()]
+    public class RevitCmdExecutorTests
+    {
+        [TestMethod()]
+        public void ExecuteCmdTest()
+        {
+            JObject jObject=new JObject();
+            jObject.Add("ProjectId", "Pj4201050001");
+            jObject.Add("UserId", "18612660722");
+            string json = jObject.ToString();
+            var executor=new RevitCmdExecutor();
+            executor.ExecuteCmd("DataCheckCommand", json, new HashSet<string>());
+            Assert.Fail();
+        }
+    }
+}

+ 67 - 0
ClientTests/app.config

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options.ConfigurationExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Transport" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Buffers" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Common" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Codecs" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 6 - 0
ClientTests/packages.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MSTest.TestAdapter" version="1.1.18" targetFramework="net461" />
+  <package id="MSTest.TestFramework" version="1.1.18" targetFramework="net461" />
+  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net461" />
+</packages>

BIN
Dlls/SAGA.RevitAPI.dll


+ 150 - 0
HttpDownload/DownloadTask.cs

@@ -0,0 +1,150 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HttpDownload
+{
+    public class DownloadTask
+    {
+        public int BelongingId { get; set; }
+        public int DownloadTaskId { get; set; }
+        public string FileUrl { get; }
+        public string FileDir { get; }
+        public long Offset { get; } // 开始下载的位置
+        public string ExpectedMD5 { get; }
+
+        private volatile DownloadStatus status;
+        public DownloadStatus Status { get { return status; } }
+        private string exceptionInfo;
+        public string ExceptionInfo { get { return exceptionInfo; } } //  保存发生异常时的Message
+        private double percentage = 0d;
+        private HttpDownloader httpDownloader = null;
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="fileUrl"></param>
+        /// <param name="fileDir"></param>
+        /// <param name="expectedMD5"></param>
+        /// <param name="offset">如果 offset == -1, 则把已写入文件的字节数当作offset</param>
+        public DownloadTask(string fileUrl, string fileDir, string expectedMD5, long offset = 0L)
+        {
+            this.FileUrl = fileUrl;
+            this.FileDir = fileDir;
+            this.Offset = offset;
+            this.ExpectedMD5 = expectedMD5;
+            status = DownloadStatus.Created;
+            exceptionInfo = string.Empty;
+            httpDownloader = new HttpDownloader(fileUrl, fileDir, offset);
+
+        }
+
+        public DownloadTask(int belongingId, int downTaskId, string fileUrl, string fileDir, string expectedMD5, long offset = 0L)
+        {
+            this.BelongingId = belongingId;
+            this.DownloadTaskId = downTaskId;
+            this.FileUrl = fileUrl;
+            this.FileDir = fileDir;
+            this.Offset = offset;
+            this.ExpectedMD5 = expectedMD5;
+            status = DownloadStatus.Created;
+            exceptionInfo = string.Empty;
+            httpDownloader = new HttpDownloader(fileUrl, fileDir, offset);
+        }
+
+
+        internal static void download(DownloadTask dTask)
+        {
+            try
+            {
+                if (dTask.status.Equals(DownloadStatus.Paused))
+                    return;
+                dTask.status = DownloadStatus.Processing;
+                dTask.httpDownloader.DownloadFile();
+                if (dTask.httpDownloader.running)
+                    dTask.status = DownloadStatus.Completed;
+            }
+            catch (Exception ex)
+            {
+                dTask.status = DownloadStatus.ExceptionStopped;
+                dTask.exceptionInfo = ex.Message;
+            }
+        }
+
+        public string calculateMD5()
+        {
+            if (Status.Equals(DownloadStatus.Completed))
+            {
+                string md5Digest = "";
+                return md5Digest;
+            }
+            return null;
+        }
+
+        public void pauseTask()
+        {
+            if (status == DownloadStatus.Completed)
+                return;
+            httpDownloader.running = false;
+            status = DownloadStatus.Paused;
+        }
+        public void resumeTask()
+        {
+            if (!httpDownloader.running)
+            {
+                httpDownloader.running = true;
+                status = DownloadStatus.WaitToRun;
+            }
+        }
+        public bool isFinished()
+        {
+            return httpDownloader.Finished;
+        }
+        public string getFileName()
+        {
+            return Path.GetFileName(FileDir);
+        }
+
+        public long totalFileSize
+        {
+            get
+            {
+                if (httpDownloader != null)
+                    return httpDownloader.TotalRemoteFileSize;
+                return 0;
+            }
+        }
+        public long BytesWritten
+        {
+            get
+            {
+                if (httpDownloader != null)
+                    return httpDownloader.BytesWritten;
+                return 0;
+            }
+        }
+        public string getSpeed(bool isFormatted)
+        {
+            if (httpDownloader != null && DownloadStatus.Processing.Equals(status))
+                return httpDownloader.getSpeed(isFormatted);
+            return "0 B/s";
+        }
+        public double getPercentage(int decimals)
+        {
+            if (httpDownloader != null)
+                return httpDownloader.getPercentage(decimals);
+            return 0d;
+        }
+    }
+    public enum DownloadStatus
+    {
+        Created, // 初始状态
+        WaitToRun, // 进入队列等待被执行 
+        Paused,    // 已暂停
+        Processing,// 正在执行
+        Completed, // 完成
+        ExceptionStopped // 出现异常已暂停
+    }
+}

+ 51 - 0
HttpDownload/HttpDownload.csproj

@@ -0,0 +1,51 @@
+<?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>{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HttpDownload</RootNamespace>
+    <AssemblyName>HttpDownload</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <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.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DownloadTask.cs" />
+    <Compile Include="HttpDownloader.cs" />
+    <Compile Include="LimitedConcurrencyLevelTaskScheduler.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TaskDownloadManager.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 281 - 0
HttpDownload/HttpDownloader.cs

@@ -0,0 +1,281 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO;
+using System.Net;
+
+namespace HttpDownload
+{
+    class HttpDownloader
+    {
+        const int bytebuff = 4096;
+        const int ReadWriteTimeOut = 10 * 1000;// 在写入超时或读取超时之前的毫秒数
+        const int TimeOutWait = 10 * 1000;// 请求超时前等待的毫秒数
+        const int MaxTryTime = 10; // 最大重试次数
+        int currentRetryTimes = 0;
+        private bool finished = false;
+        public bool Finished { get { return finished; } }
+        private long totalRemoteFileSize = 0L; // 要下载的文件的总大小
+        public long TotalRemoteFileSize { get { return totalRemoteFileSize; } }
+        public long BytesWritten { get { return offset; } }
+
+        string url, destPath;
+        private long offset, timeStamp, bytesAtTimeStamp;
+        volatile private int speed;
+        FileStream fs;
+        internal volatile bool running = false;
+
+
+        public HttpDownloader(string url, string destPath, long offset = 0)
+        {
+            this.destPath = destPath;
+            this.url = url;
+            this.offset = offset;
+        }
+
+        public void DownloadFile()
+        {
+            if (isDownloadFinished(offset))
+            {
+                return;
+            }
+            try
+            {
+                for (; !finished && running;)
+                    HttpDownloadFile();
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+        }
+        const string errorInfo = "下载结束, 但是文件长度与下载字节数不一致!";
+        /// <summary>
+        /// 下载文件(同步)  支持断点续传
+        /// </summary>
+        private bool HttpDownloadFile()
+        {
+            //打开上次下载的文件
+            //long lStartPos = 0;
+            fs = getFileStream();
+            HttpWebRequest request = null;
+            WebResponse respone = null;
+            Stream ns = null;
+            try
+            {
+                request = (HttpWebRequest)WebRequest.Create(url);
+                request.ReadWriteTimeout = ReadWriteTimeOut;
+                request.Timeout = TimeOutWait;
+                if (offset > 0)
+                    request.AddRange(offset);//设置Range值,断点续传
+
+                //向服务器请求,获得服务器回应数据流
+                respone = request.GetResponse();
+                ns = respone.GetResponseStream();
+                byte[] nbytes = new byte[bytebuff];
+                int nReadSize = ns.Read(nbytes, 0, bytebuff);
+                if (timeStamp == 0)
+                {
+                    timeStamp = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
+                    bytesAtTimeStamp = offset;
+                }
+                while (nReadSize > 0 && running)
+                {
+                    long now = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
+                    if (now - timeStamp >= 1000)
+                    {
+                        long dataDiff = offset - bytesAtTimeStamp, timeDiff = now - timeStamp;
+                        speed = (int)(dataDiff * 1000 / timeDiff);     // 1000是由ms转为s
+                        timeStamp = now;
+                        bytesAtTimeStamp = offset;
+                    }
+                    fs.Write(nbytes, 0, nReadSize);
+                    fs.Flush();
+                    offset += nReadSize;
+                    //Thread.Sleep(20);
+                    nReadSize = ns.Read(nbytes, 0, bytebuff);
+                }
+                if (!running)
+                    return true;
+                if (offset != totalRemoteFileSize && running)//文件长度不等于下载长度,下载出错
+                {
+                    throw new Exception(errorInfo);
+                }
+                if (running)
+                    finished = true;
+            }
+            catch (Exception ex)
+            {
+                if (ex.Message.Equals(errorInfo))
+                    throw ex;
+                ++currentRetryTimes;
+                if (currentRetryTimes > MaxTryTime)
+                {
+                    throw ex;
+                }
+            }
+            finally
+            {
+                if (ns != null)
+                    ns.Close();
+                if (fs != null)
+                    fs.Close();
+                if (request != null)
+                    request.Abort();
+            }
+            return false;
+        }
+
+        private FileStream getFileStream()
+        {
+            if (fs != null)
+            {
+                fs.Close();
+            }
+            if (File.Exists(destPath))
+            {
+                fs = File.OpenWrite(destPath);
+                // offset < 0 则按照文件的大小定为offset
+                if (offset < 0)
+                {
+                    offset = fs.Length;
+                }
+                fs.Seek(offset, SeekOrigin.Current);//移动文件流中的当前指针
+            }
+            else
+            {
+                string dirName = Path.GetDirectoryName(destPath);
+
+                if (!Directory.Exists(dirName))//如果不存在保存文件夹路径,新建文件夹
+                {
+                    Directory.CreateDirectory(dirName);
+                }
+                fs = new FileStream(destPath, FileMode.Create);
+                offset = 0;
+            }
+            return fs;
+        }
+
+        /// <summary>
+        /// 获取下载文件长度
+        /// </summary>
+        /// <param name="url"></param>
+        /// <returns></returns>
+        public static long GetFileContentLength(string url)
+        {
+            HttpWebRequest request = null;
+            try
+            {
+                request = (HttpWebRequest)HttpWebRequest.Create(url);
+                request.Timeout = TimeOutWait;
+                request.ReadWriteTimeout = ReadWriteTimeOut;
+                //向服务器请求,获得服务器回应数据流
+                WebResponse respone = request.GetResponse();
+                request.Abort();
+                return respone.ContentLength;
+            }
+            catch (Exception e)
+            {
+                if (request != null)
+                    request.Abort();
+                return 0;
+            }
+        }
+        private bool isDownloadFinished(long offset)
+        {
+            if (finished)
+                return true;
+            if (totalRemoteFileSize == 0)
+                totalRemoteFileSize = GetFileContentLength(url);
+            if (totalRemoteFileSize != 0 && totalRemoteFileSize == offset)
+            {
+                //下载完成
+                finished = true;
+                return true;
+            }
+            return false;
+        }
+        /// <summary>
+        /// 获取当前速度
+        /// </summary>
+        /// <param name="formatted"></param>
+        /// <returns></returns>
+        public string getSpeed(bool formatted)
+        {
+            if (formatted)
+            {
+                if (finished)
+                    return "0 kB/s";
+                else
+                {
+                    return formatSpeed(speed, 0L, 0);
+                }
+            }
+            else
+            {
+                if (finished)
+                    return "0";
+                else
+                    return speed + "";
+            }
+        }
+        private string formatSpeed(long speed, long decimalDigit, int depth)
+        {
+            if (speed < 1024)
+            {
+                return handleDigit(speed, decimalDigit) + getUnitByDepth(depth);
+            }
+            else
+            {
+                return formatSpeed(speed / 1024, speed % 1024, depth + 1);
+            }
+        }
+        private string handleDigit(long integer, long decimalDigit)
+        {
+            if (decimalDigit == 0)
+            {
+                return integer.ToString();
+            }
+            else
+            {
+                return integer.ToString() + Math.Round((double)decimalDigit / 1024, 1).ToString().Substring(1);
+            }
+        }
+        private string getUnitByDepth(int depth)
+        {
+            string val = string.Empty;
+            switch (depth)
+            {
+                case 0:
+                    val = " B/s";
+                    break;
+                case 1:
+                    val = " kB/s";
+                    break;
+                case 2:
+                    val = " MB/s";
+                    break;
+                case 3:
+                    val = " GB/s";
+                    break;
+                default:
+                    val = " unknown/s";
+                    break;
+            }
+            return val;
+        }
+        public double getPercentage(int decimals)
+        {
+            if (totalRemoteFileSize == 0L)
+            {
+                return Math.Round(0d, decimals);
+            }
+            if (finished)
+                return Math.Round(100d, decimals);
+            double percentage = (double)offset * 100d / totalRemoteFileSize;
+            return Math.Round(percentage, decimals);
+        }
+    }
+}

+ 184 - 0
HttpDownload/LimitedConcurrencyLevelTaskScheduler.cs

@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace HttpDownload
+{
+    class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
+    {
+        /// <summary>Whether the current thread is processing work items.</summary>
+        [ThreadStatic]
+        private static bool _currentThreadIsProcessingItems;
+        /// <summary>The list of tasks to be executed.</summary>
+        private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
+                                                                           /// <summary>The maximum concurrency level allowed by this scheduler.</summary>
+        private readonly int _maxDegreeOfParallelism;
+        /// <summary>Whether the scheduler is currently processing work items.</summary>
+        private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks)
+
+        /// <summary>
+        /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
+        /// specified degree of parallelism.
+        /// </summary>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
+        public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
+        {
+            if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
+            _maxDegreeOfParallelism = maxDegreeOfParallelism;
+        }
+
+        /// <summary>Queues a task to the scheduler.</summary>
+        /// <param name="task">The task to be queued.</param>
+        protected sealed override void QueueTask(Task task)
+        {
+            // Add the task to the list of tasks to be processed.  If there aren't enough
+            // delegates currently queued or running to process tasks, schedule another.
+            lock (_tasks)
+            {
+                _tasks.AddLast(task);
+                if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
+                {
+                    ++_delegatesQueuedOrRunning;
+                    NotifyThreadPoolOfPendingWork();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Informs the ThreadPool that there's work to be executed for this scheduler.
+        /// </summary>
+        private void NotifyThreadPoolOfPendingWork()
+        {
+            ThreadPool.UnsafeQueueUserWorkItem(_ =>
+            {
+                // Note that the current thread is now processing work items.
+                // This is necessary to enable inlining of tasks into this thread.
+                _currentThreadIsProcessingItems = true;
+                try
+                {
+                    // Process all available items in the queue.
+                    while (true)
+                    {
+                        Task item;
+                        lock (_tasks)
+                        {
+                            // When there are no more items to be processed,
+                            // note that we're done processing, and get out.
+                            if (_tasks.Count == 0)
+                            {
+                                --_delegatesQueuedOrRunning;
+                                break;
+                            }
+
+                            // Get the next item from the queue
+                            item = _tasks.First.Value;
+                            _tasks.RemoveFirst();
+                        }
+
+                        // Execute the task we pulled out of the queue
+                        base.TryExecuteTask(item);
+                    }
+                }
+                // We're done processing items on the current thread
+                finally { _currentThreadIsProcessingItems = false; }
+            }, null);
+        }
+
+        /// <summary>Attempts to execute the specified task on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued"></param>
+        /// <returns>Whether the task could be executed on the current thread.</returns>
+        protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            // If this thread isn't already processing a task, we don't support inlining
+            if (!_currentThreadIsProcessingItems) return false;
+
+            // If the task was previously queued, remove it from the queue
+            if (taskWasPreviouslyQueued) TryDequeue(task);
+
+            // Try to run the task.
+            return base.TryExecuteTask(task);
+        }
+
+        /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
+        /// <param name="task">The task to be removed.</param>
+        /// <returns>Whether the task could be found and removed.</returns>
+        protected sealed override bool TryDequeue(Task task)
+        {
+            lock (_tasks) return _tasks.Remove(task);
+        }
+
+        /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
+        public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
+
+        /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
+        /// <returns>An enumerable of the tasks currently scheduled.</returns>
+        protected sealed override IEnumerable<Task> GetScheduledTasks()
+        {
+            bool lockTaken = false;
+            try
+            {
+                Monitor.TryEnter(_tasks, ref lockTaken);
+                if (lockTaken) return _tasks.ToArray();
+                else throw new NotSupportedException();
+            }
+            finally
+            {
+                if (lockTaken) Monitor.Exit(_tasks);
+            }
+        }
+    }
+    class TaskFactoryMananger
+    {
+        //USE
+        public static void Run()
+        {
+
+            try
+            {
+                while (true)
+                {
+                    LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(10);
+                    TaskFactory factory = new TaskFactory(lcts);
+                    Task[] spiderTask = new Task[] {
+                        factory.StartNew(() =>
+                        {
+                            //Log.Logger.Information("{0} Start on thread {1}", "111", Thread.CurrentThread.ManagedThreadId);
+                            //Log.Logger.Information("{0} Finish  on thread {1}", "111", Thread.CurrentThread.ManagedThreadId);
+                        }),
+                        factory.StartNew(() =>
+                        {
+                            Thread.Sleep(TimeSpan.FromSeconds(3));
+                            //Log.Logger.Information("{0} Start on thread {1}", "222", Thread.CurrentThread.ManagedThreadId);
+                            //Log.Logger.Information("{0} Finish  on thread {1}", "222", Thread.CurrentThread.ManagedThreadId);
+                        }),
+                        factory.StartNew(() =>
+                        {
+                            Thread.Sleep(TimeSpan.FromSeconds(5));
+                            //Log.Logger.Information("{0} Start on thread {1}", "333", Thread.CurrentThread.ManagedThreadId);
+                            //Log.Logger.Information("{0} Finish  on thread {1}", "333", Thread.CurrentThread.ManagedThreadId);
+                        })
+                        };
+                    Task.WaitAll(spiderTask);
+                    Thread.Sleep(TimeSpan.FromMinutes(1));
+                }
+            }
+            catch (AggregateException ex)
+            {
+                foreach (Exception inner in ex.InnerExceptions)
+                {
+                    //Log.Logger.Error(inner.Message);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Provides a task scheduler that ensures a maximum concurrency level while
+        /// running on top of the ThreadPool.
+        /// </summary>
+
+    }
+}

+ 36 - 0
HttpDownload/Properties/AssemblyInfo.cs

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

+ 128 - 0
HttpDownload/TaskDownloadManager.cs

@@ -0,0 +1,128 @@
+using System;
+using System.Collections;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HttpDownload
+{
+    public class TaskDownloadManager
+    {
+        public int Capacity { get; set; }
+
+        // DownloadTask list
+        ArrayList allTasks = new ArrayList();
+
+        LimitedConcurrencyLevelTaskScheduler lcts = null;
+        TaskFactory factory = null;
+
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="count">最大同时任务数[1, 30], 异常为5</param>
+        public TaskDownloadManager(int count)
+        {
+            //ThreadPool.SetMaxThreads(count, count);
+            if (count >= 1 && count <= 30)
+                Capacity = count;
+            else
+                Capacity = 5;
+            lcts = new LimitedConcurrencyLevelTaskScheduler(Capacity);
+            factory = new TaskFactory(lcts);
+        }
+        /// <summary>
+        /// 添加任务到队列
+        /// </summary>
+        /// <param name="fileUrl">文件的下载地址</param>
+        /// <param name="fileDir">文件再本地的保存路径</param>
+        /// <param name="offset">在文件中开始下载的的位置, byte</param>
+        /// <returns>任务</returns>
+        public DownloadTask enqueueTask(string fileUrl, string fileDir, string expectedMD5, long offset = 0L)
+        {
+            DownloadTask task = new DownloadTask(fileUrl, fileDir, expectedMD5, offset);
+            allTasks.Add(task);
+            return task;
+        }
+        public DownloadTask enqueueTask(int belongingId, int downTaskId, string fileUrl, string fileDir, string expectedMD5, long offset = 0L)
+        {
+            DownloadTask task = new DownloadTask(belongingId, downTaskId, fileUrl, fileDir, expectedMD5, offset);
+            allTasks.Add(task);
+            return task;
+        }
+
+        public DownloadTask getDownloadTaskByDownloadTaskId(int downloadTaskId) {
+            foreach (DownloadTask down in allTasks) {
+                if (downloadTaskId == down.DownloadTaskId) {
+                    return down;
+                }
+            }
+            return null;
+        }
+        public void runAllTasks()
+        {
+            foreach (DownloadTask task in allTasks)
+            {
+                task.resumeTask();
+                factory.StartNew(() => { DownloadTask.download(task); });
+            }
+        }
+
+        public void pauseAllTasks()
+        {
+            foreach (DownloadTask task in allTasks)
+            {
+                task.pauseTask();
+            }
+        }
+        public void resumeAllTasks()
+        {
+            foreach (DownloadTask task in allTasks)
+            {
+                task.resumeTask();
+                factory.StartNew(() => { DownloadTask.download(task); });
+            }
+        }
+
+        public ArrayList getAllTasks() { return allTasks; }
+
+        public Hashtable getAllTasksMap() {
+            Hashtable table = new Hashtable();
+            foreach (DownloadTask down in allTasks) {
+                int belongingid = down.BelongingId;
+                if (table.ContainsKey(belongingid))
+                {
+                    ArrayList arr = (ArrayList)table[belongingid];
+                    arr.Add(down);
+                }
+                else {
+                    ArrayList arr = new ArrayList();
+                    arr.Add(down);
+                    table.Add(belongingid, arr);
+                }
+            }
+            return table;
+        }
+
+        public void runTask(DownloadTask task)
+        {
+            task.resumeTask();
+            factory.StartNew(() => { DownloadTask.download(task); });
+        }
+
+        public void pauseTask(DownloadTask task)
+        {
+            task.pauseTask();
+        }
+        public void resumeTask(DownloadTask task)
+        {
+            task.resumeTask();
+            factory.StartNew(() => { DownloadTask.download(task); });
+        }
+        public void removeTask(DownloadTask task)
+        {
+            task.pauseTask();
+            allTasks.Remove(task);
+        }
+    }
+}

+ 13 - 0
NettyClient/ClientWrapper.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NettyClient
+{
+    class ClientWrapper
+    {
+        
+    }
+}

+ 181 - 0
NettyClient/NettyClient.csproj

@@ -0,0 +1,181 @@
+<?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>{7A08D4E8-A171-47BD-A527-BC9BA1833305}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>NettyClient</RootNamespace>
+    <AssemblyName>NettyClient</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="DotNetty.Buffers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Buffers.0.6.0\lib\net45\DotNetty.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Codecs, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Codecs.0.6.0\lib\net45\DotNetty.Codecs.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Codecs.Protobuf, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Codecs.Protobuf.0.6.0\lib\net45\DotNetty.Codecs.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Common, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Common.0.6.0\lib\net45\DotNetty.Common.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Transport, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Transport.0.6.0\lib\net45\DotNetty.Transport.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.2.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.2.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration.Binder, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Options, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Primitives, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression.FileSystem" />
+    <Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime" />
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ClientWrapper.cs" />
+    <Compile Include="proto\MessageProto.cs" />
+    <Compile Include="proto\MessageUtil.cs" />
+    <Compile Include="TaskNettyClient.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SimpleMessageHandler.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 6 - 0
NettyClient/NettyClient.csproj.user

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectView>ShowAllFiles</ProjectView>
+  </PropertyGroup>
+</Project>

+ 36 - 0
NettyClient/Properties/AssemblyInfo.cs

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

+ 82 - 0
NettyClient/SimpleMessageHandler.cs

@@ -0,0 +1,82 @@
+using DotNetty.Transport.Channels;
+using System;
+using System.Collections.Concurrent;
+using System.Windows.Forms;
+using Message = Cn.Sagacloud.Proto.Message;
+
+namespace NettyClient
+{
+    public class SimpleMessageHandler : ChannelHandlerAdapter
+    {
+        public SimpleMessageHandler()
+        {
+
+            //var protobufEncoder = new ProtobufEncoder();
+        }
+        public static ConcurrentQueue<Message> messageQueue = new ConcurrentQueue<Message>();
+        public IChannelHandlerContext context;
+        public override void ChannelActive(IChannelHandlerContext context)
+        {
+            MessageBox.Show("connected");
+            this.context = context;
+        }
+        public override void ChannelRead(IChannelHandlerContext context, object message)
+        {
+            if (message is Message msg)
+            {
+                toString(msg);
+                messageQueue.Enqueue(msg);
+            }
+        }
+
+        public override void ChannelReadComplete(IChannelHandlerContext context)
+        {
+            context.Flush();
+        }
+
+        public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
+        {
+            Console.WriteLine("Exception: " + exception);
+            context.CloseAsync();
+        }
+        public override void ChannelInactive(IChannelHandlerContext context)
+        {
+            base.ChannelInactive(context);
+            Console.WriteLine("1");
+        }
+
+        public override void ChannelUnregistered(IChannelHandlerContext context)
+        {
+            base.ChannelUnregistered(context);
+            Console.WriteLine("2");
+        }
+
+        public override void HandlerRemoved(IChannelHandlerContext context)
+        {
+            base.HandlerRemoved(context);
+        }
+
+
+
+        public void toString(Message msg)
+        {
+            MessageBox.Show("Received from server: cmd : " + msg.Cmd + ", taskId : " + msg.TaskId + ", content : " + msg.Content);
+        }
+        public bool WriteMessage(Message message)
+        {
+            if (context == null || !context.Channel.Active)
+            {
+                return false;
+            }
+            try
+            {
+                context.WriteAndFlushAsync(message);
+            }
+            catch
+            {
+                return false;
+            }
+            return true;
+        }
+    }
+}

+ 109 - 0
NettyClient/TaskNettyClient.cs

@@ -0,0 +1,109 @@
+using DotNetty.Transport.Bootstrapping;
+using DotNetty.Transport.Channels;
+using DotNetty.Transport.Channels.Sockets;
+using System;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using DotNetty.Codecs.Protobuf;
+using Message = Cn.Sagacloud.Proto.Message;
+
+namespace NettyClient
+{
+    public class TaskNettyClient
+    {
+        private string ip;
+        private int port;
+        IChannel clientChannel;
+        MultithreadEventLoopGroup group;
+        Bootstrap bootstrap;
+        public TaskNettyClient(string ip, int port)
+        {
+            this.ip = ip;
+            this.port = port;
+        }
+        public async Task RunClientAsync(ChannelHandlerAdapter channelHandler)
+        {
+            group = new MultithreadEventLoopGroup();
+            try
+            {
+                bootstrap = new Bootstrap();
+                bootstrap
+                    .Group(group)
+                    .Channel<TcpSocketChannel>()
+                    .Option(ChannelOption.TcpNodelay, true)
+                    .Handler(
+                        new ActionChannelInitializer<ISocketChannel>(
+                            channel =>
+                            {
+                                //var protobufEncoder = new ProtobufEncoder();
+                                IChannelPipeline pipeline = channel.Pipeline;
+                                pipeline.AddLast(new ProtobufVarint32LengthFieldPrepender());
+                                pipeline.AddLast(new ProtobufVarint32FrameDecoder());
+                                pipeline.AddLast("encoder", new ProtobufEncoder());
+                                pipeline.AddLast("decoder", new ProtobufDecoder(Message.Parser));
+                                pipeline.AddLast("simple", channelHandler);
+
+                            }));
+                clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(ip), port));
+                //await clientChannel.CloseAsync();
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace + $"ip:{ip};port{port}");
+            }
+            finally
+            {
+                //await Task.WhenAll(group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
+            }
+        }
+        public async Task CloseAsync()
+        {
+            try
+            {
+                await clientChannel.CloseAsync();
+            }
+            catch { }
+            finally
+            {
+                await Task.WhenAll(group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
+            }
+        }
+
+        public static void Main(string[] args)
+        {
+            TaskNettyClient client = new TaskNettyClient("127.0.0.1", 6666);
+            SimpleMessageHandler simpleHandler = new SimpleMessageHandler();
+            client.RunClientAsync(simpleHandler).Wait();
+            while (true)
+            {
+                Thread.Sleep(15000);
+                client.CloseAsync().Wait();
+                // 重启
+                //client.RunClientAsync(new SimpleHandler()).Wait();
+            }
+        }
+    }
+
+    public static class NettyHelper
+    {
+        //static NettyHelper()
+        //{
+        //    Configuration = new ConfigurationBuilder()
+        //    //    .SetBasePath(ProcessDirectory)
+        //    //    .AddJsonFile("appsettings.json")
+        //        .Build();
+        //}
+
+        //public static IConfigurationRoot Configuration { get; }
+
+        //public static void SetConsoleLogger() => InternalLoggerFactory.DefaultFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, false));
+        //public static void SetConsoleLogger()
+        //{
+        //    InternalLoggerFactory.DefaultFactory.AddProvider(
+        //        new ConsoleLoggerProvider((s, level) => { level = Microsoft.Extensions.Logging.LogLevel.Error; return true; }, false)
+        //    );
+        //}
+    }
+}

+ 75 - 0
NettyClient/app.config

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.4.0.0" newVersion="3.4.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options.ConfigurationExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Common" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Codecs" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Buffers" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Transport" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 72 - 0
NettyClient/packages.config

@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="DotNetty.Buffers" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Codecs" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Codecs.Protobuf" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Common" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Transport" version="0.6.0" targetFramework="net461" />
+  <package id="Google.Protobuf" version="3.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration.Abstractions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration.Binder" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Logging" version="1.1.1" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.1" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Options" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Options.ConfigurationExtensions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Primitives" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
+  <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
+  <package id="System.AppContext" version="4.3.0" targetFramework="net461" />
+  <package id="System.Buffers" version="4.4.0" targetFramework="net461" />
+  <package id="System.Collections" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections.Immutable" version="1.5.0" targetFramework="net461" />
+  <package id="System.ComponentModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" />
+  <package id="System.Console" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Memory" version="4.5.1" targetFramework="net461" />
+  <package id="System.Net.Http" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
+  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net461" />
+  <package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net461" />
+  <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net461" />
+  <package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
+</packages>

+ 224 - 0
NettyClient/proto/MessageProto - 复制.cs

@@ -0,0 +1,224 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: MessageProto.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+using pb = Google.Protobuf;
+using pbr = Google.Protobuf.Reflection;
+namespace Cn.Sagacloud.Proto
+{
+
+    /// <summary>Holder for reflection information generated from MessageProto.proto</summary>
+    public static partial class MessageProtoReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for MessageProto.proto</summary>
+    public static pbr.FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr.FileDescriptor descriptor;
+
+    static MessageProtoReflection() {
+      byte[] descriptorData = System.Convert.FromBase64String(
+          string.Concat(
+            "ChJNZXNzYWdlUHJvdG8ucHJvdG8SEmNuLnNhZ2FjbG91ZC5wcm90byI3CgdN",
+            "ZXNzYWdlEgsKA2NtZBgBIAEoCRIOCgZ0YXNrSWQYAiABKAUSDwoHY29udGVu",
+            "dBgDIAEoCUIQQgxNZXNzYWdlUHJvdG9IAWIGcHJvdG8z"));
+      descriptor = pbr.FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr.FileDescriptor[] { },
+          new pbr.GeneratedClrTypeInfo(null, new pbr.GeneratedClrTypeInfo[] {
+            new pbr.GeneratedClrTypeInfo(typeof(Cn.Sagacloud.Proto.Message), Cn.Sagacloud.Proto.Message.Parser, new[]{ "Cmd", "TaskId", "Content" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  public sealed partial class Message : pb.IMessage<Message> {
+    private static readonly pb.MessageParser<Message> _parser = new pb.MessageParser<Message>(() => new Message());
+     private pb.UnknownFieldSet _unknownFields;
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb.MessageParser<Message> Parser { get { return _parser; } }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr.MessageDescriptor Descriptor {
+      get { return Cn.Sagacloud.Proto.MessageProtoReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr.MessageDescriptor pb.IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Message() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Message(Message other) : this() {
+      cmd_ = other.cmd_;
+      taskId_ = other.taskId_;
+      content_ = other.content_;
+         _unknownFields = pb.UnknownFieldSet.Clone(other._unknownFields);
+        }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Message Clone() {
+      return new Message(this);
+    }
+
+    /// <summary>Field number for the "cmd" field.</summary>
+    public const int CmdFieldNumber = 1;
+    private string cmd_ = "";
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Cmd {
+      get { return cmd_; }
+      set {
+        cmd_ = pb.ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "taskId" field.</summary>
+    public const int TaskIdFieldNumber = 2;
+    private int taskId_;
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int TaskId {
+      get { return taskId_; }
+      set {
+        taskId_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "content" field.</summary>
+    public const int ContentFieldNumber = 3;
+    private string content_ = "";
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Content {
+      get { return content_; }
+      set {
+        content_ = pb.ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as Message);
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(Message other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Cmd != other.Cmd) return false;
+      if (TaskId != other.TaskId) return false;
+      if (Content != other.Content) return false;
+        return Equals(_unknownFields, other._unknownFields);
+            return true;
+    }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Cmd.Length != 0) hash ^= Cmd.GetHashCode();
+      if (TaskId != 0) hash ^= TaskId.GetHashCode();
+      if (Content.Length != 0) hash ^= Content.GetHashCode();
+            if (_unknownFields != null) {hash ^= _unknownFields.GetHashCode();}
+            return hash;
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb.JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb.CodedOutputStream output) {
+      if (Cmd.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Cmd);
+      }
+      if (TaskId != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(TaskId);
+      }
+      if (Content.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(Content);
+      }
+
+            if (_unknownFields != null){_unknownFields.WriteTo(output);}
+        }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Cmd.Length != 0) {
+        size += 1 + pb.CodedOutputStream.ComputeStringSize(Cmd);
+      }
+      if (TaskId != 0) {
+        size += 1 + pb.CodedOutputStream.ComputeInt32Size(TaskId);
+      }
+      if (Content.Length != 0) {
+        size += 1 + pb.CodedOutputStream.ComputeStringSize(Content);
+      }
+
+             if (_unknownFields != null){size += _unknownFields.CalculateSize();}
+            return size;
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(Message other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Cmd.Length != 0) {
+        Cmd = other.Cmd;
+      }
+      if (other.TaskId != 0) {
+        TaskId = other.TaskId;
+      }
+      if (other.Content.Length != 0) {
+        Content = other.Content;
+      }
+        _unknownFields = pb.UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+        }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb.CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+_unknownFields = Google.Protobuf.UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+                        break;
+          case 10: {
+            Cmd = input.ReadString();
+            break;
+          }
+          case 16: {
+            TaskId = input.ReadInt32();
+            break;
+          }
+          case 26: {
+            Content = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code

+ 224 - 0
NettyClient/proto/MessageProto.cs

@@ -0,0 +1,224 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: MessageProto.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+using pb = Google.Protobuf;
+using pbr = Google.Protobuf.Reflection;
+namespace Cn.Sagacloud.Proto
+{
+
+    /// <summary>Holder for reflection information generated from MessageProto.proto</summary>
+    public static partial class MessageProtoReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for MessageProto.proto</summary>
+    public static pbr.FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr.FileDescriptor descriptor;
+
+    static MessageProtoReflection() {
+      byte[] descriptorData = System.Convert.FromBase64String(
+          string.Concat(
+            "ChJNZXNzYWdlUHJvdG8ucHJvdG8SEmNuLnNhZ2FjbG91ZC5wcm90byI3CgdN",
+            "ZXNzYWdlEgsKA2NtZBgBIAEoCRIOCgZ0YXNrSWQYAiABKAUSDwoHY29udGVu",
+            "dBgDIAEoCUIQQgxNZXNzYWdlUHJvdG9IAWIGcHJvdG8z"));
+      descriptor = pbr.FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr.FileDescriptor[] { },
+          new pbr.GeneratedClrTypeInfo(null, new pbr.GeneratedClrTypeInfo[] {
+            new pbr.GeneratedClrTypeInfo(typeof(Cn.Sagacloud.Proto.Message), Cn.Sagacloud.Proto.Message.Parser, new[]{ "Cmd", "TaskId", "Content" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  public sealed partial class Message : pb.IMessage<Message> {
+    private static readonly pb.MessageParser<Message> _parser = new pb.MessageParser<Message>(() => new Message());
+     //04 private pb.UnknownFieldSet _unknownFields;
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb.MessageParser<Message> Parser { get { return _parser; } }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr.MessageDescriptor Descriptor {
+      get { return Cn.Sagacloud.Proto.MessageProtoReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr.MessageDescriptor pb.IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Message() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Message(Message other) : this() {
+      cmd_ = other.cmd_;
+      taskId_ = other.taskId_;
+      content_ = other.content_;
+        //04  _unknownFields = pb.UnknownFieldSet.Clone(other._unknownFields);
+        }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public Message Clone() {
+      return new Message(this);
+    }
+
+    /// <summary>Field number for the "cmd" field.</summary>
+    public const int CmdFieldNumber = 1;
+    private string cmd_ = "";
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Cmd {
+      get { return cmd_; }
+      set {
+        cmd_ = pb.ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "taskId" field.</summary>
+    public const int TaskIdFieldNumber = 2;
+    private int taskId_;
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int TaskId {
+      get { return taskId_; }
+      set {
+        taskId_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "content" field.</summary>
+    public const int ContentFieldNumber = 3;
+    private string content_ = "";
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Content {
+      get { return content_; }
+      set {
+        content_ = pb.ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as Message);
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(Message other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Cmd != other.Cmd) return false;
+      if (TaskId != other.TaskId) return false;
+      if (Content != other.Content) return false;
+        //04  return Equals(_unknownFields, other._unknownFields);
+            return true;
+    }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Cmd.Length != 0) hash ^= Cmd.GetHashCode();
+      if (TaskId != 0) hash ^= TaskId.GetHashCode();
+      if (Content.Length != 0) hash ^= Content.GetHashCode();
+            //04   if (_unknownFields != null) {hash ^= _unknownFields.GetHashCode();}
+            return hash;
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb.JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb.CodedOutputStream output) {
+      if (Cmd.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Cmd);
+      }
+      if (TaskId != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(TaskId);
+      }
+      if (Content.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(Content);
+      }
+
+        //04    if (_unknownFields != null){_unknownFields.WriteTo(output);}
+        }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Cmd.Length != 0) {
+        size += 1 + pb.CodedOutputStream.ComputeStringSize(Cmd);
+      }
+      if (TaskId != 0) {
+        size += 1 + pb.CodedOutputStream.ComputeInt32Size(TaskId);
+      }
+      if (Content.Length != 0) {
+        size += 1 + pb.CodedOutputStream.ComputeStringSize(Content);
+      }
+
+            //04    if (_unknownFields != null){size += _unknownFields.CalculateSize();}
+            return size;
+    }
+
+    [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(Message other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Cmd.Length != 0) {
+        Cmd = other.Cmd;
+      }
+      if (other.TaskId != 0) {
+        TaskId = other.TaskId;
+      }
+      if (other.Content.Length != 0) {
+        Content = other.Content;
+      }
+        //04  _unknownFields = pb.UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+        }
+
+        [System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb.CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+              //04 _unknownFields = Google.Protobuf.UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+                        break;
+          case 10: {
+            Cmd = input.ReadString();
+            break;
+          }
+          case 16: {
+            TaskId = input.ReadInt32();
+            break;
+          }
+          case 26: {
+            Content = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code

+ 20 - 0
NettyClient/proto/MessageUtil.cs

@@ -0,0 +1,20 @@
+using Cn.Sagacloud.Proto;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NettyClient.proto
+{
+    public class MessageUtil
+    {
+        public static Message generateMessage(string cmd, int taskId, string content) {
+            Message msg = new Message();
+            msg.Cmd = cmd;
+            msg.TaskId = taskId;
+            msg.Content = content;
+            return msg;
+        }
+    }
+}

+ 74 - 0
SAGA.Revit/App.config

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+    </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options.ConfigurationExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Codecs" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Common" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Transport" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Buffers" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 9 - 0
SAGA.Revit/App.xaml

@@ -0,0 +1,9 @@
+<Application x:Class="SAGA.Revit.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:SAGA.Revit"
+             StartupUri="MainWindow.xaml">
+    <Application.Resources>
+         
+    </Application.Resources>
+</Application>

+ 17 - 0
SAGA.Revit/App.xaml.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace SAGA.Revit
+{
+    /// <summary>
+    /// App.xaml 的交互逻辑
+    /// </summary>
+    public partial class App : Application
+    {
+    }
+}

+ 17 - 0
SAGA.Revit/MainWindow.xaml

@@ -0,0 +1,17 @@
+<Window x:Class="SAGA.Revit.MainWindow"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:SAGA.Revit"
+        mc:Ignorable="d"
+        Title="上格云BIM" Height="300" Width="300">
+
+    <Canvas>
+        <Image Width="275" Height="225" Source="三维.jpg"></Image>
+        <Label  Canvas.Left="5" Canvas.Bottom="10" Content="请选择版本:"></Label>
+        <ComboBox Name="CmbRevit" Canvas.Left="80" Canvas.Bottom="10" Width="100" Text="Revit2016"></ComboBox>
+        <Button  Canvas.Left="190" Canvas.Bottom="10" Content="启动" Width="80"
+                 Click="ButtonBase_OnClick"></Button>
+    </Canvas>
+</Window>

+ 42 - 0
SAGA.Revit/MainWindow.xaml.cs

@@ -0,0 +1,42 @@
+
+/* ==============================================================================
+ * 功能描述:插件程序的启动界面
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/9/17 
+ * ==============================================================================*/
+ 
+using System.Collections.Generic;
+using System.Windows;
+using SAGA.RevitMenu.Addin;
+
+namespace SAGA.Revit
+{
+    /// <summary>
+    /// MainWindow.xaml 的交互逻辑
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        public MainWindow()
+        {
+            InitializeComponent();
+            this.Start();
+        }
+        
+        private RevitProductExt prodInfo;
+        private List<string> listTszProg;
+        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
+        {
+
+            var currentVersion = RevitVersionExt.Revit2017;
+            var prodInfo = RevitStartHelper.GetRevitProductExt(currentVersion);
+            listTszProg=new List<string>();
+            RevitStartHelper.StartRevit(prodInfo, listTszProg);
+            this.Close();
+        }
+
+        public void Start()
+        {
+            this.ButtonBase_OnClick(null,null);
+        }
+    }
+}

+ 55 - 0
SAGA.Revit/Properties/AssemblyInfo.cs

@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("SAGY.Revit")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SAGY.Revit")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+//若要开始生成可本地化的应用程序,请设置
+//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
+//例如,如果您在源文件中使用的是美国英语,
+//使用的是美国英语,请将 <UICulture> 设置为 en-US。  然后取消
+//对以下 NeutralResourceLanguage 特性的注释。  更新
+//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+                                     //(未在页面中找到资源时使用,
+                                     //或应用程序资源字典中找到时使用)
+    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+                                              //(未在页面中找到资源时使用,
+                                              //、应用程序或任何主题专用资源字典中找到时使用)
+)]
+
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
SAGA.Revit/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本: 4.0.30319.42000
+//
+//     对此文件的更改可能导致不正确的行为,如果
+//     重新生成代码,则所做更改将丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace SAGA.Revit.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("SAGY.Revit.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
SAGA.Revit/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
SAGA.Revit/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 SAGA.Revit.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
SAGA.Revit/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 44 - 0
SAGA.Revit/RevitInfo/RevitProductExt.cs

@@ -0,0 +1,44 @@
+
+/* ==============================================================================
+ * 功能描述:Revit 版本信息 对RevitProduct进行一次包装
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/9/17 
+ * ==============================================================================*/
+
+using System.IO;
+using Autodesk.RevitAddIns;
+
+namespace SAGY.Revit.RevitInfo
+{
+    public class RevitProductExt
+    {
+        public RevitProductExt(RevitProduct rp)
+        {
+            this.Name = rp.Name;
+            this.InstallLocation = rp.InstallLocation;
+            this.RevitExeFile = Path.Combine(this.InstallLocation, "Revit.exe");
+            this.CurrentUserAddInFolder = rp.CurrentUserAddInFolder;
+            this.AllUsersAddInFolder = rp.AllUsersAddInFolder;
+            this.Version = rp.Version.ToString();
+        }
+        /// <summary>
+        /// 公用 用户的文件夹路径
+        /// </summary>
+        public string AllUsersAddInFolder { get; set; }
+        /// <summary>
+        /// 当前用户的文件夹路径
+        /// </summary>
+        public string CurrentUserAddInFolder { get; set; }
+        /// <summary>
+        /// Revit 安装路径
+        /// </summary>
+        public string InstallLocation { get; set; }
+
+        public string Name { get; set; }
+
+        public string RevitExeFile { get; set; }
+
+        public string Version { get; set; }
+    }
+}
+

+ 309 - 0
SAGA.Revit/RevitInfo/RevitStartHelper.cs

@@ -0,0 +1,309 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using Autodesk.RevitAddIns;
+using SAGY.DotNetUtils;
+
+namespace SAGY.Revit.RevitInfo
+{
+    public static class RevitStartHelper
+    {
+        private const string AddInFormat = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RevitAddIns>\r\n<AddIn Type=\"Application\">\r\n<Name>{0}</Name>\r\n<Assembly>{1}</Assembly>\r\n<AddInId>{2}</AddInId>\r\n<FullClassName>{3}</FullClassName>\r\n<VendorId>{4}</VendorId>\r\n<VendorDescription>上格云技术, www.sagacloud.cn</VendorDescription>\r\n</AddIn>\r\n</RevitAddIns>";
+        /// <summary>
+        /// 启动完成后删除Addin文件
+        /// </summary>
+        /// <param name="addInId"></param>
+        /// <param name="strProductType"></param>
+        /// <param name="strRevitVersion"></param>
+        /// <returns></returns>
+        public static bool ClearAddInFile(Guid addInId, string strProductType, string strRevitVersion)
+        {
+            try
+            {
+                RevitVersionExt ext;
+                ProductType unknown = ProductType.Unknown;
+                string str7 = strProductType;
+                if (str7 != null)
+                {
+                    if (!(str7 == "Revit"))
+                    {
+                        if (str7 == "Architecture")
+                        {
+                            goto Label_0054;
+                        }
+                        if (str7 == "Structure")
+                        {
+                            goto Label_0058;
+                        }
+                        if (str7 == "MEP")
+                        {
+                            goto Label_005C;
+                        }
+                        if (str7 == "Unknown")
+                        {
+                            goto Label_0060;
+                        }
+                    }
+                    else
+                    {
+                        unknown = ProductType.Revit;
+                    }
+                }
+                goto Label_0062;
+            Label_0054:
+                unknown = ProductType.Architecture;
+                goto Label_0062;
+            Label_0058:
+                unknown = ProductType.Structure;
+                goto Label_0062;
+            Label_005C:
+                unknown = ProductType.MEP;
+                goto Label_0062;
+            Label_0060:
+                unknown = ProductType.Unknown;
+            Label_0062:
+                ext = GetRevitVersion(strRevitVersion);
+                if ((unknown == ProductType.Unknown) || (ext == RevitVersionExt.Unknown))
+                {
+                    return false;
+                }
+                //获取所有安装过的Revit版本
+                List<RevitProduct> allInstalledRevitProducts = RevitProductUtility.GetAllInstalledRevitProducts();
+                if ((allInstalledRevitProducts == null) || (allInstalledRevitProducts.Count <= 0))
+                {
+                    return false;
+                }
+                RevitProduct product = null;
+                foreach (RevitProduct product2 in allInstalledRevitProducts)
+                {
+                    if ((product2.Product == unknown) && (product2.Version == ((RevitVersion) ((int) ext))))
+                    {
+                        product = product2;
+                        break;
+                    }
+                }
+                if (product != null)
+                {
+                    string currentUserAddInFolder = product.CurrentUserAddInFolder;
+                    string allUsersAddInFolder = product.AllUsersAddInFolder;
+                    string str4 = GetTszPoductString(addInId.ToString()) + ".addin";
+                    string[] strArray = new string[] { currentUserAddInFolder, allUsersAddInFolder };
+                    foreach (string str5 in strArray)
+                    {
+                        if ((str5 != null) && (str5.Trim().Length > 0))
+                        {
+                            string path = Path.Combine(str5, str4);
+                            if (File.Exists(path))
+                            {
+                                try
+                                {
+                                    File.Delete(path);
+                                }
+                                catch
+                                {
+                                }
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+        }
+        /// <summary>
+        /// AddIn内部文件赋值
+        /// </summary>
+        /// <param name="strFormat"></param>
+        /// <param name="strAddInId"></param>
+        /// <returns></returns>
+        public static string GetAddInFormatString(string strFormat, string strAddInId)
+        {
+            string str = "上格云技术";
+            string str2 = "SAGY.RevitMenu.MenuApp";
+            string str3 = "SAGY";
+            string revitMenuDll = GetRevitMenuDll();
+            return string.Format(strFormat, new object[] { str, revitMenuDll, strAddInId, str2, str3 });
+        }
+        /// <summary>
+        /// 获取Revit启动加载dll的路径
+        /// </summary>
+        /// <returns></returns>
+        public static string GetRevitMenuDll()
+        {
+            return Path.Combine(Path.Combine(AppBaseInfo.AppRunPath, "OutputDll"), "SAGY.RevitMenu.dll");
+        }
+        /// <summary>
+        /// 获取已安装的Revit版本信息
+        /// </summary>
+        /// <returns></returns>
+        public static List<Revit.RevitInfo.RevitProductExt> GetRevitProductExts()
+        {
+            List<Revit.RevitInfo.RevitProductExt> list = new List<Revit.RevitInfo.RevitProductExt>();
+            foreach (RevitProduct product in RevitProductUtility.GetAllInstalledRevitProducts())
+            {
+                list.Add(new Revit.RevitInfo.RevitProductExt(product));
+            }
+            return list;
+        }
+
+
+        /// <summary>
+        /// 由R18获取Revit版本信息
+        /// </summary>
+        /// <param name="strVer"></param>
+        /// <returns></returns>
+        public static Revit.RevitInfo.RevitProductExt GetRevitProductVer(string strVer)
+        {
+            RevitProduct rp = null;
+            RevitVersionExt versionExt = GetRevitVersion2(strVer);
+            List<Revit.RevitInfo.RevitProductExt> revitProductExts = GetRevitProductExts();
+            Revit.RevitInfo.RevitProductExt revitProductExt =
+                revitProductExts.FirstOrDefault(t => t.Version.ToInt() == (int)versionExt);
+            return revitProductExt;
+        }
+
+        /// <summary>
+        /// 2018 转化为RevitVersionExt.Revit2018
+        /// </summary>
+        /// <param name="strVersionNumber"></param>
+        /// <returns></returns>
+        public static RevitVersionExt GetRevitVersion(string strVersionNumber)
+        {
+            RevitVersionExt result = RevitVersionExt.Unknown;
+
+            if (strVersionNumber == null)
+            {
+                return result;
+            }
+            string str = strVersionNumber;
+            int versionInt = str.ToInt();
+            int rvInt = versionInt - 2010;
+            try
+            {
+                result = (RevitVersionExt) rvInt;
+            }
+            catch 
+            {
+                //强转失败
+                result=RevitVersionExt.Unknown;
+            }
+            return result;
+        }
+        /// <summary>
+        /// R18 转化为RevitVersionExt.Revit2018
+        /// </summary>
+        /// <param name="strVersionNumber"></param>
+        /// <returns></returns>
+        public static RevitVersionExt GetRevitVersion2(string strVersionNumber)
+        {
+            RevitVersionExt result = RevitVersionExt.Unknown;
+
+            if (strVersionNumber == null)
+            {
+                return result;
+            }
+            //R18
+            string str = strVersionNumber.Substring(1);
+            //18
+            int versionInt = str.ToInt();
+            int rvInt = versionInt - 10;
+            try
+            {
+                result = (RevitVersionExt)rvInt;
+            }
+            catch
+            {
+                //强转失败
+                result = RevitVersionExt.Unknown;
+            }
+            return result;
+        }
+        /// <summary>
+        /// 获取AddIn文件的名称
+        /// </summary>
+        /// <param name="strAddInId"></param>
+        /// <returns></returns>
+        public static string GetTszPoductString(string strAddInId)
+        {
+            string str2;
+            string str = "";
+            //if (((str2 = strAddInId.ToUpper()) != null) && (str2 == "EABBE53F-04A0-4D10-905F-FE4DB67E1F3C"))
+            //{
+            //    str = "TSBIM";
+            //}
+            str = "SAGABIM";
+            return str;
+        }
+
+        [DllImport("shell32.dll")]
+        public static extern int ShellExecute(IntPtr hwnd, StringBuilder lpszOp, StringBuilder lpszFile, StringBuilder lpszParams, StringBuilder lpszDir, int fsShowCmd);
+        public static bool StartRevit(Revit.RevitInfo.RevitProductExt prodInfo, List<string> listTszProg)
+        {
+            try
+            {
+                string currentUserAddInFolder = prodInfo.CurrentUserAddInFolder;
+                string allUsersAddInFolder = prodInfo.AllUsersAddInFolder;
+                string[] strArray = new string[] { currentUserAddInFolder };
+                //foreach (string str3 in listTszProg)
+                {
+                    string str3 = "EABBE53F-04A0-4D10-905F-FE4DB67E1F3C";//addinid,后期可根据需要修改
+                    string str5 = GetTszPoductString(str3) + ".addin";
+                    foreach (string str6 in strArray)
+                    {
+                        if ((str6 != null) && (str6.Trim().Length > 0))
+                        {
+                            string path = Path.Combine(str6, str5);
+                            string str8 = Path.Combine(allUsersAddInFolder, str5);
+                            try
+                            {
+                                if (!Directory.Exists(str6))
+                                {
+                                    Directory.CreateDirectory(str6);
+                                }
+                                if (File.Exists(path))
+                                {
+                                    File.Delete(path);
+                                }
+                                if (File.Exists(str8))
+                                {
+                                    File.Delete(str8);
+                                }
+                            }
+                            catch
+                            {
+                            }
+                            using (StreamWriter writer = new StreamWriter(path, false, Encoding.UTF8))
+                            {
+                                string addInFormatString = GetAddInFormatString(AddInFormat, str3);
+                                if (!string.IsNullOrEmpty(addInFormatString))
+                                {
+                                    writer.Write(addInFormatString);
+                                }
+                                else
+                                {
+                                    MessageShowBase.Infomation("初始化Revit加载信息错误");
+                                    return false;
+                                }
+                            }
+                        }
+                    }
+                }
+                string directoryName = Path.GetDirectoryName(prodInfo.RevitExeFile);
+                return (ShellExecute(IntPtr.Zero, new StringBuilder("open"), new StringBuilder("Revit"), new StringBuilder(""), new StringBuilder(directoryName), 1) > 0x20);
+            }
+            catch (Exception exception)
+            {
+                MessageShowBase.Infomation("配置Revit加载文件失败,请以管理员登录或在控制面板中“更改UAC设置”。");
+                MessageShowBase.Show(exception);
+                return false;
+            }
+        }
+    }
+}
+

+ 23 - 0
SAGA.Revit/RevitInfo/RevitVersionExt.cs

@@ -0,0 +1,23 @@
+
+/* ==============================================================================
+ * 功能描述:Revit 版本的枚举
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/9/17 
+ * ==============================================================================*/
+
+namespace SAGY.Revit.RevitInfo
+{
+    public enum RevitVersionExt
+    {
+        Revit2011 = 1,
+        Revit2012 = 2,
+        Revit2013 = 3,
+        Revit2014 = 4,
+        Revit2015 = 5,
+        Revit2016 = 6,
+        Revit2017 = 7,
+        Revit2018 = 8,
+        Unknown = -1
+    }
+}
+

+ 373 - 0
SAGA.Revit/SAGA.Revit.csproj

@@ -0,0 +1,373 @@
+<?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>{26C0661D-086C-4352-84B0-03B5D493EC77}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>SAGY.Revit</RootNamespace>
+    <AssemblyName>SAGY.Revit</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</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>..\OutputDll\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R18|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R17|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R18|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\R18\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R17|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\R17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R18|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\R18\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'R17|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\R17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RR17|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RR17|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\RR17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RR17|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\RR17\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Antlr3.Runtime, Version=3.5.0.2, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
+      <HintPath>..\packages\Antlr3.Runtime.3.5.1\lib\net40-client\Antlr3.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Buffers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Buffers.0.6.0\lib\net45\DotNetty.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Codecs, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Codecs.0.6.0\lib\net45\DotNetty.Codecs.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Codecs.Protobuf, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Codecs.Protobuf.0.6.0\lib\net45\DotNetty.Codecs.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Common, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Common.0.6.0\lib\net45\DotNetty.Common.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Transport, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Transport.0.6.0\lib\net45\DotNetty.Transport.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.7.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.7.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="HttpDownload, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\SchedulerClient\HttpDownload\bin\Debug\HttpDownload.dll</HintPath>
+    </Reference>
+    <Reference Include="Iesi.Collections, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
+      <HintPath>..\packages\Iesi.Collections.4.0.4\lib\net461\Iesi.Collections.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="MySql.Data, Version=8.0.15.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <HintPath>..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="NHibernate, Version=5.2.0.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
+      <HintPath>..\packages\NHibernate.5.2.4\lib\net461\NHibernate.dll</HintPath>
+    </Reference>
+    <Reference Include="Remotion.Linq, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Remotion.Linq.2.2.0\lib\net45\Remotion.Linq.dll</HintPath>
+    </Reference>
+    <Reference Include="Remotion.Linq.EagerFetching, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Remotion.Linq.EagerFetching.2.2.0\lib\net45\Remotion.Linq.EagerFetching.dll</HintPath>
+    </Reference>
+    <Reference Include="SAGA.DotNetUtils">
+      <HintPath>..\..\ServiceMBI\Dlls\SAGA.DotNetUtils.dll</HintPath>
+    </Reference>
+    <Reference Include="ServiceMBI.Modes">
+      <HintPath>..\..\ServiceMBI\OutputDll\ServiceMBI.Modes.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Drawing.Design" />
+    <Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression.FileSystem" />
+    <Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Management" />
+    <Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
+      <Private>True</Private>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="TaskDatabase, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\SchedulerClient\TaskDatabase\bin\Debug\TaskDatabase.dll</HintPath>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Page Include="MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="三维.jpg" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\SAGA.RevitMenu\SAGA.RevitMenu.csproj">
+      <Project>{066ec682-baa8-4cf8-aae0-f08b962ba1dd}</Project>
+      <Name>SAGA.RevitMenu</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+  </PropertyGroup>
+</Project>

BIN
SAGA.Revit/三维.jpg


+ 1 - 1
SAGA.RevitMenu/Addin/RevitProductExt.cs

@@ -8,7 +8,7 @@
 using System.IO;
 using Autodesk.RevitAddIns;
 
-namespace SAGA.RevitUtility
+namespace SAGA.RevitMenu.Addin
 {
     public class RevitProductExt
     {

+ 1 - 1
SAGA.RevitMenu/Addin/RevitStartHelper.cs

@@ -9,7 +9,7 @@ using SAGA.DotNetUtils;
 using SAGA.DotNetUtils.Extend;
 using SAGA.DotNetUtils.Others;
 
-namespace SAGA.RevitUtility
+namespace SAGA.RevitMenu.Addin
 {
     public static class RevitStartHelper
     {

+ 1 - 1
SAGA.RevitMenu/Addin/RevitVersionExt.cs

@@ -5,7 +5,7 @@
  * 创建日期:2017/9/17 
  * ==============================================================================*/
 
-namespace SAGA.RevitUtility
+namespace SAGA.RevitMenu.Addin
 {
     public enum RevitVersionExt
     {

+ 0 - 234
SAGA.RevitMenu/ChangeProduct.cs

@@ -1,234 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Drawing;
-using System.IO;
-using System.Windows.Forms;
-using Microsoft.Win32;
-using SAGY.DotNetUtils;
-using SAGY.DotNetUtils.Configration;
-using SAGY.DotNetUtils.WinForms;
-using SAGY.RevitUtility;
-
-namespace SAGY.RevitMenu
-{
-    public class ChangeProduct : BaseForm
-    {
-        private static Dictionary<string, string> _mConfigParam;
-        private static Dictionary<string, string> _mConfigProduct;
-        private Button btn_Cancle;
-        private Button btn_OK;
-        private IContainer components;
-        private DataGridView dataGridView1;
-        private GroupBox groupBox1;
-        private DataGridViewTextBoxColumn ParamName;
-        private DataGridViewTextBoxColumn Path;
-        private DataGridViewTextBoxColumn ProName;
-        private DataGridViewTextBoxColumn Ver;
-
-        public ChangeProduct()
-        {
-            this.InitializeComponent();
-        }
-
-        private void btn_Cancle_Click(object sender, EventArgs e)
-        {
-            base.Close();
-        }
-
-        private void btn_OK_Click(object sender, EventArgs e)
-        {
-            if ((this.dataGridView1.CurrentRow != null) && (this.dataGridView1.CurrentRow.Index != -1))
-            {
-                string str = this.dataGridView1.Rows[this.dataGridView1.CurrentRow.Index].Cells["Path"].Value.ToString();
-                string str2 = this.dataGridView1.Rows[this.dataGridView1.CurrentRow.Index].Cells["ParamName"].Value.ToString();
-                Process process = new Process();
-                string fileName = str + @"DLL\TSZ.Revit.exe";
-                string str4 = RevitStartHelper.GetRevitProductVer1(VersionAdapter.RevitApiVersion);
-                ProcessStartInfo info = new ProcessStartInfo(fileName, str4 + " " + str2);
-                process.StartInfo = info;
-                process.Start();
-            }
-            base.Close();
-        }
-
-        private void ChangeProduct_Load(object sender, EventArgs e)
-        {
-            string path = AppBaseInfo.AppRunPath + @"\DLL\TSZ.Revit.exe";
-            if (File.Exists(path))
-            {
-                FileInfo info = new FileInfo(path);
-                this.Text = "当前程序版本:" + info.LastWriteTime.ToString("yyyy-MM-dd");
-            }
-            foreach (string str2 in Registry.LocalMachine.OpenSubKey(@"SOFTWARE\TszCAD").GetSubKeyNames())
-            {
-                string str3;
-                RegistryKey key2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\TszCAD\" + str2);
-                if ((key2 != null) && ConfigProduct.TryGetValue(str2.Substring(str2.LastIndexOf("-", StringComparison.Ordinal) + 1), out str3))
-                {
-                    string str4 = key2.GetValue("Path").ToString();
-                    string str5 = str4 + @"DLL\TSZ.Revit.exe";
-                    if (File.Exists(str5))
-                    {
-                        FileInfo info2 = new FileInfo(str5);
-                        string str6 = info2.LastWriteTime.ToString("yyyy-MM-dd");
-                        this.dataGridView1.Rows.Add(1);
-                        int num = this.dataGridView1.Rows.Count - 1;
-                        string str7 = str2.Split(new char[] { '-' })[0];
-                        this.dataGridView1.Rows[num].Cells["Ver"].Value = str7.Substring(str7.Length - 4) + "(" + str6 + ")";
-                        ProductEnum featuresBit = (ProductEnum) Enum.Parse(typeof(ProductEnum), str3);
-                        this.dataGridView1.Rows[num].Cells["ProName"].Value = ProductUtil.GetModuleName(featuresBit);
-                        ConfigParam.TryGetValue(str2.Substring(str2.LastIndexOf("-", StringComparison.Ordinal) + 1), out str3);
-                        this.dataGridView1.Rows[num].Cells["ParamName"].Value = str3;
-                        this.dataGridView1.Rows[num].Cells["Path"].Value = str4;
-                    }
-                }
-            }
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (this.components != null))
-            {
-                this.components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        private void InitializeComponent()
-        {
-            ComponentResourceManager manager = new ComponentResourceManager(typeof(ChangeProduct));
-            this.btn_Cancle = new Button();
-            this.btn_OK = new Button();
-            this.groupBox1 = new GroupBox();
-            this.dataGridView1 = new DataGridView();
-            this.Ver = new DataGridViewTextBoxColumn();
-            this.ProName = new DataGridViewTextBoxColumn();
-            this.ParamName = new DataGridViewTextBoxColumn();
-            this.Path = new DataGridViewTextBoxColumn();
-            this.groupBox1.SuspendLayout();
-            ((ISupportInitialize) this.dataGridView1).BeginInit();
-            base.SuspendLayout();
-            this.btn_Cancle.Location = new Point(0xe4, 0x128);
-            this.btn_Cancle.Name = "btn_Cancle";
-            this.btn_Cancle.Size = new Size(0x4b, 0x17);
-            this.btn_Cancle.TabIndex = 5;
-            this.btn_Cancle.Text = "关闭";
-            this.btn_Cancle.UseVisualStyleBackColor = true;
-            this.btn_Cancle.Click += new EventHandler(this.btn_Cancle_Click);
-            this.btn_OK.Location = new Point(0x93, 0x128);
-            this.btn_OK.Name = "btn_OK";
-            this.btn_OK.Size = new Size(0x4b, 0x17);
-            this.btn_OK.TabIndex = 4;
-            this.btn_OK.Text = "启动";
-            this.btn_OK.UseVisualStyleBackColor = true;
-            this.btn_OK.Click += new EventHandler(this.btn_OK_Click);
-            this.groupBox1.Controls.Add(this.dataGridView1);
-            this.groupBox1.Location = new Point(11, 15);
-            this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new Size(0x12a, 0x113);
-            this.groupBox1.TabIndex = 3;
-            this.groupBox1.TabStop = false;
-            this.groupBox1.Text = "已安装产品";
-            this.dataGridView1.AllowUserToAddRows = false;
-            this.dataGridView1.BackgroundColor = System.Drawing.Color.White;
-            this.dataGridView1.BorderStyle = BorderStyle.Fixed3D;
-            this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
-            this.dataGridView1.Columns.AddRange(new DataGridViewColumn[] { this.Ver, this.ProName, this.ParamName, this.Path });
-            this.dataGridView1.GridColor = System.Drawing.Color.White;
-            this.dataGridView1.Location = new Point(6, 20);
-            this.dataGridView1.MultiSelect = false;
-            this.dataGridView1.Name = "dataGridView1";
-            this.dataGridView1.ReadOnly = true;
-            this.dataGridView1.RowHeadersVisible = false;
-            this.dataGridView1.RowTemplate.Height = 0x17;
-            this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
-            this.dataGridView1.Size = new Size(0x11e, 0xf9);
-            this.dataGridView1.TabIndex = 0;
-            this.Ver.DataPropertyName = "Ver";
-            this.Ver.HeaderText = "版本";
-            this.Ver.Name = "Ver";
-            this.Ver.ReadOnly = true;
-            this.Ver.Width = 120;
-            this.ProName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
-            this.ProName.DataPropertyName = "ProName";
-            this.ProName.HeaderText = "名称";
-            this.ProName.Name = "ProName";
-            this.ProName.ReadOnly = true;
-            this.ParamName.DataPropertyName = "ParamName";
-            this.ParamName.HeaderText = "ParamName";
-            this.ParamName.Name = "ParamName";
-            this.ParamName.ReadOnly = true;
-            this.ParamName.Visible = false;
-            this.Path.DataPropertyName = "Path";
-            this.Path.HeaderText = "路径";
-            this.Path.Name = "Path";
-            this.Path.ReadOnly = true;
-            this.Path.Visible = false;
-            base.AutoScaleDimensions = new SizeF(6f, 12f);
-            base.ClientSize = new Size(0x141, 0x14c);
-            base.Controls.Add(this.btn_Cancle);
-            base.Controls.Add(this.btn_OK);
-            base.Controls.Add(this.groupBox1);
-            base.MaximizeBox = false;
-            base.MinimizeBox = false;
-            base.Name = "ChangeProduct";
-            base.StartPosition = FormStartPosition.CenterScreen;
-            this.Text = "产品切换";
-            base.Load += new EventHandler(this.ChangeProduct_Load);
-            this.groupBox1.ResumeLayout(false);
-            ((ISupportInitialize) this.dataGridView1).EndInit();
-            base.ResumeLayout(false);
-        }
-
-        public static Dictionary<string, string> ConfigParam
-        {
-            get
-            {
-                Dictionary<string, string> dictionary;
-                if (_mConfigParam == null)
-                {
-                    dictionary = new Dictionary<string, string>();
-                    dictionary.Add("TSRA", "TSRA");
-                    dictionary.Add("TSRS", "TSRS");
-                    dictionary.Add("TSPT", "TSPT");
-                    dictionary.Add("T3PT", "T3PT");
-                    dictionary.Add("TS3DSR", "TS3DSR");
-                    dictionary.Add("TSCC", "TSCC");
-                    dictionary.Add("TSCF", "TSCF");
-                    dictionary.Add("TSDCP", "TSDCP");
-                    dictionary.Add("TSRFA", "TSRFA");
-                    dictionary.Add("TSRMEP", "TSRMEP");
-                    dictionary.Add("地下特种结构", "TSIPS");
-                }
-                return (_mConfigParam = dictionary);
-            }
-        }
-
-        public static Dictionary<string, string> ConfigProduct
-        {
-            get
-            {
-                Dictionary<string, string> dictionary;
-                if (_mConfigProduct == null)
-                {
-                    dictionary = new Dictionary<string, string>();
-                    dictionary.Add("TSRA", "TSRA");
-                    dictionary.Add("TSRS", "TSRS");
-                    dictionary.Add("TSPT", "TSPTREVIT");
-                    dictionary.Add("T3PT", "T3PTREVIT");
-                    dictionary.Add("TS3DSR", "TS3DSR");
-                    dictionary.Add("TSCC", "TSCC");
-                    dictionary.Add("TSCF", "TSCF");
-                    dictionary.Add("TSDCP", "TSDCP");
-                    dictionary.Add("TSRFA", "TSRFA");
-                    dictionary.Add("TSRMEP", "TSRMEP");
-                    dictionary.Add("地下特种结构", "TSIPS");
-                }
-                return (_mConfigProduct = dictionary);
-            }
-        }
-    }
-}
-

+ 0 - 21
SAGA.RevitMenu/ChangeProductCmd.cs

@@ -1,21 +0,0 @@
-using Autodesk.Revit.Attributes;
-using Autodesk.Revit.DB;
-using Autodesk.Revit.UI;
-
-namespace SAGY.RevitMenu
-{
-    [Transaction(TransactionMode.Manual), Regeneration(RegenerationOption.Manual)]
-    public class ChangeProductCmd : ExternalCommand
-    {
-        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
-        {
-            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
-            {
-                return Result.Cancelled;
-            }
-            new ChangeProduct().ShowDialog(base.WinImpl);
-            return Result.Succeeded;
-        }
-    }
-}
-

+ 1 - 1
SAGA.RevitMenu/Configuration/MenuConfig.cs

@@ -17,8 +17,8 @@ using System.Xml;
 using Autodesk.Windows;
 using SAGA.DotNetUtils.Extend;
 using SAGA.DotNetUtils.Others;
+using SAGA.RevitMenu.Addin;
 using TSZ.RevitMenu.Configuration;
-using SAGA.RevitUtility;
 using RibbonItem = Autodesk.Revit.UI.RibbonItem;
 using RibbonPanel = Autodesk.Revit.UI.RibbonPanel;
 

+ 0 - 187
SAGA.RevitMenu/Globals.cs

@@ -1,187 +0,0 @@
-using System;
-using System.IO;
-using Autodesk.Revit.DB.Events;
-using Autodesk.Revit.UI;
-using Autodesk.Revit.UI.Events;
-using SAGY.DotNetUtils;
-using SAGY.RevitMenu.Configuration;
-using SAGY.RevitUtils;
-using SAGY.RevitUtils.Extends;
-using TSZ.RevitMenu;
-using TSZ.RevitMenu.Configuration;
-
-namespace SAGY.RevitMenu
-{
-    public class Globals : IRegisterDockpaneApp
-    {
-        private static ScreenMenu _dockMenu = null;
-        private static bool _mIsHide;
-        public const string ApplicationName = "屏幕菜单";
-        public const string DiagnosticsPanelName = "屏幕菜单";
-        public static ExternalCommandData ExtCmdData = null;
-        public static DockablePaneId MLeftDockablePanelId = new DockablePaneId(new Guid("7EB1ED3F-0993-4540-B291-D17FF539F5B9"));
-        public const string ScreenMenuState = "TSZ.ScreenMenu.State";
-        public static UIControlledApplication UiApp = null;
-
-        private void application_ApplicationClosing(object sender, ApplicationClosingEventArgs e)
-        {
-            _mIsHide = false;
-            if (GetState())
-            {
-                PressHelper.KeyPress("HIDMENU");
-                _mIsHide = true;
-            }
-            SaveState(_mIsHide);
-        }
-
-        private void ControlledApplication_DocumentCreated(object sender, DocumentCreatedEventArgs e)
-        {
-            if (!e.Document.IsFamilyDocument)
-            {
-                _mIsHide = GetState();
-                IntPtr mainWindowHandle = RevitProcess.GetMainWindowHandle();
-                if (_mIsHide)
-                {
-                    PressHelper.KeyPress(mainWindowHandle, "SHOMENU");
-                }
-                else
-                {
-                    PressHelper.KeyPress(mainWindowHandle, "HIDMENU");
-                }
-            }
-        }
-
-        private void ControlledApplication_DocumentOpened(object sender, DocumentOpenedEventArgs e)
-        {
-            if (!e.Document.IsFamilyDocument)
-            {
-                IntPtr mainWindowHandle = RevitProcess.GetMainWindowHandle();
-                _mIsHide = GetState();
-                if (_mIsHide)
-                {
-                    PressHelper.KeyPress(mainWindowHandle, "SHOMENU");
-                }
-                else
-                {
-                    PressHelper.KeyPress("HIDMENU");
-                }
-                AppRegister.RegisterStructRebarCount(e.Document);
-            }
-        }
-
-        public static bool GetState()
-        {
-            try
-            {
-                IniFileOperate operate = new IniFileOperate(Path.Combine(AppBaseInfo.AppTempFilePath, "TSZ.ScreenMenu.State.ini"));
-                return operate.ReadValue("RevitMenu", "TSZ.ScreenMenu.State").ToBool();
-            }
-            catch (Exception exception)
-            {
-                MessageShow.Show(exception, true, "");
-            }
-            return true;
-        }
-
-        public static void HidePanels(ExternalCommandData cmdData)
-        {
-            SetWindowVisibility(cmdData, MLeftDockablePanelId, false);
-        }
-
-        public static void HidePanels(UIControlledApplication application)
-        {
-            SetWindowVisibility(application, MLeftDockablePanelId, false);
-        }
-
-        public bool RegisterApp(UIControlledApplication application)
-        {
-            try
-            {
-                UiApp = application;
-                _dockMenu = new ScreenMenu();
-                _dockMenu.SetInitialDockingParameters(0, 150, 0, 700, DockPosition.Bottom, Guid.Empty);
-                application.RegisterDockablePane(MLeftDockablePanelId, "屏幕菜单", _dockMenu);
-                application.ControlledApplication.DocumentCreated += new EventHandler<DocumentCreatedEventArgs>(this.ControlledApplication_DocumentCreated);
-                application.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(this.ControlledApplication_DocumentOpened);
-                application.ApplicationClosing += new EventHandler<ApplicationClosingEventArgs>(this.application_ApplicationClosing);
-            }
-            catch (Exception exception)
-            {
-                MessageShow.Show(exception, false, "");
-                return false;
-            }
-            return true;
-        }
-
-        public static void SaveState(bool state)
-        {
-            try
-            {
-                new IniFileOperate(Path.Combine(AppBaseInfo.AppTempFilePath, "TSZ.ScreenMenu.State.ini")).WriteValue("RevitMenu", "TSZ.ScreenMenu.State", state.ToString());
-            }
-            catch (Exception exception)
-            {
-                MessageShow.Show(exception, true, "");
-            }
-        }
-
-        private static void SetWindowVisibility(ExternalCommandData cmdData, DockablePaneId dockablePaneId, bool state)
-        {
-            try
-            {
-                DockablePane dockablePane = cmdData.Application.GetDockablePane(dockablePaneId);
-                if (dockablePane != null)
-                {
-                    if (state)
-                    {
-                        _dockMenu.SetCmdData(cmdData);
-                        dockablePane.Show();
-                    }
-                    else
-                    {
-                        _dockMenu.SetCmdData(cmdData);
-                        dockablePane.Hide();
-                    }
-                }
-            }
-            catch (Exception exception)
-            {
-                MessageShow.Show(exception, false, "");
-            }
-        }
-
-        private static void SetWindowVisibility(UIControlledApplication application, DockablePaneId dockablePaneId, bool state)
-        {
-            try
-            {
-                DockablePane dockablePane = application.GetDockablePane(dockablePaneId);
-                if (dockablePane != null)
-                {
-                    if (state)
-                    {
-                        dockablePane.Show();
-                    }
-                    else
-                    {
-                        dockablePane.Hide();
-                    }
-                }
-            }
-            catch (Exception exception)
-            {
-                MessageShow.Show(exception, false, "");
-            }
-        }
-
-        public static void ShowPanels(ExternalCommandData cmdData)
-        {
-            SetWindowVisibility(cmdData, MLeftDockablePanelId, true);
-        }
-
-        public static void ShowPanels(UIControlledApplication application)
-        {
-            SetWindowVisibility(application, MLeftDockablePanelId, true);
-        }
-    }
-}
-

+ 39 - 136
SAGA.RevitMenu/MenuApp.cs

@@ -5,167 +5,70 @@
  * 创建日期:2017/8/30
  * ==============================================================================*/
 
-using System;
-using System.IO;
-using System.Windows;
 using Autodesk.Revit.Attributes;
-using Autodesk.Revit.DB.Events;
-using Autodesk.Revit.UI;
 using Autodesk.Revit.DB;
-using Autodesk.Revit.UI.Events;
+using Autodesk.Revit.UI;
+using Client;
 using SAGA.DotNetUtils;
-using SAGA.DotNetUtils.Extend;
-using SAGA.DotNetUtils.Logger;
-using SAGA.RevitMenu.Configuration;
-using SAGA.RevitMenu.Dockpane;
-using SAGA.RevitUtils.ErrorSupports;
-using SAGA.RevitUtils.Extends;
-using SAGA.RevitUtils.Log;
-using System.Threading;
+using SAGA.DotNetUtils.Others;
 using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+using ServiceMBI.Modes;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using Client.Start;
+using Microsoft.Extensions.Logging.Abstractions;
 
 namespace SAGA.RevitMenu
 {
+
     [Transaction(TransactionMode.Manual), Regeneration(RegenerationOption.Manual)]
     public class MenuApp : ExternalApplication
     {
+        //NettyClient.TaskNettyClient m_Client;
+
         public override Result OnShutdown(UIControlledApplication application)
         {
-            ErrorHandlers.Stop();
-            RevitEventsBingding.RemoveEvents(application);
+            //ErrorHandlers.Stop();
+            //RevitEventsBingding.RemoveEvents(application);
             base.OnShutdown(application);
-            TszDocChanged -= App_DocumentChanged;
-            application.ControlledApplication.DocumentClosing -= ControlledApplication_DocumentClosing;
+
+            #region 关闭ServiceMBI服务
+
+            //ServiceMBIClientHandler.Stop();
+
+            #endregion
+
             return Result.Succeeded;
         }
 
 
         public override Result OnStartup(UIControlledApplication application)
         {
-            ErrorHandlers.Start();
+            //ErrorHandlers.Start();
             base.OnStartup(application);
-         
-            StartSetting.RegiterPane(application);
-            //使用快捷键自动创建空间,需要先设置快捷键   
-            //ScreenMenuKeyBoardShortCut.SetKeyboardShortcuts(application.ControlledApplication.VersionName);
-            //记录空间设备修改;Chang时仅保存到临时文件中;Save时保存到log文件中;关闭是清除临时文件
-            TszDocChanged += App_DocumentChanged;
-            application.ControlledApplication.DocumentClosing += ControlledApplication_DocumentClosing;
-            RevitEventsBingding.AddEvents(application);
-            //将加载菜单逻辑后移 
-            if (!MenuConfig.LoadMenus(application))
-            {
-                return Result.Failed;
-            }
+            //Class1.Show();
+            //RevitEventsBingding.AddEvents(application);
             //删除Addin文件
-            MenuConfig.ClearAddInFile(application);
-            return Result.Succeeded;
-        }
+            //MenuConfig.ClearAddInFile(application);
 
-        private void ControlledApplication_DocumentClosing(object sender, DocumentClosingEventArgs e)
-        {
-            DocumentChangedLog.DeleteTempLog(e.Document.PathName);
-        }
+            //MessageShowBase.Infomation("PreStart");
+            //NettyClient.TaskNettyClient client = new NettyClient.TaskNettyClient("172.16.0.183", 6666);
+            //client.RunClientAsync(new NettyClient.SimpleMessageHandler()).Wait();
+            //MessageShowBase.Infomation("Start");
 
+            #region 启动ServiceMBI服务
 
-        /// <summary>
-        /// 记录操作日志
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void App_DocumentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
-        {
-            var doc = e.GetDocument();
-            if (doc.IsFamilyDocument) return;
-            var pathName = doc.PathName;
-            //楼层文件名称,无后缀
-            var docName = pathName.GetFileName();
-            
-            Func<ElementId, string> getTypeName = (elementId) => doc.GetElement(elementId).GetType().Name;
-            Func<ElementId, string> getFamilyName = (elementId) => doc.GetElement(elementId).GetFamily()?.Name;
-            Func<ElementId, string> getCategory = (elementId) => doc.GetElement(elementId).GetCategory().ToString();
-            //删除
-            var deletes = e.GetDeletedElementIds();
-            if (deletes.Count > 0)
-            {
-                foreach (var elementId in deletes)
-                {
-                    DocumentChangedLogMode mode = new DocumentChangedLogMode();
-                    mode.DataTime = DateTime.Now.ToString();
-                    mode.DocPath = pathName;
-                    mode.DocName = docName;
-                    mode.Operator = DocumentChangedOperator.Delete.ToString();
-                    mode.Id = elementId.ToString();
-                    
-                    DocumentChangedLog.Log(mode.DocPath, mode.ToJson());
-                }
-            }
-            //增加
-            var adds = e.GetAddedElementIds();
-            if (adds.Count > 0)
-            {
-                foreach (var elementId in adds)
-                {
-                    //if(!IsWatchType(doc,elementId))continue;
-                    DocumentChangedLogMode mode = new DocumentChangedLogMode();
-                    mode.DataTime = DateTime.Now.ToString();
-                    mode.DocPath = pathName;
-                    mode.DocName = docName;
-                    mode.Operator = DocumentChangedOperator.Add.ToString();
-                    mode.Id = elementId.ToString();
-                    mode.Type = getTypeName(elementId);
-                    mode.Family = getFamilyName(elementId);
-                    mode.Category = getCategory(elementId);
-                    DocumentChangedLog.Log(mode.DocPath, mode.ToJson());
-                }
-            }
-            //修改
-            var modifieds = e.GetModifiedElementIds();
-            if (modifieds.Count > 0)
-            {
-                foreach (var elementId in modifieds)
-                {
-                    //if (!IsWatchType(doc, elementId)) continue;
-                    DocumentChangedLogMode mode = new DocumentChangedLogMode();
-                    mode.DataTime = DateTime.Now.ToString();
-                    mode.DocPath = pathName;
-                    mode.DocName = docName;
-                    mode.Operator = DocumentChangedOperator.Modified.ToString();
-                    mode.Id = elementId.ToString();
-                    mode.Type = getTypeName(elementId);
-                    mode.Family = getFamilyName(elementId);
-                    mode.Category = getCategory(elementId);
-                    DocumentChangedLog.Log(mode.DocPath, mode.ToJson());
-                }
-            }
-        }
-        /// <summary>
-        /// 是否为需要监视的类型
-        /// </summary>
-        /// <param name="doc"></param>
-        /// <param name="elementId"></param>
-        /// <returns></returns>
-        private bool IsWatchType(Document doc, ElementId elementId)
-        {
-            var type = doc.GetElement(elementId).GetType().Name;
-            //族类型命名规则具有特殊性,不做有判定依据
-            var family = doc.GetElement(elementId).GetFamily()?.Name;
-            bool result = false;
-            switch (type)
-            {
-                case "SpaceTag":
-                    result = true;
-                    break;
-                case "Space":
-                    result = true;
-                    break;
-                case "FamilyInstance":
-                    result = true;
-                    break;
-            }
-            return result;
+            Client.Start.ServiceMBIClientHandler.Start();
+           
+            #endregion
+
+            return Result.Succeeded;
         }
-        
+
     }
+    
 }
 

+ 130 - 1
SAGA.RevitMenu/SAGA.RevitMenu.csproj

@@ -152,8 +152,42 @@
     <Reference Include="AdWindows">
       <HintPath>..\Dlls\RevitRefDll\AdWindows.dll</HintPath>
     </Reference>
+    <Reference Include="DotNetty.Buffers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Buffers.0.6.0\lib\net45\DotNetty.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Codecs, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Codecs.0.6.0\lib\net45\DotNetty.Codecs.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Common, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Common.0.6.0\lib\net45\DotNetty.Common.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Transport, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Transport.0.6.0\lib\net45\DotNetty.Transport.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.7.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.7.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Win32.Primitives">
+      <HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
+    <Reference Include="Remotion.Linq, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Remotion.Linq.2.2.0\lib\net45\Remotion.Linq.dll</HintPath>
+    </Reference>
+    <Reference Include="Remotion.Linq.EagerFetching, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Remotion.Linq.EagerFetching.2.2.0\lib\net45\Remotion.Linq.EagerFetching.dll</HintPath>
+    </Reference>
     <Reference Include="RevitAddInUtility">
       <HintPath>..\Dlls\RevitRefDll\RevitAddInUtility.dll</HintPath>
     </Reference>
@@ -170,16 +204,97 @@
       <HintPath>..\Dlls\SAGA.RevitUtils.dll</HintPath>
     </Reference>
     <Reference Include="System" />
+    <Reference Include="System.AppContext">
+      <HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Configuration.Install" />
+    <Reference Include="System.Console">
+      <HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="System.Core" />
+    <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
+    </Reference>
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Drawing.Design" />
+    <Reference Include="System.Globalization.Calendars">
+      <HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.IO.Compression">
+      <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.IO.Compression.FileSystem" />
+    <Reference Include="System.IO.Compression.ZipFile">
+      <HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.IO.FileSystem">
+      <HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.IO.FileSystem.Primitives">
+      <HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Management" />
+    <Reference Include="System.Net.Http">
+      <HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Net.Sockets">
+      <HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.InteropServices.RuntimeInformation">
+      <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Algorithms">
+      <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Encoding">
+      <HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Primitives">
+      <HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.X509Certificates">
+      <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Transactions" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xaml" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
     <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.ReaderWriter">
+      <HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="WindowsBase" />
   </ItemGroup>
   <ItemGroup>
@@ -210,5 +325,19 @@
   <ItemGroup>
     <WCFMetadata Include="Connected Services\" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Client\Client.csproj">
+      <Project>{6a52af44-63c6-4ab6-92d4-2a05173d45fb}</Project>
+      <Name>Client</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\ServiceMBI.Modes\ServiceMBI.Modes.csproj">
+      <Project>{676f1602-6f8a-44c7-bb81-2172d963ac1a}</Project>
+      <Name>ServiceMBI.Modes</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 1 - 1
SAGA.RevitMenu/SAGA.RevitMenu.csproj.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <ProjectView>ProjectFiles</ProjectView>
+    <ProjectView>ShowAllFiles</ProjectView>
   </PropertyGroup>
 </Project>

+ 0 - 217
SAGA.RevitMenu/ScreenMenu.cs

@@ -1,217 +0,0 @@
-using SAGY.RevitMenu;
-using SAGY.RevitMenu.Configuration;
-
-namespace TSZ.RevitMenu
-{
-    using Autodesk.Revit.UI;
-    using System;
-    using System.CodeDom.Compiler;
-    using System.ComponentModel;
-    using System.Diagnostics;
-    using System.Drawing;
-    using System.IO;
-    using System.Windows;
-    using System.Windows.Controls;
-    using System.Windows.Forms;
-    using System.Windows.Forms.Integration;
-    using System.Windows.Markup;
-    using TSZ.RevitBaseDll.Extends;
-    using TSZ.RevitMenu.Configuration;
-
-    public class ScreenMenu : Page, IDockablePaneProvider, IComponentConnector
-    {
-        private bool _contentLoaded;
-        private TszButtonData _curCmd;
-        private ExternalCommandData _extCmdData;
-        private ExternalEvent _externalEvent;
-        private RvtCmdExternalEventHandler _handler;
-        private int m_bottom = 1;
-        private int m_left = 1;
-        private DockPosition m_position = DockPosition.Bottom;
-        private int m_right = 1;
-        private Guid m_targetGuid;
-        private int m_top = 1;
-        internal OutlookBar obMenu;
-
-        public ScreenMenu()
-        {
-            this.InitializeComponent();
-            this._handler = new RvtCmdExternalEventHandler(this._extCmdData);
-            this._externalEvent = ExternalEvent.Create(this._handler);
-        }
-
-        [GeneratedCode("PresentationBuildTasks", "4.0.0.0"), DebuggerNonUserCode]
-        internal Delegate _CreateDelegate(System.Type delegateType, string handler)
-        {
-            return Delegate.CreateDelegate(delegateType, this, handler);
-        }
-
-        private void Host_SizeChanged(object sender, SizeChangedEventArgs e)
-        {
-            this.obMenu.UpdateSize(e.NewSize.Width, e.NewSize.Height);
-        }
-
-        [GeneratedCode("PresentationBuildTasks", "4.0.0.0"), DebuggerNonUserCode]
-        public void InitializeComponent()
-        {
-            if (!this._contentLoaded)
-            {
-                this._contentLoaded = true;
-                Uri resourceLocator = new Uri("/TSZ.RevitMenu;component/screenmenu.xaml", UriKind.Relative);
-                System.Windows.Application.LoadComponent(this, resourceLocator);
-            }
-        }
-
-        private void Page_FocusableChanged(object sender, DependencyPropertyChangedEventArgs e)
-        {
-            this.UpdateSize();
-        }
-
-        public void PanelEvent(object sender, EventArgs e)
-        {
-            try
-            {
-                if (this._extCmdData != null)
-                {
-                    System.Windows.Forms.Control control = (System.Windows.Forms.Control) sender;
-                    this._curCmd = control.Tag as TszButtonData;
-                    if (this._curCmd != null)
-                    {
-                        this._extCmdData.Application.ActiveViewFocus();
-                        this._handler.CurBtnCmd = this._curCmd;
-                        this._externalEvent.Raise();
-                        this.UpdateSize();
-                    }
-                }
-            }
-            catch (Exception exception)
-            {
-                MessageShow.Show(exception, false, "");
-            }
-        }
-
-        private void ScreenMenu_OnLoaded(object sender, RoutedEventArgs e)
-        {
-            if (this.obMenu.Controls.Count <= 0)
-            {
-                try
-                {
-                    bool blnRevit = false;
-                    foreach (TszTabData data in MenuConfig.GetConfigTabs(Globals.UiApp.ControlledApplication.VersionNumber, out blnRevit))
-                    {
-                        if (data.TabText != "MTSMENU")
-                        {
-                            CmdPanel panel = new CmdPanel();
-                            this.obMenu.AddTabButton(data.TabName, panel);
-                            foreach (TszPanelData data2 in data.Panels)
-                            {
-                                foreach (TszButtonData data3 in data2.Buttons)
-                                {
-                                    string path = data3.ImageName + "16.png";
-                                    if (File.Exists(path))
-                                    {
-                                        string caption = data3.ButtonText.Replace(" ", "").Replace("\r\n", "").Replace("\n", "");
-                                        panel.AddCmdButton(caption, System.Drawing.Image.FromFile(path), data3, new EventHandler(this.PanelEvent));
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    this.obMenu.SelectTabButton(0);
-                }
-                catch (Exception exception)
-                {
-                    MessageShow.Show(exception, false, "");
-                }
-            }
-        }
-
-        public void SetCmdData(ExternalCommandData cmdData)
-        {
-            this.ExtCmdData = cmdData;
-            if (this._handler != null)
-            {
-                this._handler.ExtCmdData = cmdData;
-            }
-        }
-
-        public void SetInitialDockingParameters(int left, int right, int top, int bottom, DockPosition position, Guid targetGuid)
-        {
-            this.m_position = position;
-            this.m_left = left;
-            this.m_right = right;
-            this.m_top = top;
-            this.m_bottom = bottom;
-            this.m_targetGuid = targetGuid;
-        }
-
-        public void SetupDockablePane(DockablePaneProviderData data)
-        {
-            DockablePaneId id;
-            data.FrameworkElement = this;
-            data.InitialState = new DockablePaneState();
-            data.InitialState.DockPosition = this.m_position;
-            if (this.m_targetGuid == Guid.Empty)
-            {
-                id = null;
-            }
-            else
-            {
-                id = new DockablePaneId(this.m_targetGuid);
-            }
-            if (this.m_position == DockPosition.Tabbed)
-            {
-                data.InitialState.TabBehind = id;
-            }
-            if (this.m_position == DockPosition.Floating)
-            {
-                data.InitialState.SetFloatingRectangle(new Autodesk.Revit.UI.Rectangle(this.m_left, this.m_top, this.m_right, this.m_bottom));
-            }
-        }
-
-        [GeneratedCode("PresentationBuildTasks", "4.0.0.0"), EditorBrowsable(EditorBrowsableState.Never), DebuggerNonUserCode]
-        void IComponentConnector.Connect(int connectionId, object target)
-        {
-            switch (connectionId)
-            {
-                case 1:
-                    ((ScreenMenu) target).Loaded += new RoutedEventHandler(this.ScreenMenu_OnLoaded);
-                    ((ScreenMenu) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
-                    ((ScreenMenu) target).FocusableChanged += new DependencyPropertyChangedEventHandler(this.Page_FocusableChanged);
-                    return;
-
-                case 2:
-                    ((WindowsFormsHost) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
-                    ((WindowsFormsHost) target).FocusableChanged += new DependencyPropertyChangedEventHandler(this.Page_FocusableChanged);
-                    return;
-
-                case 3:
-                    ((Grid) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
-                    return;
-
-                case 4:
-                    ((WindowsFormsHost) target).SizeChanged += new SizeChangedEventHandler(this.Host_SizeChanged);
-                    return;
-
-                case 5:
-                    this.obMenu = (OutlookBar) target;
-                    return;
-            }
-            this._contentLoaded = true;
-        }
-
-        private void UpdateSize()
-        {
-            this.obMenu.UpdateSize(base.RenderSize.Width, base.RenderSize.Height);
-        }
-
-        public ExternalCommandData ExtCmdData
-        {
-            set
-            {
-                this._extCmdData = value;
-            }
-        }
-    }
-}
-

+ 0 - 27
SAGA.RevitMenu/SetMenuCmd.cs

@@ -1,27 +0,0 @@
-using System.Windows.Forms;
-using Autodesk.Revit.Attributes;
-using Autodesk.Revit.DB;
-using Autodesk.Revit.UI;
-using SAGY.RevitUtils;
-
-namespace SAGY.RevitMenu
-{
-    [Regeneration(RegenerationOption.Manual), Transaction(TransactionMode.Manual)]
-    public class SetMenuCmd : ExternalCommand
-    {
-        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
-        {
-            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
-            {
-                return Result.Cancelled;
-            }
-            SetMenuForm form = new SetMenuForm();
-            if (form.ShowDialog(base.WinImpl) == DialogResult.OK)
-            {
-                MessageShow.Infomation("重新启动后菜单设置生效!");
-            }
-            return Result.Succeeded;
-        }
-    }
-}
-

+ 0 - 552
SAGA.RevitMenu/SetMenuForm.cs

@@ -1,552 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-using System.Windows.Forms;
-using Autodesk.Revit.DB;
-using SAGY.DotNetUtils;
-using SAGY.DotNetUtils.Configration;
-using SAGY.DotNetUtils.WinForms;
-using TSZ.RevitMenu.Configuration;
-using ComboBox = Autodesk.Revit.UI.ComboBox;
-using Tab = TSZ.RevitMenu.Configuration.Tab;
-
-namespace SAGY.RevitMenu
-{
-    public class SetMenuForm : BaseForm
-    {
-        private System.Windows.Forms.Button bn_Up;
-        private System.Windows.Forms.Button btn_Add;
-        private System.Windows.Forms.Button btn_Cancle;
-        private System.Windows.Forms.Button btn_Delete;
-        private System.Windows.Forms.Button btn_Down;
-        private System.Windows.Forms.Button btn_OK;
-        private System.Windows.Forms.Button btn_ReSet;
-        private ComboBox comboBox1;
-        private ComboBox comboBox2;
-        private IContainer components;
-        private GroupBox groupBox1;
-        private GroupBox groupBox2;
-        private Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> newDic = new Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>>();
-        private Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> originDic = new Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>>();
-        private TreeView treeView1;
-        private TreeView treeView2;
-        private List<string> xmlFile = new List<string>();
-
-        public SetMenuForm()
-        {
-            this.InitializeComponent();
-        }
-
-        private void bn_Up_Click(object sender, EventArgs e)
-        {
-            if ((this.treeView2.SelectedNode != null) && (this.treeView2.SelectedNode.Parent != null))
-            {
-                if (this.treeView2.SelectedNode.Index > 0)
-                {
-                    TreeNode selectedNode = this.treeView2.SelectedNode;
-                    int index = this.treeView2.SelectedNode.Index;
-                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(index--);
-                    this.treeView2.SelectedNode.Parent.Nodes.Insert(index, selectedNode);
-                }
-                else if (this.treeView2.SelectedNode.Parent.Index > 0)
-                {
-                    TreeNode node = this.treeView2.SelectedNode;
-                    int num2 = this.treeView2.SelectedNode.Index;
-                    int num3 = this.treeView2.SelectedNode.Parent.Index;
-                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(num2);
-                    this.treeView2.Nodes[num3 - 1].Nodes.Add(node);
-                }
-                this.ChangeData();
-            }
-        }
-
-        private void btn_Add_Click(object sender, EventArgs e)
-        {
-            Dictionary<TreeNode, TreeNode> dictionary = new Dictionary<TreeNode, TreeNode>();
-            foreach (TreeNode node in this.treeView1.Nodes)
-            {
-                if ((node.Nodes != null) || (node.Nodes.Count > 0))
-                {
-                    foreach (TreeNode node2 in node.Nodes)
-                    {
-                        if (node2.Checked)
-                        {
-                            dictionary.Add(node2, node2.Parent);
-                        }
-                    }
-                }
-            }
-            List<string> list = new List<string>();
-            List<TreeNode> list2 = new List<TreeNode>();
-            foreach (KeyValuePair<TreeNode, TreeNode> pair in dictionary)
-            {
-                if (!list.Contains(pair.Value.Text))
-                {
-                    list.Add(pair.Value.Text);
-                    TreeNode item = new TreeNode(pair.Value.Text) {
-                        Tag = pair.Value.Tag
-                    };
-                    list2.Add(item);
-                }
-            }
-            int num = 0;
-            foreach (string str in list)
-            {
-                bool flag = false;
-                foreach (TreeNode node4 in this.treeView2.Nodes)
-                {
-                    if (str == node4.Text)
-                    {
-                        flag = true;
-                        break;
-                    }
-                }
-                if (!flag)
-                {
-                    new TreeNode(str);
-                    this.treeView2.Nodes.Add(list2[num]);
-                }
-                num++;
-            }
-            foreach (KeyValuePair<TreeNode, TreeNode> pair2 in dictionary)
-            {
-                foreach (TreeNode node5 in this.treeView2.Nodes)
-                {
-                    if (((node5.Nodes == null) && (node5.Nodes.Count <= 0)) || !(node5.Text == pair2.Value.Text))
-                    {
-                        continue;
-                    }
-                    bool flag2 = false;
-                    foreach (TreeNode node6 in node5.Nodes)
-                    {
-                        if (node6.Text == pair2.Key.Text)
-                        {
-                            flag2 = true;
-                            break;
-                        }
-                    }
-                    if (!flag2)
-                    {
-                        node5.Nodes.Add(pair2.Key.Clone() as TreeNode);
-                    }
-                }
-            }
-            this.ChangeData();
-        }
-
-        private void btn_Cancle_Click(object sender, EventArgs e)
-        {
-            base.Close();
-            base.DialogResult = DialogResult.Cancel;
-        }
-
-        private void btn_Delete_Click(object sender, EventArgs e)
-        {
-            for (int i = 0; i < this.treeView2.Nodes.Count; i++)
-            {
-                TreeNode node = this.treeView2.Nodes[i];
-                if (node.Checked)
-                {
-                    node.Remove();
-                    i--;
-                }
-                else
-                {
-                    for (int j = 0; j < node.Nodes.Count; j++)
-                    {
-                        if (node.Nodes[j].Checked)
-                        {
-                            node.Nodes[j].Remove();
-                            j--;
-                        }
-                    }
-                }
-            }
-            this.ChangeData();
-        }
-
-        private void btn_Down_Click(object sender, EventArgs e)
-        {
-            if ((this.treeView2.SelectedNode != null) && (this.treeView2.SelectedNode.Parent != null))
-            {
-                if (this.treeView2.SelectedNode.Index < (this.treeView2.SelectedNode.Parent.Nodes.Count - 1))
-                {
-                    TreeNode selectedNode = this.treeView2.SelectedNode;
-                    int index = this.treeView2.SelectedNode.Index;
-                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(index++);
-                    this.treeView2.SelectedNode.Parent.Nodes.Insert(index, selectedNode);
-                }
-                else if (this.treeView2.SelectedNode.Parent.Index < (this.treeView2.Nodes.Count - 1))
-                {
-                    TreeNode node = this.treeView2.SelectedNode;
-                    int num2 = this.treeView2.SelectedNode.Index;
-                    int num3 = this.treeView2.SelectedNode.Parent.Index;
-                    this.treeView2.SelectedNode.Parent.Nodes.RemoveAt(num2);
-                    this.treeView2.Nodes[num3 + 1].Nodes.Insert(0, node);
-                }
-                this.ChangeData();
-            }
-        }
-
-        private void btn_OK_Click(object sender, EventArgs e)
-        {
-            List<Menus> list = new List<Menus>();
-            string strPath = Path.Combine(AppBaseInfo.AppRunPath, "Menu");
-            string path = Path.Combine(Path.Combine(AppBaseInfo.AppTempFilePath, "Menu"), AppBaseInfo.LoadArgs);
-            this.ReadXML(this.xmlFile, list, strPath);
-            foreach (Menus menus in list)
-            {
-                string appName = menus.App.AppName;
-                List<Tab> list2 = new List<Tab>();
-                List<TSZ.RevitMenu.Configuration.Panel> list3 = new List<TSZ.RevitMenu.Configuration.Panel>();
-                foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in this.newDic)
-                {
-                    if (pair.Key.Modules == appName)
-                    {
-                        list2.Add(pair.Key);
-                        list3.AddRange(pair.Value);
-                    }
-                }
-                if (list2.Count > 0)
-                {
-                    menus.Tab = list2.ToArray();
-                }
-                if (list3.Count > 0)
-                {
-                    menus.Panel = list3.ToArray();
-                }
-                if (!Directory.Exists(path))
-                {
-                    Directory.CreateDirectory(path);
-                }
-                XMLFile.SaveXMLFile<Menus>(Path.Combine(path, appName + ".xml"), menus);
-            }
-            base.DialogResult = DialogResult.OK;
-        }
-
-        private void btn_ReSet_Click(object sender, EventArgs e)
-        {
-            string path = Path.Combine(Path.Combine(AppBaseInfo.AppTempFilePath, "Menu"), AppBaseInfo.LoadArgs);
-            if (Directory.Exists(path))
-            {
-                DirectoryInfo info = new DirectoryInfo(path);
-                foreach (FileInfo info2 in info.GetFiles("*.xml"))
-                {
-                    info2.Delete();
-                }
-            }
-            base.DialogResult = DialogResult.OK;
-        }
-
-        private void ChangeData()
-        {
-            foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in this.newDic)
-            {
-                if (pair.Key.TabName == this.comboBox2.Text)
-                {
-                    Tab key = pair.Key;
-                    this.newDic.Remove(pair.Key);
-                    List<TSZ.RevitMenu.Configuration.Panel> list = new List<TSZ.RevitMenu.Configuration.Panel>();
-                    foreach (TreeNode node in this.treeView2.Nodes)
-                    {
-                        TSZ.RevitMenu.Configuration.Panel tag = node.Tag as TSZ.RevitMenu.Configuration.Panel;
-                        TSZ.RevitMenu.Configuration.Button[] buttonArray = new TSZ.RevitMenu.Configuration.Button[node.Nodes.Count];
-                        for (int i = 0; i < node.Nodes.Count; i++)
-                        {
-                            buttonArray[i] = node.Nodes[i].Tag as TSZ.RevitMenu.Configuration.Button;
-                            buttonArray[i].MenuTab = pair.Key.MenuTab;
-                            buttonArray[i].Modules = pair.Key.Modules;
-                        }
-                        tag.Button = buttonArray;
-                        list.Add(tag);
-                    }
-                    this.newDic.Add(key, list);
-                    break;
-                }
-            }
-        }
-
-        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
-        {
-            this.LoadTreeView(this.comboBox1, this.comboBox1.Text, this.treeView1, this.originDic);
-        }
-
-        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
-        {
-            this.LoadTreeView(this.comboBox2, this.comboBox2.Text, this.treeView2, this.newDic);
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (this.components != null))
-            {
-                this.components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        private void GetDictionary(List<Menus> menus, Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> dic)
-        {
-            List<Tab> list = new List<Tab>();
-            List<TSZ.RevitMenu.Configuration.Panel> list2 = new List<TSZ.RevitMenu.Configuration.Panel>();
-            for (int i = 0; i < menus.Count; i++)
-            {
-                list.AddRange(menus[i].Tab);
-                list2.AddRange(menus[i].Panel);
-            }
-            foreach (Tab tab in list)
-            {
-                List<TSZ.RevitMenu.Configuration.Panel> list3 = new List<TSZ.RevitMenu.Configuration.Panel>();
-                foreach (TSZ.RevitMenu.Configuration.Panel panel in list2)
-                {
-                    if (((panel.Button.Length > 0) && (panel.Button[0].MenuTab == tab.MenuTab)) && (panel.Button[0].Modules == tab.Modules))
-                    {
-                        list3.Add(panel);
-                    }
-                }
-                dic.Add(tab, list3);
-            }
-        }
-
-        private void InitializeComponent()
-        {
-            this.comboBox1 = new ComboBox();
-            this.btn_Add = new System.Windows.Forms.Button();
-            this.btn_Delete = new System.Windows.Forms.Button();
-            this.bn_Up = new System.Windows.Forms.Button();
-            this.btn_Down = new System.Windows.Forms.Button();
-            this.btn_OK = new System.Windows.Forms.Button();
-            this.btn_Cancle = new System.Windows.Forms.Button();
-            this.treeView1 = new TreeView();
-            this.treeView2 = new TreeView();
-            this.groupBox1 = new GroupBox();
-            this.groupBox2 = new GroupBox();
-            this.comboBox2 = new ComboBox();
-            this.btn_ReSet = new System.Windows.Forms.Button();
-            this.groupBox1.SuspendLayout();
-            this.groupBox2.SuspendLayout();
-            base.SuspendLayout();
-            this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
-            this.comboBox1.FormattingEnabled = true;
-            this.comboBox1.Location = new Point(6, 0x10);
-            this.comboBox1.Name = "comboBox1";
-            this.comboBox1.Size = new Size(0x9e, 20);
-            this.comboBox1.TabIndex = 0;
-            this.comboBox1.SelectedIndexChanged += new EventHandler(this.comboBox1_SelectedIndexChanged);
-            this.btn_Add.Location = new Point(370, 0x4a);
-            this.btn_Add.Name = "btn_Add";
-            this.btn_Add.Size = new Size(0x4b, 0x17);
-            this.btn_Add.TabIndex = 4;
-            this.btn_Add.Text = "添加";
-            this.btn_Add.UseVisualStyleBackColor = true;
-            this.btn_Add.Click += new EventHandler(this.btn_Add_Click);
-            this.btn_Delete.Location = new Point(370, 0x71);
-            this.btn_Delete.Name = "btn_Delete";
-            this.btn_Delete.Size = new Size(0x4b, 0x17);
-            this.btn_Delete.TabIndex = 5;
-            this.btn_Delete.Text = "删除";
-            this.btn_Delete.UseVisualStyleBackColor = true;
-            this.btn_Delete.Click += new EventHandler(this.btn_Delete_Click);
-            this.bn_Up.Location = new Point(370, 0x9c);
-            this.bn_Up.Name = "bn_Up";
-            this.bn_Up.Size = new Size(0x4b, 0x17);
-            this.bn_Up.TabIndex = 6;
-            this.bn_Up.Text = "上移";
-            this.bn_Up.UseVisualStyleBackColor = true;
-            this.bn_Up.Click += new EventHandler(this.bn_Up_Click);
-            this.btn_Down.Location = new Point(370, 0xc7);
-            this.btn_Down.Name = "btn_Down";
-            this.btn_Down.Size = new Size(0x4b, 0x17);
-            this.btn_Down.TabIndex = 7;
-            this.btn_Down.Text = "下移";
-            this.btn_Down.UseVisualStyleBackColor = true;
-            this.btn_Down.Click += new EventHandler(this.btn_Down_Click);
-            this.btn_OK.Location = new Point(0x114, 0x139);
-            this.btn_OK.Name = "btn_OK";
-            this.btn_OK.Size = new Size(0x4b, 0x17);
-            this.btn_OK.TabIndex = 8;
-            this.btn_OK.Text = "确定";
-            this.btn_OK.UseVisualStyleBackColor = true;
-            this.btn_OK.Click += new EventHandler(this.btn_OK_Click);
-            this.btn_Cancle.Location = new Point(370, 0x139);
-            this.btn_Cancle.Name = "btn_Cancle";
-            this.btn_Cancle.Size = new Size(0x4b, 0x17);
-            this.btn_Cancle.TabIndex = 9;
-            this.btn_Cancle.Text = "取消";
-            this.btn_Cancle.UseVisualStyleBackColor = true;
-            this.btn_Cancle.Click += new EventHandler(this.btn_Cancle_Click);
-            this.treeView1.CheckBoxes = true;
-            this.treeView1.Location = new Point(6, 0x21);
-            this.treeView1.Name = "treeView1";
-            this.treeView1.Size = new Size(0x9e, 0xfd);
-            this.treeView1.TabIndex = 10;
-            this.treeView1.AfterCheck += new TreeViewEventHandler(this.treeView1_AfterCheck);
-            this.treeView2.CheckBoxes = true;
-            this.treeView2.Location = new Point(6, 0x21);
-            this.treeView2.Name = "treeView2";
-            this.treeView2.Size = new Size(0x9e, 0xfd);
-            this.treeView2.TabIndex = 11;
-            this.treeView2.AfterCheck += new TreeViewEventHandler(this.treeView2_AfterCheck);
-            this.groupBox1.Controls.Add(this.treeView1);
-            this.groupBox1.Controls.Add(this.comboBox1);
-            this.groupBox1.Location = new Point(12, 0x10);
-            this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new Size(0xa9, 0x126);
-            this.groupBox1.TabIndex = 14;
-            this.groupBox1.TabStop = false;
-            this.groupBox1.Text = "设置前菜单";
-            this.groupBox2.Controls.Add(this.comboBox2);
-            this.groupBox2.Controls.Add(this.treeView2);
-            this.groupBox2.Location = new Point(0xbb, 0x10);
-            this.groupBox2.Name = "groupBox2";
-            this.groupBox2.Size = new Size(0xa9, 0x126);
-            this.groupBox2.TabIndex = 15;
-            this.groupBox2.TabStop = false;
-            this.groupBox2.Text = "设置后菜单";
-            this.comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
-            this.comboBox2.FormattingEnabled = true;
-            this.comboBox2.Location = new Point(6, 0x10);
-            this.comboBox2.Name = "comboBox2";
-            this.comboBox2.Size = new Size(0x9e, 20);
-            this.comboBox2.TabIndex = 11;
-            this.comboBox2.SelectedIndexChanged += new EventHandler(this.comboBox2_SelectedIndexChanged);
-            this.btn_ReSet.Location = new Point(0xb0, 0x13c);
-            this.btn_ReSet.Name = "btn_ReSet";
-            this.btn_ReSet.Size = new Size(0x4b, 0x17);
-            this.btn_ReSet.TabIndex = 0x10;
-            this.btn_ReSet.Text = "恢复设置";
-            this.btn_ReSet.UseVisualStyleBackColor = true;
-            this.btn_ReSet.Click += new EventHandler(this.btn_ReSet_Click);
-            base.AutoScaleDimensions = new SizeF(6f, 12f);
-            base.AutoScaleMode = AutoScaleMode.Font;
-            base.ClientSize = new Size(0x1c5, 350);
-            base.Controls.Add(this.btn_ReSet);
-            base.Controls.Add(this.groupBox2);
-            base.Controls.Add(this.groupBox1);
-            base.Controls.Add(this.btn_Cancle);
-            base.Controls.Add(this.btn_OK);
-            base.Controls.Add(this.btn_Down);
-            base.Controls.Add(this.bn_Up);
-            base.Controls.Add(this.btn_Delete);
-            base.Controls.Add(this.btn_Add);
-            base.MaximizeBox = false;
-            base.MinimizeBox = false;
-            base.Name = "SetMenuForm";
-            this.Text = "设置菜单";
-            base.Load += new EventHandler(this.SetMenuForm_Load);
-            this.groupBox1.ResumeLayout(false);
-            this.groupBox2.ResumeLayout(false);
-            base.ResumeLayout(false);
-        }
-
-        private void LoadData(ComboBox cmb, Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> dic)
-        {
-            foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in dic)
-            {
-                cmb.Items.Add(pair.Key.TabName);
-            }
-            if (cmb.Items.Count > 0)
-            {
-                cmb.SelectedIndex = 0;
-            }
-        }
-
-        private void LoadTreeView(ComboBox cmb, string tabName, TreeView tv, Dictionary<Tab, List<TSZ.RevitMenu.Configuration.Panel>> dic)
-        {
-            tv.Nodes.Clear();
-            foreach (KeyValuePair<Tab, List<TSZ.RevitMenu.Configuration.Panel>> pair in dic)
-            {
-                if (pair.Key.TabName == tabName)
-                {
-                    foreach (TSZ.RevitMenu.Configuration.Panel panel in pair.Value)
-                    {
-                        TreeNode node = new TreeNode(panel.PanelName) {
-                            Tag = panel
-                        };
-                        foreach (TSZ.RevitMenu.Configuration.Button button in panel.Button)
-                        {
-                            if (button.ButtonStyles == "Separator")
-                            {
-                                button.ButtonText = "——";
-                            }
-                            TreeNode node2 = new TreeNode(button.ButtonText) {
-                                Tag = button
-                            };
-                            node.Nodes.Add(node2);
-                        }
-                        tv.Nodes.Add(node);
-                    }
-                }
-            }
-        }
-
-        private void ReadXML(List<string> xmlFile, List<Menus> menus, string strPath)
-        {
-            DirectoryInfo info = new DirectoryInfo(strPath);
-            foreach (FileInfo info2 in info.GetFiles("*.xml"))
-            {
-                Menus x = new Menus();
-                if (xmlFile.Contains(Path.GetFileNameWithoutExtension(info2.FullName)))
-                {
-                    XMLFile.OpenXMLFile<Menus>(info2.FullName, ref x);
-                    menus.Add(x);
-                }
-            }
-        }
-
-        private void SetMenuForm_Load(object sender, EventArgs e)
-        {
-            this.xmlFile.AddRange(AppBaseInfo.LoadArgs.ToString().Split(new char[] { ',' }));
-            List<Menus> menus = new List<Menus>();
-            List<Menus> list2 = new List<Menus>();
-            string strPath = Path.Combine(AppBaseInfo.AppRunPath, "Menu");
-            string path = Path.Combine(AppBaseInfo.AppTempFilePath, "Menu");
-            this.ReadXML(this.xmlFile, menus, strPath);
-            if (Directory.Exists(path))
-            {
-                this.ReadXML(this.xmlFile, list2, path);
-            }
-            this.GetDictionary(menus, this.originDic);
-            if ((list2 != null) && (list2.Count > 0))
-            {
-                this.GetDictionary(list2, this.newDic);
-            }
-            else
-            {
-                this.newDic = this.originDic;
-            }
-            this.LoadData(this.comboBox1, this.originDic);
-            this.LoadData(this.comboBox2, this.newDic);
-        }
-
-        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
-        {
-            TreeViewChecked(e);
-        }
-
-        private void treeView2_AfterCheck(object sender, TreeViewEventArgs e)
-        {
-            TreeViewChecked(e);
-        }
-
-        private static void TreeViewChecked(TreeViewEventArgs e)
-        {
-            if (e.Action != TreeViewAction.Unknown)
-            {
-                if (e.Node.Parent == null)
-                {
-                    foreach (TreeNode node in e.Node.Nodes)
-                    {
-                        node.Checked = e.Node.Checked;
-                    }
-                }
-                else if (!e.Node.Checked)
-                {
-                    e.Node.Parent.Checked = e.Node.Checked;
-                }
-            }
-        }
-    }
-}
-

+ 0 - 26
SAGA.RevitMenu/TSZHideScreenMenuCmd.cs

@@ -1,26 +0,0 @@
-using SAGY.RevitMenu;
-
-namespace TSZ.RevitMenu
-{
-    using Autodesk.Revit.Attributes;
-    using Autodesk.Revit.DB;
-    using Autodesk.Revit.UI;
-    using System;
-    using TSZ.RevitBaseDll.Extends;
-
-    [Regeneration(RegenerationOption.Manual), Transaction(TransactionMode.Manual)]
-    public class TSZHideScreenMenuCmd : ExternalCommand
-    {
-        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
-        {
-            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
-            {
-                return Result.Cancelled;
-            }
-            Globals.HidePanels(commandData);
-            Globals.SaveState(false);
-            return Result.Succeeded;
-        }
-    }
-}
-

+ 0 - 24
SAGA.RevitMenu/TSZShowScreenMenuCmd.cs

@@ -1,24 +0,0 @@
-using Autodesk.Revit.Attributes;
-using Autodesk.Revit.DB;
-using Autodesk.Revit.UI;
-
-namespace SAGY.RevitMenu
-{
-    [Regeneration(RegenerationOption.Manual), Transaction(TransactionMode.Manual)]
-    public class TSZShowScreenMenuCmd : ExternalCommand
-    {
-        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
-        {
-            while (base.Execute(commandData, ref message, elements) == Result.Cancelled)
-            {
-                return Result.Cancelled;
-            }
-            Globals.ExtCmdData = commandData;
-            Globals.ShowPanels(commandData);
-            Globals.SaveState(true);
-            ScreenMenuKeyBoardShortCut.SetKeyboardShortcuts(commandData.Application.Application.VersionName);
-            return Result.Succeeded;
-        }
-    }
-}
-

+ 71 - 0
SAGA.RevitMenu/app.config

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.1.0" newVersion="1.1.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Options.ConfigurationExtensions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Codecs" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Buffers" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Transport" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="DotNetty.Common" publicKeyToken="bc13ca065fa06c29" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.6.0.0" newVersion="0.6.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 50 - 0
SAGA.RevitMenu/packages.config

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.0" targetFramework="net461" />
+  <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
+  <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
+  <package id="System.AppContext" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
+  <package id="System.Console" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Http" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
+  <package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
+</packages>

+ 25 - 0
ServiceMBI.Modes/IServiceCommand.cs

@@ -0,0 +1,25 @@
+
+/* ==============================================================================
+ * 功能描述:服务器执行命令的接口
+ * 创 建 者:SAGACLOUD
+ * 创建日期:2017/9/17 
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServiceMBI.Modes
+{
+    /// <summary>
+    /// IMBICommand
+    /// </summary>
+    public interface IServiceCommand
+    {
+
+        bool Execute(string param, ref string msg);
+
+    }
+}

+ 36 - 0
ServiceMBI.Modes/Properties/AssemblyInfo.cs

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

+ 48 - 0
ServiceMBI.Modes/ServiceMBI.Modes.csproj

@@ -0,0 +1,48 @@
+<?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>{676F1602-6F8A-44C7-BB81-2172D963AC1A}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ServiceMBI.Modes</RootNamespace>
+    <AssemblyName>ServiceMBI.Modes</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\OutputDll\</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.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="IServiceCommand.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ServiceMBIBuiltInParameter.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 38 - 0
ServiceMBI.Modes/ServiceMBIBuiltInParameter.cs

@@ -0,0 +1,38 @@
+/* ==============================================================================
+ * 功能描述:ServiceMBIBuiltInParameter  
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/12 14:09:44
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServiceMBI.Modes
+{
+    /// <summary>
+    /// ServiceMBIBuiltInParameter
+    /// </summary>
+    public class ServiceMBIBuiltInParameter
+    {
+        /// <summary>
+        /// 项目ID
+        /// </summary>
+        public   const string ProjectId = "ProjectId";
+        /// <summary>
+        /// 用户名
+        /// </summary>
+        public const string UserId = "UserId";
+
+        /// <summary>
+        /// 参考楼层
+        /// </summary>
+        public const string ReferFloors = "ReferFloors";
+
+        /// <summary>
+        /// 检查项
+        /// </summary>
+        public const string CheckItems = "CheckItems";
+    }
+}

+ 256 - 0
ServiceMBI.sln

@@ -7,6 +7,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceMBI", "ServiceMBI\Se
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAGA.RevitMenu", "SAGA.RevitMenu\SAGA.RevitMenu.csproj", "{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceMBI.Modes", "ServiceMBI.Modes\ServiceMBI.Modes.csproj", "{676F1602-6F8A-44C7-BB81-2172D963AC1A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAGA.Revit", "SAGA.Revit\SAGA.Revit.csproj", "{26C0661D-086C-4352-84B0-03B5D493EC77}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testDll", "testDll\testDll.csproj", "{146A0BCF-3995-4875-99EF-FCA0B4CFB663}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpDownload", "HttpDownload\HttpDownload.csproj", "{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NettyClient", "NettyClient\NettyClient.csproj", "{7A08D4E8-A171-47BD-A527-BC9BA1833305}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaskDatabase", "TaskDatabase\TaskDatabase.csproj", "{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientTests", "ClientTests\ClientTests.csproj", "{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -86,6 +102,246 @@ Global
 		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x64.Build.0 = RR17|x64
 		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x86.ActiveCfg = RR17|x86
 		{066EC682-BAA8-4CF8-AAE0-F08B962BA1DD}.RR17|x86.Build.0 = RR17|x86
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Debug|x64.Build.0 = Debug|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Debug|x86.Build.0 = Debug|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R17|Any CPU.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R17|x64.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R17|x64.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R17|x86.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R17|x86.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R18|Any CPU.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R18|x64.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R18|x64.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R18|x86.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.R18|x86.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Release|x64.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Release|x64.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Release|x86.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.Release|x86.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.RR17|x64.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.RR17|x64.Build.0 = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.RR17|x86.ActiveCfg = Release|Any CPU
+		{676F1602-6F8A-44C7-BB81-2172D963AC1A}.RR17|x86.Build.0 = Release|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Debug|x64.ActiveCfg = Debug|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Debug|x64.Build.0 = Debug|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Debug|x86.ActiveCfg = Debug|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Debug|x86.Build.0 = Debug|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R17|Any CPU.ActiveCfg = R17|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R17|Any CPU.Build.0 = R17|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R17|x64.ActiveCfg = R17|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R17|x64.Build.0 = R17|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R17|x86.ActiveCfg = R17|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R17|x86.Build.0 = R17|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R18|Any CPU.ActiveCfg = R18|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R18|Any CPU.Build.0 = R18|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R18|x64.ActiveCfg = R18|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R18|x64.Build.0 = R18|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R18|x86.ActiveCfg = R18|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.R18|x86.Build.0 = R18|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Release|Any CPU.Build.0 = Release|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Release|x64.ActiveCfg = Release|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Release|x64.Build.0 = Release|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Release|x86.ActiveCfg = Release|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.Release|x86.Build.0 = Release|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.RR17|Any CPU.ActiveCfg = RR17|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.RR17|Any CPU.Build.0 = RR17|Any CPU
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.RR17|x64.ActiveCfg = RR17|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.RR17|x64.Build.0 = RR17|x64
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.RR17|x86.ActiveCfg = RR17|x86
+		{26C0661D-086C-4352-84B0-03B5D493EC77}.RR17|x86.Build.0 = RR17|x86
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Debug|x64.Build.0 = Debug|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Debug|x86.Build.0 = Debug|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R17|Any CPU.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R17|x64.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R17|x64.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R17|x86.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R17|x86.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R18|Any CPU.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R18|x64.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R18|x64.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R18|x86.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.R18|x86.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Release|Any CPU.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Release|x64.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Release|x64.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Release|x86.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.Release|x86.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.RR17|x64.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.RR17|x64.Build.0 = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.RR17|x86.ActiveCfg = Release|Any CPU
+		{146A0BCF-3995-4875-99EF-FCA0B4CFB663}.RR17|x86.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Debug|x64.Build.0 = Debug|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Debug|x86.Build.0 = Debug|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R17|Any CPU.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R17|x64.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R17|x64.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R17|x86.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R17|x86.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R18|Any CPU.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R18|x64.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R18|x64.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R18|x86.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.R18|x86.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Release|x64.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Release|x64.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Release|x86.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.Release|x86.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.RR17|x64.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.RR17|x64.Build.0 = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.RR17|x86.ActiveCfg = Release|Any CPU
+		{6A52AF44-63C6-4AB6-92D4-2A05173D45FB}.RR17|x86.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Debug|x64.Build.0 = Debug|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Debug|x86.Build.0 = Debug|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R17|Any CPU.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R17|x64.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R17|x64.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R17|x86.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R17|x86.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R18|Any CPU.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R18|x64.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R18|x64.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R18|x86.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.R18|x86.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Release|x64.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Release|x64.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Release|x86.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.Release|x86.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.RR17|x64.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.RR17|x64.Build.0 = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.RR17|x86.ActiveCfg = Release|Any CPU
+		{9F423033-98A9-4B6B-9BB1-F1AA8C648A02}.RR17|x86.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Debug|x64.Build.0 = Debug|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Debug|x86.Build.0 = Debug|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R17|Any CPU.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R17|x64.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R17|x64.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R17|x86.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R17|x86.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R18|Any CPU.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R18|x64.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R18|x64.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R18|x86.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.R18|x86.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Release|x64.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Release|x64.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Release|x86.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.Release|x86.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.RR17|x64.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.RR17|x64.Build.0 = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.RR17|x86.ActiveCfg = Release|Any CPU
+		{7A08D4E8-A171-47BD-A527-BC9BA1833305}.RR17|x86.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Debug|x64.Build.0 = Debug|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Debug|x86.Build.0 = Debug|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R17|Any CPU.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R17|x64.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R17|x64.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R17|x86.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R17|x86.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R18|Any CPU.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R18|x64.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R18|x64.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R18|x86.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.R18|x86.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Release|x64.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Release|x64.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Release|x86.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.Release|x86.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.RR17|x64.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.RR17|x64.Build.0 = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.RR17|x86.ActiveCfg = Release|Any CPU
+		{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}.RR17|x86.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Debug|x64.Build.0 = Debug|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Debug|x86.Build.0 = Debug|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R17|Any CPU.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R17|Any CPU.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R17|x64.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R17|x64.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R17|x86.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R17|x86.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R18|Any CPU.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R18|Any CPU.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R18|x64.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R18|x64.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R18|x86.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.R18|x86.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Release|x64.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Release|x64.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Release|x86.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.Release|x86.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.RR17|Any CPU.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.RR17|Any CPU.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.RR17|x64.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.RR17|x64.Build.0 = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.RR17|x86.ActiveCfg = Release|Any CPU
+		{5EFC2C05-9AF3-4B1A-878A-B6E7599C43FE}.RR17|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 40 - 0
ServiceMBI/Commands/BaseCommandArgs.cs

@@ -0,0 +1,40 @@
+/* ==============================================================================
+ * 功能描述:命令执行需要的参数
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/12 9:02:16
+ * ==============================================================================*/
+
+using System.ComponentModel;
+using ServiceMBI.Modes;
+
+namespace ServiceMBI.Commands
+{
+    /// <summary>
+    /// CommandParam
+    /// </summary>
+    class BaseCommandArgs
+    {
+        private string m_ProjectId;
+        /// <summary>
+        /// 当前项目id
+        /// </summary>
+        [Description(ServiceMBIBuiltInParameter.ProjectId)]
+        public string ProjectId
+        {
+            get { return m_ProjectId; }
+            set { m_ProjectId = value; }
+        }
+
+        private string m_UserId;
+        /// <summary>
+        /// 用户id
+        /// </summary>
+        [Description(ServiceMBIBuiltInParameter.UserId)]
+        public string UserId
+        {
+            get { return m_UserId; }
+            set { m_UserId = value; }
+        }
+
+    }
+}

+ 58 - 0
ServiceMBI/Commands/BaseServiceCommand.cs

@@ -0,0 +1,58 @@
+/* ==============================================================================
+ * 功能描述:MBICommand  
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/12 9:00:39
+ * ==============================================================================*/
+
+using System;
+using SAGA.RevitUtils;
+using ServiceMBI.Modes;
+
+namespace ServiceMBI.Commands
+{
+    /// <summary>
+    /// MBICommand
+    /// </summary>
+    class BaseServiceCommand : IServiceCommand
+    {
+        private BaseCommandArgs m_CommandArgs;
+
+        public  BaseCommandArgs CommandArgs
+        {
+            get { return m_CommandArgs; }
+            set { m_CommandArgs = value; }
+        }
+
+        public virtual bool Execute(string param,ref string msg)
+        {
+            bool result = false;
+            if (!ParseParam(param))
+            {
+                msg = "解析参数失败";
+                return result;
+            }
+
+            result = true;
+            return result;
+        }
+
+        /// <summary>
+        /// 解析参数
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public virtual bool ParseParam(string param)
+        {
+            bool result = false;
+            try
+            {
+                result = true;
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e);
+            }
+            return result;
+        }
+    }
+}

+ 42 - 0
ServiceMBI/Commands/DataCheckCommand.cs

@@ -0,0 +1,42 @@
+/* ==============================================================================
+ * 功能描述:DataCheckCommand  
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/11 16:08:11
+ * ==============================================================================*/
+
+using System;
+using System.Collections.Generic;
+using SAGA.DotNetUtils.Others;
+using SAGA.RevitUtils;
+
+namespace ServiceMBI.Commands
+{
+    /// <summary>
+    /// DataCheckCommand
+    /// </summary>
+    class DataCheckCommand : BaseServiceCommand
+    {
+        public DataCheckCommand()
+        {
+            CommandArgs=new DataCheckCommandArgs();
+        }
+
+        public override bool Execute(string param, ref string msg)
+        {
+            bool result = false;
+            if (base.Execute(param, ref msg))
+            {
+                try
+                {
+                    MessageShowBase.Infomation("DataCommand执行了");
+                }
+                catch (Exception e)
+                {
+
+                }
+            }
+
+            return result;
+        }
+    }
+}

+ 30 - 0
ServiceMBI/Commands/DataCheckCommandArgs.cs

@@ -0,0 +1,30 @@
+/* ==============================================================================
+ * 功能描述:数据检查所需要的参数
+ * 创 建 者:Garrett
+ * 创建日期:2019/4/12 10:13:07
+ * ==============================================================================*/
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ServiceMBI.Modes;
+
+namespace ServiceMBI.Commands
+{
+    /// <summary>
+    /// DataCheckCommandArgs
+    /// </summary>
+    class DataCheckCommandArgs:BaseCommandArgs
+    {
+        private List<string> m_CheckItems;
+        [Description(ServiceMBIBuiltInParameter.CheckItems)]
+        public List<string> CheckItems
+        {
+            get { return m_CheckItems; }
+            set { m_CheckItems = value; }
+        }
+
+    }
+}

+ 1 - 1
ServiceMBI/Command.cs

@@ -21,7 +21,7 @@ namespace ServiceMBI
     /// </summary>
     [Transaction(TransactionMode.Manual)]
     [Regeneration(RegenerationOption.Manual)]
-    public class Command : ExternalCommand
+    public class RevitCommand : ExternalCommand
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {

+ 17 - 1
ServiceMBI/ServiceMBI.csproj

@@ -35,6 +35,9 @@
     <StartupObject />
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="DotNetty.Handlers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Handlers.0.6.0\lib\net45\DotNetty.Handlers.dll</HintPath>
+    </Reference>
     <Reference Include="RevitAPI">
       <HintPath>..\Dlls\RevitRefDll\RevitAPI.dll</HintPath>
     </Reference>
@@ -57,12 +60,25 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Command.cs" />
+    <Compile Include="Commands\DataCheckCommandArgs.cs" />
+    <Compile Include="RevitCommand.cs" />
+    <Compile Include="Commands\BaseCommandArgs.cs" />
+    <Compile Include="Commands\DataCheckCommand.cs" />
+    <Compile Include="Commands\BaseServiceCommand.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ServiceMBI.Modes\ServiceMBI.Modes.csproj">
+      <Project>{676f1602-6f8a-44c7-bb81-2172d963ac1a}</Project>
+      <Name>ServiceMBI.Modes</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="DataCheck\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 44 - 0
TaskDatabase/Mappings/TaskModel.hbm.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+                   assembly="TaskDatabase" default-lazy="false"
+                   namespace="TaskDatabase.Model">
+
+  <!-- more mapping info here -->
+  <class name="TaskModel" table="task" entity-name="TaskModel">
+    <id name="Tid">
+      <!--<generator class="guid" />-->
+      <generator class="native" />
+      <!--  <generator class="native" />主键自增。使用数据库自带的生成器 -->
+    </id>
+    <property name="Id" />
+    <property name="Task_name"/>
+    <property name="Task_cmd" update="false" />
+    <property name="Task_param" update="false"/>
+    <property name="Task_status"/>
+    <property name="Task_result_json" />
+    <property name="Task_expected_finish_time"  update="false"/>
+    <property name="Task_add_time" insert="false" update="false"/>
+    <set name="DownloadTaskModelList">
+      <key column="Task_id" property-ref="Id"/>
+      <one-to-many class="DownloadTaskModel"/>
+    </set>
+  </class>
+
+  <class name="DownloadTaskModel" table="download">
+    <id name="Tid">
+      <!--<generator class="guid" />-->
+      <generator class="native" />
+      <!--  <generator class="native" />主键自增。使用数据库自带的生成器 -->
+    </id>
+    <property name="Id" />
+    <property name="Task_id" >
+      <!--<many-to-one class="DownloadTaskModel" column="Task_Id"/>-->
+    </property>
+    <property name="Task_url" />
+    <property name="Task_md5" />
+    <property name="Local_dir" />
+    <property name="Downloaded_bytes" />
+    <property name="File_bytes" />
+    <property name="Finish_time" />
+  </class>
+</hibernate-mapping>

+ 35 - 0
TaskDatabase/Models/TaskModel.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TaskDatabase.Model
+{
+    public class TaskModel
+    {
+        public virtual int Tid { get; set; }
+        public virtual int Id { get; set; }
+        public virtual string Task_name { get; set; }
+        public virtual string Task_cmd { get; set; }
+        public virtual string Task_param { get; set; }
+        public virtual int Task_status { get; set; }
+        public virtual string Task_result_json { get; set; }
+        public virtual long Task_expected_finish_time { get; set; }
+        public virtual DateTime Task_add_time { get; set; }
+        public virtual ICollection<DownloadTaskModel> DownloadTaskModelList { get; set; }
+    }
+
+    public class DownloadTaskModel
+    {
+        public virtual int Tid { get; set; }
+        public virtual int Id { get; set; }
+        public virtual string Task_id { get; set; }
+        public virtual string Task_url { get; set; }
+        public virtual string Task_md5 { get; set; }
+        public virtual string Local_dir { get; set; }
+        public virtual long Downloaded_bytes { get; set; }
+        public virtual long File_bytes { get; set; }
+        public virtual long Finish_time { get; set; }
+    }
+}

+ 42 - 0
TaskDatabase/NHibernateHelper.cs

@@ -0,0 +1,42 @@
+using NHibernate;
+using NHibernate.Cfg;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TaskDatabase
+{
+    public class NHibernateHelper
+    {
+        private static object lockObj = new object();
+        private static ISessionFactory _sessionFactory;
+
+        private static ISessionFactory SessionFactory
+        {
+            get
+            {
+                if (_sessionFactory == null)
+                {
+                    lock (lockObj)
+                    {
+                        if (_sessionFactory == null)
+                        {
+                            var configuration = new Configuration();
+                            configuration.Configure();
+                            //configuration.AddAssembly(typeof(TaskModel).Assembly);
+                            _sessionFactory = configuration.BuildSessionFactory();
+                        }
+                    }
+                }
+                return _sessionFactory;
+            }
+        }
+
+        public static ISession OpenSession()
+        {
+            return SessionFactory.OpenSession();
+        }
+    }
+}

+ 36 - 0
TaskDatabase/Properties/AssemblyInfo.cs

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

+ 93 - 0
TaskDatabase/TaskDatabase.csproj

@@ -0,0 +1,93 @@
+<?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>{ADE36AA5-FCA8-4E5B-A27E-2360884404B3}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>TaskDatabase</RootNamespace>
+    <AssemblyName>TaskDatabase</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Antlr3.Runtime, Version=3.5.0.2, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
+      <HintPath>..\packages\Antlr3.Runtime.3.5.1\lib\net40-client\Antlr3.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.5.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="Iesi.Collections, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
+      <HintPath>..\packages\Iesi.Collections.4.0.4\lib\net461\Iesi.Collections.dll</HintPath>
+    </Reference>
+    <Reference Include="MySql.Data, Version=8.0.15.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
+      <HintPath>..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll</HintPath>
+    </Reference>
+    <Reference Include="NHibernate, Version=5.2.0.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
+      <HintPath>..\packages\NHibernate.5.2.4\lib\net461\NHibernate.dll</HintPath>
+    </Reference>
+    <Reference Include="Remotion.Linq, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Remotion.Linq.2.2.0\lib\net45\Remotion.Linq.dll</HintPath>
+    </Reference>
+    <Reference Include="Remotion.Linq.EagerFetching, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Remotion.Linq.EagerFetching.2.2.0\lib\net45\Remotion.Linq.EagerFetching.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Configuration.Install" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Drawing.Design" />
+    <Reference Include="System.Management" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Transactions" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="NHibernateHelper.cs" />
+    <Compile Include="Models\TaskModel.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TaskService.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Mappings\TaskModel.hbm.xml">
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="hibernate.cfg.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 209 - 0
TaskDatabase/TaskService.cs

@@ -0,0 +1,209 @@
+using NHibernate;
+using NHibernate.Criterion;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TaskDatabase.Model;
+
+namespace TaskDatabase
+{
+    public class TaskService
+    {
+        public bool AddTask(TaskModel task) {
+            ITransaction transaction = null;
+            try
+            {
+                //如果存在该任务, 则不允许添加
+                if (isContainsTask(task.Id))
+                {
+                    return false;
+                }
+                using (ISession session = NHibernateHelper.OpenSession()) {
+                    using (transaction = session.BeginTransaction()) {
+                        try
+                        {
+                            session.Save(task);
+                            if(task.DownloadTaskModelList != null)
+                            {
+                                foreach(var download in task.DownloadTaskModelList)
+                                {
+                                    session.Save(download);
+                                }
+                            }
+                            transaction.Commit();
+                        }
+                        catch {
+                            if (transaction != null && transaction.IsActive)
+                            {
+                                transaction.Rollback();
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+            catch {}
+            return false;
+        }
+
+        public bool UpdateTask(TaskModel task)
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        session.Update(task);
+                        transaction.Commit();
+                    }
+                }
+                return true;
+            }
+            catch { }
+            return false;
+        }
+        public bool UpdateDownload(DownloadTaskModel download)
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        session.Update(download);
+                        transaction.Commit();
+                    }
+                }
+                return true;
+            }
+            catch { }
+            return false;
+        }
+        public IList<TaskModel> GetTasksByStatus(int status)
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        var queryResult = session.CreateCriteria(typeof(TaskModel))
+                                .Add(Restrictions.Eq("Task_status", status))
+                                .List<TaskModel>();
+                        return queryResult;
+                    }
+                }
+            }
+            catch (Exception ex){
+                
+                Console.WriteLine(ex.Message);
+            }
+            return null;
+        }
+
+        public TaskModel GetTasksByTid(int tid)
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        var queryResult = session.CreateCriteria(typeof(TaskModel))
+                                .Add(Restrictions.Eq("Tid", tid))
+                                .UniqueResult<TaskModel>();
+                        return queryResult;
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+
+                Console.WriteLine(ex.Message);
+            }
+            return null;
+        }
+
+        public IList<TaskModel> GetTasksByTaskId(int taskId)
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        var queryResult = session.CreateCriteria(typeof(TaskModel))
+                                .Add(Restrictions.Eq("Id", taskId))
+                                .List<TaskModel>();
+                        return queryResult;
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message);
+            }
+            return null;
+        }
+
+        public bool isContainsTask(int taskId)
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        var queryResult = session.CreateCriteria(typeof(TaskModel))
+                                .Add(Restrictions.Eq("Id", taskId))
+                                .List<TaskModel>();
+                        return queryResult.Count > 0;
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message);
+            }
+            return true;
+        }
+
+        public void removeErrorTask()
+        {
+            ITransaction transaction = null;
+            try
+            {
+                using (ISession session = NHibernateHelper.OpenSession())
+                {
+                    using (transaction = session.BeginTransaction())
+                    {
+                        var queryResult = session.CreateCriteria(typeof(TaskModel))
+                                .Add(Restrictions.Le("Task_status", -1))
+                                .List<TaskModel>();
+                        for (int i = 0; i < queryResult.Count; ++i) {
+                            ICollection<DownloadTaskModel> downloadTaskModels = queryResult[i].DownloadTaskModelList;
+                            for (int j = 0; j < downloadTaskModels.Count; ++j) {
+                                session.Delete(downloadTaskModels.ElementAt(j));
+                            }
+                            session.Delete(queryResult[i]);
+                        }
+                        transaction.Commit();
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message);
+            }
+        }
+    }
+}

+ 11 - 0
TaskDatabase/hibernate.cfg.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
+  <session-factory>
+    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
+    <property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
+    <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
+    <property name="connection.connection_string">Server=localhost;Database=worker;User ID=root;Password=123456</property>
+    <property name="show_sql">false</property>
+    <mapping assembly="TaskDatabase"/>
+  </session-factory>
+</hibernate-configuration>

+ 10 - 0
TaskDatabase/packages.config

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Antlr3.Runtime" version="3.5.1" targetFramework="net461" />
+  <package id="Google.Protobuf" version="3.5.1" targetFramework="net461" />
+  <package id="Iesi.Collections" version="4.0.4" targetFramework="net461" />
+  <package id="MySql.Data" version="8.0.15" targetFramework="net461" />
+  <package id="NHibernate" version="5.2.4" targetFramework="net461" />
+  <package id="Remotion.Linq" version="2.2.0" targetFramework="net461" />
+  <package id="Remotion.Linq.EagerFetching" version="2.2.0" targetFramework="net461" />
+</packages>

+ 30 - 0
testDll/Class1.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using NettyClient;
+
+namespace testDll
+{
+    public class Class1
+    {
+        public static void Show()
+        {
+            MessageBox.Show("start");
+            try
+            {
+                TaskNettyClient client = new TaskNettyClient("172.16.0.183", 6666);
+                client.RunClientAsync(new SimpleMessageHandler()).Wait();
+            }
+            catch (Exception ex)
+            {
+
+                MessageBox.Show(ex.Message);
+            }
+
+            MessageBox.Show("end");
+        }
+    }
+}

+ 36 - 0
testDll/Properties/AssemblyInfo.cs

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

+ 61 - 0
testDll/SimpleMessageHandler.cs

@@ -0,0 +1,61 @@
+using DotNetty.Transport.Channels;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace NettyClient
+{
+    public class SimpleMessageHandler : ChannelHandlerAdapter
+    {
+        public SimpleMessageHandler() {
+        }
+        public IChannelHandlerContext context;
+        public override void ChannelActive(IChannelHandlerContext context)
+        {
+            MessageBox.Show("connected"); 
+            this.context = context;
+        }
+        public override void ChannelRead(IChannelHandlerContext context, object message)
+        {
+            
+        }
+
+        public override void ChannelReadComplete(IChannelHandlerContext context)
+        {
+            context.Flush();
+        }
+
+        public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
+        {
+            Console.WriteLine("Exception: " + exception);
+            context.CloseAsync();
+        }
+        //public override void ChannelInactive(IChannelHandlerContext context)
+        //{
+        //    base.ChannelInactive(context);
+        //    Console.WriteLine("1");
+        //}
+
+        //public override void ChannelUnregistered(IChannelHandlerContext context)
+        //{
+        //    base.ChannelUnregistered(context);
+        //    Console.WriteLine("2");
+        //}
+
+        public override void HandlerRemoved(IChannelHandlerContext context)
+        {
+            base.HandlerRemoved(context);
+        }
+
+
+
+        //public void toString(Message msg)
+        //{
+        //    MessageBox.Show("Received from server: cmd : " + msg.Cmd + ", taskId : " + msg.TaskId + ", content : " + msg.Content);
+        //}
+    }
+}

+ 109 - 0
testDll/TaskNettyClient.cs

@@ -0,0 +1,109 @@
+using DotNetty.Codecs.Protobuf;
+using DotNetty.Common.Internal.Logging;
+using DotNetty.Transport.Bootstrapping;
+using DotNetty.Transport.Channels;
+using DotNetty.Transport.Channels.Sockets;
+//using Microsoft.Extensions.Configuration;
+//using Microsoft.Extensions.Logging.Console;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace NettyClient
+{
+    public class TaskNettyClient
+    {
+        private string ip;
+        private int port;
+        IChannel clientChannel;
+        MultithreadEventLoopGroup group;
+        Bootstrap bootstrap;
+        public TaskNettyClient(string ip, int port)
+        {
+            this.ip = ip;
+            this.port = port;
+        }
+        public async Task RunClientAsync(ChannelHandlerAdapter channelHandler)
+        {
+            group = new MultithreadEventLoopGroup();
+            try
+            {
+                bootstrap = new Bootstrap();
+                bootstrap
+                    .Group(group)
+                    .Channel<TcpSocketChannel>()
+                    .Option(ChannelOption.TcpNodelay, true)
+                    .Handler(
+                        new ActionChannelInitializer<ISocketChannel>(
+                            channel =>
+                            {
+                                IChannelPipeline pipeline = channel.Pipeline;
+                                pipeline.AddLast(new ProtobufVarint32LengthFieldPrepender());
+                                //pipeline.AddLast("encoder", new ProtobufEncoder());
+                                pipeline.AddLast(new ProtobufVarint32FrameDecoder());
+                                //pipeline.AddLast("decoder", new ProtobufDecoder(Message.Parser));
+                                pipeline.AddLast("simple", channelHandler);
+
+                            }));
+                clientChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(ip), port));
+                //await clientChannel.CloseAsync();
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show(ex.Message+"\r\n"+ ex.StackTrace+$"ip:{ip};port{port}");
+            }
+            finally
+            {
+                //await Task.WhenAll(group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
+            }
+        }
+        public async Task CloseAsync() {
+            try
+            {
+                await clientChannel.CloseAsync();
+            }
+            catch { }
+            finally {
+                await Task.WhenAll(group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
+            }
+        }
+        public static void Main(string[] args)
+        {
+            TaskNettyClient client = new TaskNettyClient("127.0.0.1", 6666);
+            SimpleMessageHandler simpleHandler = new SimpleMessageHandler();
+            client.RunClientAsync(simpleHandler).Wait();
+            while (true) {
+                Thread.Sleep(15000);
+                client.CloseAsync().Wait();
+                // 重启
+                //client.RunClientAsync(new SimpleHandler()).Wait();
+            }
+        }
+    }
+
+    public static class NettyHelper
+    {
+        //static NettyHelper()
+        //{
+        //    Configuration = new ConfigurationBuilder()
+        //    //    .SetBasePath(ProcessDirectory)
+        //    //    .AddJsonFile("appsettings.json")
+        //        .Build();
+        //}
+        
+        //public static IConfigurationRoot Configuration { get; }
+
+        //public static void SetConsoleLogger() => InternalLoggerFactory.DefaultFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, false));
+        //public static void SetConsoleLogger()
+        //{
+        //    InternalLoggerFactory.DefaultFactory.AddProvider(
+        //        new ConsoleLoggerProvider((s, level) => { level = Microsoft.Extensions.Logging.LogLevel.Error; return true; }, false)
+        //    );
+        //}
+    }
+}

+ 19 - 0
testDll/app.config

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 67 - 0
testDll/packages.config

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="DotNetty.Buffers" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Codecs" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Common" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Handlers" version="0.6.0" targetFramework="net461" />
+  <package id="DotNetty.Transport" version="0.6.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Configuration.Abstractions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="1.1.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Logging" version="1.1.1" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Logging.Abstractions" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.Extensions.Primitives" version="2.2.0" targetFramework="net461" />
+  <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
+  <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
+  <package id="System.AppContext" version="4.3.0" targetFramework="net461" />
+  <package id="System.Buffers" version="4.4.0" targetFramework="net461" />
+  <package id="System.Collections" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
+  <package id="System.Collections.Immutable" version="1.5.0" targetFramework="net461" />
+  <package id="System.ComponentModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.Console" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
+  <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization" version="4.3.0" targetFramework="net461" />
+  <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
+  <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq" version="4.3.0" targetFramework="net461" />
+  <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Memory" version="4.5.1" targetFramework="net461" />
+  <package id="System.Net.Http" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
+  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net461" />
+  <package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net461" />
+  <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
+  <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
+  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
+  <package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net461" />
+  <package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
+  <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
+</packages>

+ 162 - 0
testDll/testDll.csproj

@@ -0,0 +1,162 @@
+<?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>{146A0BCF-3995-4875-99EF-FCA0B4CFB663}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>testDll</RootNamespace>
+    <AssemblyName>testDll</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\OutputDll\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="DotNetty.Buffers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Buffers.0.6.0\lib\net45\DotNetty.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Codecs, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Codecs.0.6.0\lib\net45\DotNetty.Codecs.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Common, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Common.0.6.0\lib\net45\DotNetty.Common.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Handlers, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Handlers.0.6.0\lib\net45\DotNetty.Handlers.dll</HintPath>
+    </Reference>
+    <Reference Include="DotNetty.Transport, Version=0.6.0.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+      <HintPath>..\packages\DotNetty.Transport.0.6.0\lib\net45\DotNetty.Transport.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Extensions.Primitives, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Extensions.Primitives.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.IO.Compression.FileSystem" />
+    <Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
+    </Reference>
+    <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.ReaderWriter">
+      <HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Class1.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SimpleMessageHandler.cs" />
+    <Compile Include="TaskNettyClient.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>