diff --git a/JiShe.CollectBus.Common/Class1.cs b/JiShe.CollectBus.Common/Class1.cs
new file mode 100644
index 0000000..deff6f7
--- /dev/null
+++ b/JiShe.CollectBus.Common/Class1.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace JiShe.CollectBus.Common
+{
+ public class Class1
+ {
+
+ }
+}
diff --git a/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj b/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj
new file mode 100644
index 0000000..b4b43f4
--- /dev/null
+++ b/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netstandard2.1
+ enable
+
+
+
diff --git a/JiShe.CollectBus.Console/Extensions/ServiceCollections/ServiceCollectionExtensions.cs b/JiShe.CollectBus.Console/Extensions/ServiceCollections/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..4d4b82f
--- /dev/null
+++ b/JiShe.CollectBus.Console/Extensions/ServiceCollections/ServiceCollectionExtensions.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JiShe.CollectBus.Core.Plugins;
+using JiShe.CollectBus.Core.Services;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class ServiceCollectionExtensions
+ {
+ ///
+ /// 添加TcpService服务。
+ ///
+ public static IServiceCollection AddTcp(this IServiceCollection services)
+ {
+ services.AddTcpService(config =>
+ {
+ config.SetListenIPHosts(10500)
+ .ConfigureContainer(a => //容器的配置顺序应该在最前面
+ {
+ a.AddConsoleLogger(); //添加一个控制台日志注入(注意:在maui中控制台日志不可用)
+ })
+ .ConfigurePlugins(a =>
+ {
+ a.UseCheckClear()
+ .SetCheckClearType(CheckClearType.All)
+ .SetTick(TimeSpan.FromSeconds(60))
+ .SetOnClose((c, t) =>
+ {
+ c.TryShutdown();
+ c.SafeClose("超时无数据");
+ });
+ a.Add();
+ a.Add();
+ a.Add();
+ });
+ });
+ return services;
+ }
+
+
+ ///
+ /// 添加UdpService服务。
+ ///
+ public static IServiceCollection AddUdp(this IServiceCollection services)
+ {
+ services.AddUdpSession(config =>
+ {
+ config.SetBindIPHost(10500)
+ .ConfigureContainer(a => //容器的配置顺序应该在最前面
+ {
+ a.AddConsoleLogger(); //添加一个控制台日志注入(注意:在maui中控制台日志不可用)
+ })
+ .ConfigurePlugins(a =>
+ {
+ a.Add();
+ a.Add();
+ })
+ .UseBroadcast()
+ .SetUdpDataHandlingAdapter(() => new NormalUdpDataHandlingAdapter());
+ });
+ return services;
+ }
+ }
+}
diff --git a/JiShe.CollectBus.Console/JiShe.CollectBus.Console.csproj b/JiShe.CollectBus.Console/JiShe.CollectBus.Console.csproj
new file mode 100644
index 0000000..d5101fa
--- /dev/null
+++ b/JiShe.CollectBus.Console/JiShe.CollectBus.Console.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/JiShe.CollectBus.Console/Program.cs b/JiShe.CollectBus.Console/Program.cs
new file mode 100644
index 0000000..de1bb00
--- /dev/null
+++ b/JiShe.CollectBus.Console/Program.cs
@@ -0,0 +1,44 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace JiShe.CollectBus.Console
+{
+ internal class Program
+ {
+
+ static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureAppConfiguration(ConfigureAppConfiguration)
+ .ConfigureServices((hostContext, services) => { ConfigureServices(services, hostContext); });
+
+
+ private static void ConfigureAppConfiguration(HostBuilderContext hostContext, IConfigurationBuilder config)
+ {
+ var env = hostContext.HostingEnvironment;
+ config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
+ config.AddEnvironmentVariables();
+ }
+
+
+ private static void ConfigureServices(IServiceCollection services, HostBuilderContext hostContext)
+ {
+ var configuration = hostContext.Configuration;
+
+ services.AddTcp();
+ services.AddUdp();
+
+ services.AddStackExchangeRedisCache(options =>
+ {
+ options.Configuration = configuration["RedisCache:ConnectionString"];
+ options.InstanceName = configuration["RedisCache:InstanceName"];
+ });
+ }
+ }
+}
+
diff --git a/JiShe.CollectBus.Console/appsettings.json b/JiShe.CollectBus.Console/appsettings.json
new file mode 100644
index 0000000..d41b49f
--- /dev/null
+++ b/JiShe.CollectBus.Console/appsettings.json
@@ -0,0 +1,6 @@
+{
+ "RedisCache": {
+ "ConnectionString": "123456@qwer@localhost:6379",
+ "InstanceName": "CollectBus"
+ }
+}
\ No newline at end of file
diff --git a/JiShe.CollectBus.Core/Exceptions/CloseException.cs b/JiShe.CollectBus.Core/Exceptions/CloseException.cs
new file mode 100644
index 0000000..e1f6260
--- /dev/null
+++ b/JiShe.CollectBus.Core/Exceptions/CloseException.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.Core.Exceptions
+{
+ public class CloseException(string msg) : Exception(msg);
+}
diff --git a/JiShe.CollectBus.Core/JiShe.CollectBus.Core.csproj b/JiShe.CollectBus.Core/JiShe.CollectBus.Core.csproj
new file mode 100644
index 0000000..b791d87
--- /dev/null
+++ b/JiShe.CollectBus.Core/JiShe.CollectBus.Core.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/JiShe.CollectBus.Core/Plugins/ClosePlugin.cs b/JiShe.CollectBus.Core/Plugins/ClosePlugin.cs
new file mode 100644
index 0000000..cc613e5
--- /dev/null
+++ b/JiShe.CollectBus.Core/Plugins/ClosePlugin.cs
@@ -0,0 +1,37 @@
+using JiShe.CollectBus.Core.Exceptions;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+
+namespace JiShe.CollectBus.Core.Plugins
+{
+ public class TcpClosePlugin(ILog logger) : PluginBase, ITcpReceivedPlugin
+ {
+ public async Task OnTcpReceived(ITcpSession client, ReceivedDataEventArgs e)
+ {
+ try
+ {
+ await e.InvokeNext();
+ }
+ catch (CloseException ex)
+ {
+ logger.Info("拦截到CloseException");
+ client.Close(ex.Message);
+ }
+ catch (Exception exx)
+ {
+ // ignored
+ }
+ finally
+ {
+ }
+ }
+ }
+
+ public class UdpClosePlugin(ILog logger) : PluginBase, IUdpReceivedPlugin
+ {
+ public async Task OnUdpReceived(IUdpSessionBase client, UdpReceivedDataEventArgs e)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs b/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs
new file mode 100644
index 0000000..6083990
--- /dev/null
+++ b/JiShe.CollectBus.Core/Plugins/TcpServiceReceivedPlugin.cs
@@ -0,0 +1,72 @@
+using JiShe.CollectBus.Core.Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+
+namespace JiShe.CollectBus.Core.Plugins
+{
+ public class TcpServiceReceivedPlugin : PluginBase, ITcpReceivedPlugin, ITcpConnectingPlugin, ITcpConnectedPlugin, ITcpClosedPlugin
+ {
+ public async Task OnTcpReceived(ITcpSession client, ReceivedDataEventArgs e)
+ {
+ //TODO:根据指令区别是376还是645协议
+
+ var protocolType = "";
+ switch (protocolType)
+ {
+ case "376":
+ //todo:登录拿到设备信息,根据设备信息使用不同的协议解析服务
+
+ break;
+ case "645":
+ //todo: 直接拿设备信息,根据设备信息使用不同的协议解析服务
+ break;
+ default:
+ break;
+ }
+
+
+ //从客户端收到信息
+ var messageHexString = Convert.ToHexString(e.ByteBlock.Span);
+ client.Logger.Info($"[TCP] 已从{client.GetIPPort()}接收到信息:{messageHexString}");
+
+
+ await e.InvokeNext();
+ }
+
+ public async Task OnTcpConnecting(ITcpSession client, ConnectingEventArgs e)
+ {
+ if (client is ITcpSessionClient sessionClient)
+ {
+ client.Logger.Info($"[TCP] ID:{sessionClient.Id} IP:{client.GetIPPort()}正在连接中...");
+ }
+
+ await e.InvokeNext();
+
+ }
+
+ public async Task OnTcpConnected(ITcpSession client, ConnectedEventArgs e)
+ {
+ if (client is ITcpSessionClient sessionClient)
+ {
+ client.Logger.Info($"[TCP] ID:{sessionClient.Id} IP:{client.GetIPPort()}已连接");
+ }
+
+ await e.InvokeNext();
+ }
+
+ public async Task OnTcpClosed(ITcpSession client, ClosedEventArgs e)
+ {
+ if (client is ITcpSessionClient sessionClient)
+ {
+ client.Logger.Info($"[TCP] ID:{sessionClient.Id} IP:{client.GetIPPort()}已关闭连接");
+
+ }
+ await e.InvokeNext();
+ }
+ }
+}
diff --git a/JiShe.CollectBus.Core/Plugins/UdpServiceReceivedPlugin.cs b/JiShe.CollectBus.Core/Plugins/UdpServiceReceivedPlugin.cs
new file mode 100644
index 0000000..3f1ddfa
--- /dev/null
+++ b/JiShe.CollectBus.Core/Plugins/UdpServiceReceivedPlugin.cs
@@ -0,0 +1,19 @@
+using System.Text;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+
+namespace JiShe.CollectBus.Core.Plugins
+{
+ public class UdpServiceReceivedPlugin : PluginBase, IUdpReceivedPlugin
+ {
+ public async Task OnUdpReceived(IUdpSessionBase client, UdpReceivedDataEventArgs e)
+ {
+
+ var udpSession = client as UdpSession;
+ udpSession?.Logger.Info($"[TCP] 收到:{e.ByteBlock.Span.ToString(Encoding.UTF8)}");
+ await udpSession.SendAsync("[TCP] 收到");
+
+ await e.InvokeNext();
+ }
+ }
+}
diff --git a/JiShe.CollectBus.Core/Services/BusService.cs b/JiShe.CollectBus.Core/Services/BusService.cs
new file mode 100644
index 0000000..ef306f5
--- /dev/null
+++ b/JiShe.CollectBus.Core/Services/BusService.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TouchSocket.Core;
+using TouchSocket.Sockets;
+
+namespace JiShe.CollectBus.Core.Services
+{
+ public class BusService : PluginBase, IServerStartedPlugin, IServerStopedPlugin
+ {
+ public Task OnServerStarted(IServiceBase sender, ServiceStateEventArgs e)
+ {
+ switch (sender)
+ {
+ case ITcpService service:
+ {
+ foreach (var item in service.Monitors)
+ {
+ ConsoleLogger.Default.Info($"TCP {item.Option.IpHost}");
+ }
+
+ break;
+ }
+ case UdpSession session:
+ ConsoleLogger.Default.Info($"UDP {session.Monitor.IPHost}");
+ break;
+ }
+
+ ConsoleLogger.Default.Info(e.ServerState == ServerState.Running
+ ? $"服务器成功启动"
+ : $"服务器启动失败,状态:{e.ServerState},异常:{e.Exception}");
+ return e.InvokeNext();
+ }
+
+ public Task OnServerStoped(IServiceBase sender, ServiceStateEventArgs e)
+ {
+ Console.WriteLine("服务已停止");
+ return e.InvokeNext();
+ }
+ }
+}
diff --git a/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs b/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs
new file mode 100644
index 0000000..2ccdb53
--- /dev/null
+++ b/JiShe.CollectBus.Protocol.Contracts/Abstracts/BaseProtocolPlugin.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using JiShe.CollectBus.Protocol.Contracts.Interfaces;
+using Microsoft.Extensions.Caching.Distributed;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
+{
+ public abstract class BaseProtocolPlugin:IProtocolPlugin
+ {
+ private readonly IDistributedCache _cache;
+
+ protected BaseProtocolPlugin(IDistributedCache cache)
+ {
+ _cache = cache;
+ }
+
+ public abstract Models.Protocol Get();
+
+ public abstract void Received();
+
+ public abstract void Send();
+
+ public void Load()
+ {
+ var result = _cache.GetString("myKey");
+ if (result == null)
+ {
+ result = "Calculated Data";
+ _cache.SetString("myKey", result, new DistributedCacheEntryOptions
+ {
+ AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
+ });
+ }
+ }
+
+ }
+}
diff --git a/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs b/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs
new file mode 100644
index 0000000..fe54005
--- /dev/null
+++ b/JiShe.CollectBus.Protocol.Contracts/Interfaces/IProtocolPlugin.cs
@@ -0,0 +1,15 @@
+using JiShe.CollectBus.Protocol.Contracts.Models;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Interfaces
+{
+ public interface IProtocolPlugin
+ {
+ Models.Protocol Get();
+
+ void Load();
+
+ void Received();
+
+ void Send();
+ }
+}
diff --git a/JiShe.CollectBus.Protocol.Contracts/JiShe.CollectBus.Protocol.Contracts.csproj b/JiShe.CollectBus.Protocol.Contracts/JiShe.CollectBus.Protocol.Contracts.csproj
new file mode 100644
index 0000000..8be6c70
--- /dev/null
+++ b/JiShe.CollectBus.Protocol.Contracts/JiShe.CollectBus.Protocol.Contracts.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard2.1
+ enable
+
+
+
+
+
+
+
diff --git a/JiShe.CollectBus.Protocol.Contracts/Models/IProtocol.cs b/JiShe.CollectBus.Protocol.Contracts/Models/IProtocol.cs
new file mode 100644
index 0000000..ba7ac3e
--- /dev/null
+++ b/JiShe.CollectBus.Protocol.Contracts/Models/IProtocol.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Models
+{
+ public interface IProtocol
+ {
+ ///
+ /// 协议名称
+ ///
+ string Name { get; set; }
+
+ ///
+ /// 基础协议 376.1/645
+ ///
+ string BaseProtocol { get; set; }
+
+ ///
+ /// 协议类型 TCP/UDP
+ ///
+ string Type { get; set; }
+
+ ///
+ /// 协议备注
+ ///
+ string Description { get; set; }
+
+ ///
+ /// 型号正则匹配
+ ///
+ string RegularExpression { get; set; }
+ }
+}
diff --git a/JiShe.CollectBus.Protocol.Contracts/Models/Protocol.cs b/JiShe.CollectBus.Protocol.Contracts/Models/Protocol.cs
new file mode 100644
index 0000000..0abc809
--- /dev/null
+++ b/JiShe.CollectBus.Protocol.Contracts/Models/Protocol.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Models
+{
+ public class Protocol:IProtocol
+ {
+ public Protocol(string name, string baseProtocol, string type, string description, string regularExpression)
+ {
+ Name = name;
+ Type = type;
+ Description = description;
+ RegularExpression = regularExpression;
+ BaseProtocol = baseProtocol;
+ }
+
+ ///
+ /// 协议名称
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// 基础协议 376.1/645
+ ///
+ public string BaseProtocol { get; set; }
+
+ ///
+ /// 协议类型 TCP/UDP
+ ///
+ public string Type { get; set; }
+
+ ///
+ /// 协议备注
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// 型号正则匹配
+ ///
+ public string RegularExpression { get; set; }
+ }
+}
diff --git a/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin.cs b/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin.cs
new file mode 100644
index 0000000..aec53c7
--- /dev/null
+++ b/JiShe.CollectBus.Protocol/Abstracts/BaseProtocolPlugin.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using JiShe.CollectBus.Protocol.Contracts.Interfaces;
+
+namespace JiShe.CollectBus.Protocol.Contracts.Abstracts
+{
+ public abstract class BaseProtocolPlugin:IProtocolPlugin
+ {
+ public abstract Models.Protocol Get();
+
+ public abstract void Received();
+
+ public abstract void Send();
+
+ public void Load()
+ {
+
+ }
+
+ }
+}
diff --git a/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj b/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj
new file mode 100644
index 0000000..8fdf043
--- /dev/null
+++ b/JiShe.CollectBus.Protocol/JiShe.CollectBus.Protocol.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs b/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
new file mode 100644
index 0000000..bf25b61
--- /dev/null
+++ b/JiShe.CollectBus.Protocol/StandardProtocolPlugin.cs
@@ -0,0 +1,27 @@
+using JiShe.CollectBus.Protocol.Contracts.Interfaces;
+
+namespace JiShe.CollectBus.Protocol
+{
+ public class StandardProtocolPlugin:IProtocolPlugin
+ {
+ public Contracts.Models.Protocol Get()
+ {
+ return new Contracts.Models.Protocol("Standard", "376.1", "TCP","376.1协议","DTS1980");
+ }
+
+ public void Load()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Received()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Send()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/JiShe.CollectBus.sln b/JiShe.CollectBus.sln
new file mode 100644
index 0000000..2073a2d
--- /dev/null
+++ b/JiShe.CollectBus.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34728.123
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Core", "JiShe.CollectBus.Core\JiShe.CollectBus.Core.csproj", "{F1360C93-5B6B-4E65-9D81-1DA38740F32D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Console", "JiShe.CollectBus.Console\JiShe.CollectBus.Console.csproj", "{40C4F834-3080-451B-9510-6FE7BC4F801F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol", "JiShe.CollectBus.Protocol\JiShe.CollectBus.Protocol.csproj", "{B2C476F1-AE32-419D-BDA2-291FCE639CF6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Protocol.Contracts", "JiShe.CollectBus.Protocol.Contracts\JiShe.CollectBus.Protocol.Contracts.csproj", "{4468B52D-3AAE-4918-B4D6-E6E8F000825D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.Common", "JiShe.CollectBus.Common\JiShe.CollectBus.Common.csproj", "{1D3A5A4E-B977-4E33-A1AF-62508110C3B7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F1360C93-5B6B-4E65-9D81-1DA38740F32D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1360C93-5B6B-4E65-9D81-1DA38740F32D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1360C93-5B6B-4E65-9D81-1DA38740F32D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1360C93-5B6B-4E65-9D81-1DA38740F32D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40C4F834-3080-451B-9510-6FE7BC4F801F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40C4F834-3080-451B-9510-6FE7BC4F801F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40C4F834-3080-451B-9510-6FE7BC4F801F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40C4F834-3080-451B-9510-6FE7BC4F801F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2C476F1-AE32-419D-BDA2-291FCE639CF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2C476F1-AE32-419D-BDA2-291FCE639CF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2C476F1-AE32-419D-BDA2-291FCE639CF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2C476F1-AE32-419D-BDA2-291FCE639CF6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4468B52D-3AAE-4918-B4D6-E6E8F000825D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4468B52D-3AAE-4918-B4D6-E6E8F000825D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4468B52D-3AAE-4918-B4D6-E6E8F000825D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4468B52D-3AAE-4918-B4D6-E6E8F000825D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D3A5A4E-B977-4E33-A1AF-62508110C3B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D3A5A4E-B977-4E33-A1AF-62508110C3B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D3A5A4E-B977-4E33-A1AF-62508110C3B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D3A5A4E-B977-4E33-A1AF-62508110C3B7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {33261859-9CD1-4A43-B181-AB75C247D1CD}
+ EndGlobalSection
+EndGlobal