@@ -7,13 +7,14 @@ | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="BPA.Communication" Version="1.0.8" /> | |||
<PackageReference Include="BPA.Communication" Version="1.0.9" /> | |||
<PackageReference Include="BPA.Helper" Version="1.0.6" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmart.Model\BPASmart.Model.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.Message\BPASmartClient.Message.csproj" /> | |||
<ProjectReference Include="..\Communication\Communication.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -2,6 +2,7 @@ | |||
using BPA.Helper; | |||
using BPA.Communication; | |||
using Microsoft.EntityFrameworkCore.Metadata.Conventions; | |||
using Communication; | |||
namespace BPASmart.Server | |||
{ | |||
@@ -10,21 +11,17 @@ namespace BPASmart.Server | |||
public void Init() | |||
{ | |||
BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化"); | |||
RedisHelper.GetInstance.Connect(); | |||
Json<CommunicationPar>.Data.CommunicationDevices.ToList()?.ForEach(item => | |||
{ | |||
#region 数据加载测试 | |||
#endregion | |||
ThreadManage.GetInstance().Start(new Action(() => | |||
{ | |||
switch (item.CommDevice) | |||
{ | |||
case ModbusRtu _modbusRtu: | |||
case BPASmart.Model.ModbusRtu _modbusRtu: | |||
break; | |||
case ModbusTcp _modbusTcp: | |||
ModbusTcpMaster modbusTcpMaster = new ModbusTcpMaster(); | |||
case BPASmart.Model.ModbusTcp _modbusTcp: | |||
BPA.Communication.ModbusTcp modbusTcpMaster = new BPA.Communication.ModbusTcp(); | |||
modbusTcpMaster.ConnectOk = new Action(() => | |||
{ | |||
ThreadManage.GetInstance().StartLong(new Action(() => | |||
@@ -77,9 +74,9 @@ namespace BPASmart.Server | |||
var DeviceModel = item; | |||
}); | |||
modbusTcpMaster.IsReconnect = true; | |||
modbusTcpMaster.ModbusTcpConnect(DeviceType.kinco_PLC, _modbusTcp.IP, _modbusTcp.PortNum); | |||
modbusTcpMaster.ModbusTcpConnect(_modbusTcp.IP, _modbusTcp.PortNum); | |||
break; | |||
case Siemens _siemens: | |||
case BPASmart.Model.Siemens _siemens: | |||
break; | |||
default: | |||
break; | |||
@@ -104,6 +101,10 @@ namespace BPASmart.Server | |||
int varIndex = Array.FindIndex(tempArray, p => p.RealAddress == readDataModel.StartAddress + (i * by)); | |||
if (varIndex >= 0 && varIndex < tempArray.Length) | |||
{ | |||
var Devicename = Json<CommunicationPar>.Data.CommunicationDevices[index].DeviceName; | |||
var varname = Json<CommunicationPar>.Data.CommunicationDevices[index].VarTableModels[varIndex].VarName; | |||
RedisHelper.GetInstance.SetValue($"{Devicename}.{varname}", arrays[i]); | |||
Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); | |||
} | |||
} | |||
@@ -28,6 +28,10 @@ | |||
<None Remove="Resources\Images\阴影边框.png" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="BPA.Communication" Version="1.0.9" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmart.Model\BPASmart.Model.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.CustomResource\BPASmartClient.CustomResource.csproj" /> | |||
@@ -14,6 +14,8 @@ using System.Text.Json.Serialization; | |||
using Microsoft.EntityFrameworkCore.Metadata.Internal; | |||
using Ubiety.Dns.Core.Records; | |||
using System.Windows; | |||
using BPA.Communication; | |||
using System.Threading; | |||
namespace BPASmart.VariableManager.ViewModels | |||
{ | |||
@@ -22,6 +24,50 @@ namespace BPASmart.VariableManager.ViewModels | |||
private int varialeInfosIndex = -1; | |||
ICommunicationDevice DeviceType; | |||
public VariableConfigViewModel(string o) | |||
{ | |||
DataInit(o); | |||
VarNameChanged(); | |||
StartMotionCommand = new RelayCommand(() => | |||
{ | |||
switch (ButtonContext) | |||
{ | |||
case "开始监控": | |||
TabName = "当前值"; | |||
CurrentVisibility = Visibility.Visible; | |||
RemoveButVisiblity = Visibility.Collapsed; | |||
ButtonContext = "停止监控"; | |||
IsEnable = false; | |||
Motion(); | |||
break; | |||
case "停止监控": | |||
TabName = "操作"; | |||
CurrentVisibility = Visibility.Collapsed; | |||
RemoveButVisiblity = Visibility.Visible; | |||
ButtonContext = "开始监控"; | |||
IsEnable = true; | |||
ThreadManage.GetInstance().StopTask($"{DeviceType} 初始化连接"); | |||
ThreadManage.GetInstance().StopTask($"{DeviceType} 设备数据采集"); | |||
break; | |||
default: | |||
break; | |||
} | |||
}); | |||
RemoveCommand = new RelayCommand<object>((o) => | |||
{ | |||
if (o != null && o is VariableInfo variable) | |||
{ | |||
varialeInfos.Remove(variable); | |||
} | |||
for (int i = 0; i < varialeInfos.Count; i++) | |||
{ | |||
varialeInfos.ElementAt(i).ID = i + 1; | |||
} | |||
}); | |||
} | |||
private void DataInit(string o) | |||
{ | |||
varialeInfosIndex = Array.FindIndex(Json<CommunicationPar>.Data.CommunicationDevices.ToArray(), p => p.DeviceName == o); | |||
if (varialeInfosIndex >= 0 && varialeInfosIndex < Json<CommunicationPar>.Data.CommunicationDevices.Count) | |||
@@ -39,7 +85,10 @@ namespace BPASmart.VariableManager.ViewModels | |||
AddressWidth = Convert.ToDouble(p[1]); | |||
} | |||
}), "TabGridSizeChanged"); | |||
} | |||
private void VarNameChanged() | |||
{ | |||
DelegationNotifi.GetInstance.VarNameChanged = new Action<int>((p) => | |||
{ | |||
var result = varialeInfos.GroupBy(P => P.VarName).ToList(); | |||
@@ -84,51 +133,85 @@ namespace BPASmart.VariableManager.ViewModels | |||
{ | |||
if (varialeInfos?.Count >= p) | |||
{ | |||
//if (varialeInfos.ElementAt(p - 1).VarName != null) | |||
//{ | |||
if (varialeInfos.ElementAt(p - 1).VarName?.Length > 0) | |||
{ | |||
if (varialeInfos.Count == p) AddRow(); | |||
} | |||
//} | |||
} | |||
} | |||
}); | |||
} | |||
StartMotionCommand = new RelayCommand(() => | |||
private void Motion() | |||
{ | |||
ThreadManage.GetInstance().Start(new Action(() => | |||
{ | |||
switch (ButtonContext) | |||
switch (DeviceType) | |||
{ | |||
case "开始监控": | |||
TabName = "当前值"; | |||
CurrentVisibility = Visibility.Visible; | |||
RemoveButVisiblity = Visibility.Collapsed; | |||
ButtonContext = "停止监控"; | |||
case BPASmart.Model.ModbusRtu _modbusRtu: | |||
break; | |||
case "停止监控": | |||
TabName = "操作"; | |||
CurrentVisibility = Visibility.Collapsed; | |||
RemoveButVisiblity = Visibility.Visible; | |||
ButtonContext = "开始监控"; | |||
case BPASmart.Model.ModbusTcp _modbusTcp: | |||
BPA.Communication.ModbusTcp modbusTcpMaster = new BPA.Communication.ModbusTcp(); | |||
modbusTcpMaster.ConnectOk = new Action(() => | |||
{ | |||
ThreadManage.GetInstance().StartLong(new Action(() => | |||
{ | |||
GetReadDataModels().ToList()?.ForEach(temp => | |||
{ | |||
switch (temp.Key) | |||
{ | |||
case EDataType.Bool: | |||
temp.Value?.ForEach(value => | |||
{ | |||
var res = modbusTcpMaster.ReadCoils(value.StartAddress, value.Length); | |||
SetValue(res, value, 1); | |||
}); | |||
break; | |||
case EDataType.Byte: | |||
break; | |||
case EDataType.Int: | |||
break; | |||
case EDataType.Word: | |||
temp.Value?.ForEach(value => | |||
{ | |||
var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); | |||
SetValue(res, value, 1); | |||
}); | |||
break; | |||
case EDataType.Dint: | |||
break; | |||
case EDataType.Dword: | |||
temp.Value?.ForEach(value => | |||
{ | |||
var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); | |||
SetValue(res, value, 2); | |||
}); | |||
break; | |||
case EDataType.Float: | |||
temp.Value?.ForEach(value => | |||
{ | |||
var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); | |||
SetValue(res, value, 2); | |||
}); | |||
break; | |||
default: | |||
break; | |||
} | |||
}); | |||
Thread.Sleep(100); | |||
}), $"{DeviceType} 设备数据采集"); | |||
//var DeviceModel = item; | |||
}); | |||
modbusTcpMaster.IsReconnect = true; | |||
modbusTcpMaster.ModbusTcpConnect(_modbusTcp.IP, _modbusTcp.PortNum); | |||
break; | |||
case BPASmart.Model.Siemens _siemens: | |||
break; | |||
default: | |||
break; | |||
} | |||
}); | |||
RemoveCommand = new RelayCommand<object>((o) => | |||
{ | |||
if (o != null && o is VariableInfo variable) | |||
{ | |||
varialeInfos.Remove(variable); | |||
} | |||
for (int i = 0; i < varialeInfos.Count; i++) | |||
{ | |||
varialeInfos.ElementAt(i).ID = i + 1; | |||
} | |||
}); | |||
}), $"{DeviceType} 初始化连接"); | |||
} | |||
/// <summary> | |||
@@ -168,6 +251,9 @@ namespace BPASmart.VariableManager.ViewModels | |||
private static Visibility _mRemoveButVisiblity = Visibility.Visible; | |||
public bool IsEnable { get { return _mIsEnable; } set { _mIsEnable = value; OnPropertyChanged(); } } | |||
private bool _mIsEnable = true; | |||
#endregion | |||
@@ -197,6 +283,78 @@ namespace BPASmart.VariableManager.ViewModels | |||
public RelayCommand<object> RemoveCommand { get; set; } | |||
#endregion | |||
private void SetValue<TArray>(TArray[] arrays, ReadDataModel readDataModel, ushort by) | |||
{ | |||
for (int i = 0; i < arrays.Length; i++) | |||
{ | |||
int varIndex = Array.FindIndex(varialeInfos.ToArray(), p => p.RealAddress == readDataModel.StartAddress + (i * by)); | |||
if (varIndex >= 0 && varIndex < varialeInfos.Count) | |||
{ | |||
varialeInfos.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); | |||
} | |||
} | |||
} | |||
private Dictionary<EDataType, List<ReadDataModel>> GetReadDataModels() | |||
{ | |||
Dictionary<EDataType, List<ReadDataModel>> readDataModels = new Dictionary<EDataType, List<ReadDataModel>>(); | |||
varialeInfos.GroupBy(p => p.DataType)?.ToList()?.ForEach(tempVar => | |||
{ | |||
if (tempVar.Key != null && tempVar.Key.Length > 0) | |||
{ | |||
int address = tempVar.Min(p => p.RealAddress); | |||
EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); | |||
switch (dataType) | |||
{ | |||
case EDataType.Bool: | |||
case EDataType.Byte: | |||
case EDataType.Int: | |||
case EDataType.Word: | |||
if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar)); | |||
break; | |||
case EDataType.Dint: | |||
case EDataType.Dword: | |||
case EDataType.Float: | |||
if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar, 2)); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
}); | |||
return readDataModels; | |||
} | |||
private List<ReadDataModel> GetDataGroup(IGrouping<string, VariableInfo> variableInfos, int by = 1) | |||
{ | |||
List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | |||
var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); | |||
int count = 0; | |||
if (res != null) | |||
{ | |||
int address = variableInfos.Min(p => p.RealAddress); | |||
int startAddress = address; | |||
for (int i = 0; i < res.Count; i++) | |||
{ | |||
if (res.ElementAt(i).RealAddress == address) | |||
{ | |||
count++; | |||
address += by; | |||
} | |||
else | |||
{ | |||
ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | |||
count = 1; | |||
address = res.ElementAt(i).RealAddress + by; | |||
startAddress = res.ElementAt(i).RealAddress; | |||
} | |||
} | |||
ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | |||
} | |||
return ReturnValue; | |||
} | |||
/// <summary> | |||
/// 下拉列表初始化 | |||
@@ -248,7 +248,7 @@ | |||
<!--#endregion--> | |||
<Grid Grid.Row="2"> | |||
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"> | |||
<ScrollViewer IsEnabled="{Binding IsEnable}" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"> | |||
<ItemsControl ItemsSource="{Binding varialeInfos}"> | |||
<ItemsControl.ItemTemplate> | |||
<DataTemplate> | |||
@@ -299,6 +299,7 @@ | |||
BorderThickness="1" | |||
FontFamily="楷体" | |||
FontSize="20" | |||
IsEnabled="{Binding DataContext.IsEnable,RelativeSource={RelativeSource AncestorType=ItemsControl,Mode=FindAncestor}}" | |||
Foreground="{Binding IsRedundant, Converter={StaticResource tabConvert}}" | |||
IsEditable="False" | |||
ItemsSource="{Binding DataContext.dataType, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}" | |||
@@ -97,7 +97,6 @@ | |||
<Setter TargetName="_borderbg" Property="Background" Value="{StaticResource ComboBoxMouseOverBackground}" /> | |||
<Setter TargetName="_txt" Property="Foreground" Value="{StaticResource ComboBoxMouseOverForegrond}" /> | |||
</MultiTrigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
@@ -194,6 +193,9 @@ | |||
<Setter TargetName="_prybr" Property="BorderBrush" Value="#aa3ba7f2" /> | |||
<!--<Setter Property="Background" Value="#553ba7f2" TargetName="_prybr"/>--> | |||
</Trigger> | |||
<Trigger Property="IsEnabled" Value="False"> | |||
<Setter TargetName="ContentSite" Property="Opacity" Value="0.6" /> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
@@ -0,0 +1,17 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net6.0</TargetFramework> | |||
<ImplicitUsings>enable</ImplicitUsings> | |||
<Nullable>enable</Nullable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="ServiceStack.Redis" Version="6.3.0" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.Message\BPASmartClient.Message.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,60 @@ | |||
using ServiceStack.Redis; | |||
namespace Communication | |||
{ | |||
public class RedisHelper | |||
{ | |||
private volatile static RedisHelper _Instance; | |||
public static RedisHelper GetInstance => _Instance ?? (_Instance = new RedisHelper()); | |||
private RedisHelper() { } | |||
RedisClient client; | |||
public void Connect() | |||
{ | |||
if (client == null) | |||
{ | |||
client = new RedisClient("124.222.238.75", 16000, "123456", 1); | |||
Thread.Sleep(1000); | |||
//while (!client.HasConnected) | |||
//{ | |||
// client = new RedisClient("124.222.238.75", 16000, "123456"); | |||
// Thread.Sleep(1000); | |||
//} | |||
} | |||
if (client.HasConnected) BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("Redis 连接成功"); | |||
} | |||
/// <summary> | |||
/// 清除所有redis 数据 | |||
/// </summary> | |||
public void FlushDb() | |||
{ | |||
client?.FlushDb(); | |||
} | |||
/// <summary> | |||
/// 设置值 | |||
/// </summary> | |||
/// <typeparam name="TValue"></typeparam> | |||
/// <param name="key"></param> | |||
/// <param name="value"></param> | |||
public void SetValue<TValue>(string key, TValue value) | |||
{ | |||
var res = client?.Set<TValue>(key, value); | |||
} | |||
/// <summary> | |||
/// 获取值 | |||
/// </summary> | |||
/// <typeparam name="TResult"></typeparam> | |||
/// <param name="key"></param> | |||
/// <returns></returns> | |||
public TResult GetValue<TResult>(string key) | |||
{ | |||
if (client == null) return default(TResult); | |||
return client.Get<TResult>(key); | |||
} | |||
} | |||
} |
@@ -158,11 +158,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.VariableManager", | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DistributedHostComputer", "DistributedHostComputer", "{CDC1E762-5E1D-4AE1-9DF2-B85761539086}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmart.DataServer", "BPASmart.DataServer\BPASmart.DataServer.csproj", "{00C5B45D-9799-43F1-B07B-9F638AA9FF72}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.DataServer", "BPASmart.DataServer\BPASmart.DataServer.csproj", "{00C5B45D-9799-43F1-B07B-9F638AA9FF72}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmart.Model", "BPASmart.Model\BPASmart.Model.csproj", "{5083C91F-B23E-445D-8B7F-AF87E636E847}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.Model", "BPASmart.Model\BPASmart.Model.csproj", "{5083C91F-B23E-445D-8B7F-AF87E636E847}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmart.Server", "BPASmart.Server\BPASmart.Server.csproj", "{F67FBFAC-6C80-466D-A596-1B9B10E885FC}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.Server", "BPASmart.Server\BPASmart.Server.csproj", "{F67FBFAC-6C80-466D-A596-1B9B10E885FC}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Communication", "Communication\Communication.csproj", "{1062F7C7-0117-413C-A45E-8F9B525FC036}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
@@ -1498,6 +1500,26 @@ Global | |||
{F67FBFAC-6C80-466D-A596-1B9B10E885FC}.Release|x64.Build.0 = Release|Any CPU | |||
{F67FBFAC-6C80-466D-A596-1B9B10E885FC}.Release|x86.ActiveCfg = Release|Any CPU | |||
{F67FBFAC-6C80-466D-A596-1B9B10E885FC}.Release|x86.Build.0 = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|ARM64.ActiveCfg = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|ARM64.Build.0 = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|x64.Build.0 = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Debug|x86.Build.0 = Debug|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|ARM.Build.0 = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|ARM64.ActiveCfg = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|ARM64.Build.0 = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x64.ActiveCfg = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x64.Build.0 = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x86.ActiveCfg = Release|Any CPU | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x86.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -1573,6 +1595,7 @@ Global | |||
{00C5B45D-9799-43F1-B07B-9F638AA9FF72} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | |||
{5083C91F-B23E-445D-8B7F-AF87E636E847} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | |||
{F67FBFAC-6C80-466D-A596-1B9B10E885FC} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | |||
{1062F7C7-0117-413C-A45E-8F9B525FC036} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | |||