diff --git a/VKT5_RemoteConsole/Plugin.cs b/VKT5_RemoteConsole/Plugin.cs new file mode 100644 index 0000000..63c1fbc --- /dev/null +++ b/VKT5_RemoteConsole/Plugin.cs @@ -0,0 +1,174 @@ +using System; +using System.Windows.Forms; +using Lers.Plugins; +using Lers.UI; +using Lers.Poll; +using Lers.Utils; +using Lers.Interop; +using System.Collections.Generic; +using Lers.UI.Tabs; +using Lers.Core; + +namespace Vkt5_RemoteConsole +{ + public class Plugin : IPlugin + { + #region IPlugin Members + + /// + /// Инициализация плагина + /// + /// + public void Initialize(IPluginHost pluginHost) + { + Plugin.Host = pluginHost; + + // Добавляем элементы управления для точек учёта + Plugin.Host.MainWindow.RegisterObjectAction(ObjectType.MeasurePoint, "ВКТ-5: Удалённый пульт", Properties.Resources.vkt5_icon, OnRemoteConsoleOpen); + } + + #endregion + + /// + /// Экземпляр хост-интерфейса клиента + /// + internal static IPluginHost Host + { + get; + private set; + } + + /// + /// Пользователь выбрал пункт меню или навигационного окна "Удалённый пульт" + /// + /// + /// + private void OnRemoteConsoleOpen(int actionId, object sender) + { + MeasurePoint measurePoint = (MeasurePoint)sender; + + // Запрашиваем требуемую для работы информацию + measurePoint.Refresh(MeasurePointInfoFlags.Equipment); + + // Проверим, что у точки учёта есть устройство + if (measurePoint.Device == null) + { + MessageBox.Show("У выбранной точки учёта не задано устройство. Выберите точку учёта с поддерживаемым устройством.", + "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); + + return; + } + + // Проверим, что мы работаем с ВКТ-5 + if (!CheckDeviceModel(measurePoint.Device)) + { + MessageBox.Show("Удалённый пульт ВКТ-5 не поддерживает работу с устройствами " + + measurePoint.Device.Model.Title, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); + + return; + } + + // Проверим, открыто ли окно с опросом этого устройства + Vkt5RemoteConsoleForm currentForm = GetOpenedForm(measurePoint.Device); + if (currentForm == null) + { + // Такого окна нет, открываем + NewForm(measurePoint.Device); + } + else + { + // Окно уже есть, переводим фокус на него + currentForm.Show(); + currentForm.Focus(); + } + } + + + /// + /// Проверяет, что в выбранной точке учёта указана модель, + /// которая поддерживается удалённым пультом + /// + /// + /// true если модель поддерживается, иначе false + private bool CheckDeviceModel(Equipment device) + { + return device.Model.Id == (int)DeviceModel.VKT_5; + } + + /// + /// Открывает новое окно для управления устройством + /// + /// + private void NewForm(Equipment device) + { + // Окно для этого устройства ещё не открыто + Vkt5RemoteConsoleForm mainForm = new Vkt5RemoteConsoleForm(); + + // Заголовок окна + mainForm.Text = "Удалённый пульт - " + device.ToString(); + + RemoteConsoleFormParams param = new RemoteConsoleFormParams(); + + // Параметры базовой формы опроса + param.PollConnections = device.PollSettings.Connections; + if (param.PollConnections != null && param.PollConnections.Length > 0) + { + param.SelectedConnection = param.PollConnections[0]; + } + + // Параметры формы удалённого пульта + param.Device = device; + + // Инициализация + mainForm.Initialize(param, Plugin.Host.Server); + + Plugin.Host.MainWindow.AddPage(mainForm); + + mainForm.Show(); + + mainForm.FormClosed += new System.Windows.Forms.FormClosedEventHandler(currentForm_FormClosed); + + lock (this.visibleForms) + { + this.visibleForms.Add(mainForm); + } + } + + /// + /// Возвращает открытую форму, работающую с указанным устройством, или null если формы нет + /// + /// + /// + private Vkt5RemoteConsoleForm GetOpenedForm(Equipment device) + { + lock (this.visibleForms) + { + foreach (Vkt5RemoteConsoleForm form in this.visibleForms) + { + if (form.Parameters.Device == device) + { + return form; + } + } + } + + return null; + } + + + /// + /// Закрыто окно удалённого пульта. Удаляем его из списка открытых окон. + /// + /// + /// + void currentForm_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e) + { + lock (this.visibleForms) + { + this.visibleForms.Remove((Vkt5RemoteConsoleForm)sender); + } + } + + private List visibleForms = new List(); + } +} \ No newline at end of file diff --git a/VKT5_RemoteConsole/Properties/AssemblyInfo.cs b/VKT5_RemoteConsole/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7f4425e --- /dev/null +++ b/VKT5_RemoteConsole/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Lers.Plugins; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Удалённый пульт ВКТ-5")] +[assembly: AssemblyDescription("Внешний модуль ЛЭРС УЧЕТ для удалённого управления теплосчётчиками ВКТ-5")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("ООО \"Хабаровский центр энергоресурсосбережения\" (www.lers.ru)")] +[assembly: AssemblyProduct("Система диспетчеризации ЛЭРС УЧЕТ")] +[assembly: AssemblyCopyright("© 2000-2014, Хабаровский центр энергоресурсосбережения")] +[assembly: AssemblyTrademark("Внимание: Данная компьютерная программа защищена законами об авторских правах и международными соглашениями. Незаконное воспроизведение или распространения данной программы или любой ее части влечет гражданскую и уголовную ответственность.")] +[assembly: AssemblyCulture("")] + +[assembly: AssemblyPlugin("B8837A83-3700-47E1-ADAA-02E7496914F0")] +[assembly: AssemblyPluginWebsite("http://www.lers.ru")] +[assembly: AssemblyPluginEmail("support@lers.ru")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("092a73fe-433c-4ab9-b6df-54ca0393806c")] + +// Чтобы внешние модули обновлялись автоматически, необходимо увеличивать версию файла. +// Т.к. мы можем забыть это сделать, то лучше чтобы версия увеличивалась сама. Звездочку можно задать только для версии сборки, +// для версии файла она не работает. Но если не указать версию файла, то она будет равна версии сборки. + +[assembly: AssemblyVersion("1.1.*")] +//[assembly: AssemblyFileVersion("1.0.0.0")] + diff --git a/VKT5_RemoteConsole/Properties/Resources.Designer.cs b/VKT5_RemoteConsole/Properties/Resources.Designer.cs new file mode 100644 index 0000000..7f3ade7 --- /dev/null +++ b/VKT5_RemoteConsole/Properties/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace Vkt5_RemoteConsole.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Vkt5_RemoteConsole.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap back { + get { + object obj = ResourceManager.GetObject("back", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap down { + get { + object obj = ResourceManager.GetObject("down", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap enter { + get { + object obj = ResourceManager.GetObject("enter", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap left { + get { + object obj = ResourceManager.GetObject("left", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap menu { + get { + object obj = ResourceManager.GetObject("menu", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap right { + get { + object obj = ResourceManager.GetObject("right", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tab { + get { + object obj = ResourceManager.GetObject("tab", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap up { + get { + object obj = ResourceManager.GetObject("up", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap vkt5_icon { + get { + object obj = ResourceManager.GetObject("vkt5_icon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/VKT5_RemoteConsole/Properties/Resources.resx b/VKT5_RemoteConsole/Properties/Resources.resx new file mode 100644 index 0000000..dddbd34 --- /dev/null +++ b/VKT5_RemoteConsole/Properties/Resources.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\vkt5_icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\back.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\enter.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\menu.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\right.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\tab.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/VKT5_RemoteConsole/Properties/licenses.licx b/VKT5_RemoteConsole/Properties/licenses.licx new file mode 100644 index 0000000..e69de29 diff --git a/VKT5_RemoteConsole/Resources/PluginImage.png b/VKT5_RemoteConsole/Resources/PluginImage.png new file mode 100644 index 0000000..ab44f66 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/PluginImage.png differ diff --git a/VKT5_RemoteConsole/Resources/back.png b/VKT5_RemoteConsole/Resources/back.png new file mode 100644 index 0000000..c95a0d3 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/back.png differ diff --git a/VKT5_RemoteConsole/Resources/down.png b/VKT5_RemoteConsole/Resources/down.png new file mode 100644 index 0000000..bb9bc22 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/down.png differ diff --git a/VKT5_RemoteConsole/Resources/enter.png b/VKT5_RemoteConsole/Resources/enter.png new file mode 100644 index 0000000..9531f91 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/enter.png differ diff --git a/VKT5_RemoteConsole/Resources/left.png b/VKT5_RemoteConsole/Resources/left.png new file mode 100644 index 0000000..ff63819 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/left.png differ diff --git a/VKT5_RemoteConsole/Resources/menu.png b/VKT5_RemoteConsole/Resources/menu.png new file mode 100644 index 0000000..2f90c45 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/menu.png differ diff --git a/VKT5_RemoteConsole/Resources/right.png b/VKT5_RemoteConsole/Resources/right.png new file mode 100644 index 0000000..3261053 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/right.png differ diff --git a/VKT5_RemoteConsole/Resources/tab.png b/VKT5_RemoteConsole/Resources/tab.png new file mode 100644 index 0000000..4f7e23c Binary files /dev/null and b/VKT5_RemoteConsole/Resources/tab.png differ diff --git a/VKT5_RemoteConsole/Resources/up.png b/VKT5_RemoteConsole/Resources/up.png new file mode 100644 index 0000000..d58d237 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/up.png differ diff --git a/VKT5_RemoteConsole/Resources/vkt5_icon.png b/VKT5_RemoteConsole/Resources/vkt5_icon.png new file mode 100644 index 0000000..9c37715 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/vkt5_icon.png differ diff --git a/VKT5_RemoteConsole/Resources/vkt5_icon1.png b/VKT5_RemoteConsole/Resources/vkt5_icon1.png new file mode 100644 index 0000000..9c37715 Binary files /dev/null and b/VKT5_RemoteConsole/Resources/vkt5_icon1.png differ diff --git a/VKT5_RemoteConsole/Vkt5Console.cs b/VKT5_RemoteConsole/Vkt5Console.cs new file mode 100644 index 0000000..3f1e71b --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5Console.cs @@ -0,0 +1,333 @@ +using System; +using Lers; +using Lers.Poll; +using System.Collections.Generic; + + +namespace Vkt5_RemoteConsole +{ + delegate void VktDataReadEventHandler(byte[] dataByte); + + enum Vkt5Key: byte + { + Right = 0, + Left = 1, + Down = 2, + Up = 3, + Tab = 4, + Enter = 5, + Back = 6, + Menu = 7, + LongMenuPress = 9 + } + + + /// + /// Класс для отправки запросов и считывания ответов от ECL 300 + /// ВНИМАНИЕ! После считывания ответа перед повторным запросом к прибору нужно выждать 400мс + /// + class Vkt5Console + { + #region События и методы для протоколирования + + /// + /// Вызвается при ошибке выполнения запроса + /// + public event EventHandler RequestError; + + private void CallRequestError() + { + if (this.RequestError != null) + this.RequestError(this, EventArgs.Empty); + } + + /// + /// Событие поднимается когда необходимо запротоколировать ошибку чтения данных + /// + public event WriteLogEventHandler WriteLog; + + private void LogMessage(string msg) + { + if (this.WriteLog != null) + { + this.WriteLog(Importance.Info, msg); + } + } + + private void LogWarning(string msg) + { + if (this.WriteLog != null) + { + this.WriteLog(Importance.Warn, msg); + } + } + + private void LogError(string msg) + { + if (this.WriteLog != null) + { + this.WriteLog(Importance.Error, msg); + } + } + + #endregion + + /// + /// Сетевой адрес прибора + /// + public int NetworkAddress + { + get; + set; + } + + /// + /// Конструктор + /// + /// + public Vkt5Console(RemoteConsole remoteConsole) + { + this.NetworkAddress = 0; + + this.remoteConsole = remoteConsole; + this.remoteConsole.DeviceDataReceived += new EventHandler(remoteConsole_DeviceDataReceived); + } + + /// + /// Сброс состояния объекта в исходную позицию + /// + public void Reset() + { + this.handlers.Clear(); + } + + /// + /// Отправляет команду на чтение буфера экрана устройства + /// + /// + public void ReadScreenBuffer(VktDataReadEventHandler readHandler) + { + byte[] rq = PackRequest(new byte[] { 0x03, 0x0C, 0x00, 0x00, 0x00 }); + SendRequest(rq, 38, readHandler); + } + + + /// + /// Отправляет в устройство команду нажатия клавишы + /// + /// + /// + public void SendKeyCode(Vkt5Key key, VktDataReadEventHandler readHandler) + { + byte[] rq = PackRequest(new byte[] { 0x10, 0x0D, 0x00, 0x00, 0x01, 0x01, (byte)key }); + SendRequest(rq, 8, readHandler); + } + + /// + /// Формирует пакет с запросом прибору + /// + /// + /// + private byte[] PackRequest(byte[] rqData) + { + List request = new List(); + + // Сетевой адрес + request.Add((byte)this.NetworkAddress); + + // Пакет с запросом + request.AddRange(rqData); + + ushort crc = ModBusCrc.Calc(request); + + request.Add((byte)(crc & 0x00FF)); + request.Add((byte)((crc & 0xFF00) >> 8)); + + + return request.ToArray(); + } + + + /// + /// Отправка запроса прибору + /// + /// + /// + /// + private void SendRequest(byte[] request, int responseLength, VktDataReadEventHandler readHandler) + { + CommandSettings cmd = new CommandSettings("", 1000, responseLength, 10); + + this.handlers.AddLast(readHandler); + + this.responseLength = responseLength; + + this.remoteConsole.SendCommandAsync(request, cmd, 0, DataReadCallback, null); + } + + private void DataReadCallback(Lers.AsyncOperation asyncOp) + { + try + { + // Завершаем операцию чтения данных + Lers.Networking.ExecuteRequestAsyncOperation execRequestAsyncOp + = (Lers.Networking.ExecuteRequestAsyncOperation)asyncOp; + + execRequestAsyncOp.EndExecuteRequest(); + } + catch (Exception e) + { + // При ошибке отправки данных отключаемся от устройства + LogError("Ошибка чтения данных. " + e.Message); + } + } + + private void remoteConsole_DeviceDataReceived(object sender, DeviceDataEventArgs args) + { + // Проверим, что консоль подключена к прибору + if (!this.remoteConsole.IsConnected) + { + return; + } + + // Получаем обработчик запроса + VktDataReadEventHandler currentHandler = this.handlers.First.Value; + this.handlers.RemoveFirst(); + + // Проверим длину считанного пакета + if (args.Response.Length < 5) + { + // Повторяем запрос + LogError("Неверная длина ответа прибора. Ожидалось не менее 5 байт, получено " + args.Response.Length); + + CallRequestError(); + + // Отключаемся + try + { + this.remoteConsole.DisconnectAsync(null, null); + } + catch (Lers.PermissionDeniedException exc) + { + LogError("Ошибка отключения удалённого пульта. " + exc.Message); + } + + return; + } + + // Проверим контрольную сумму + ushort calcCs = ModBusCrc.Calc(args.Response, 0, args.Response.Length - 2); + ushort recvCrc = BitConverter.ToUInt16(args.Response, args.Response.Length - 2); + + if (calcCs != recvCrc) + { + LogWarning("Не сходится контрольная сумма ответа"); + + // Повторяем запрос + SendRequest(args.Request, this.responseLength, currentHandler); + + return; + } + + // Проверим сетевой адрес + if (args.Response[0] != (byte)this.NetworkAddress) + { + LogWarning("В ответе указан неверный контрольный адрес"); + + // Повторяем запрос + SendRequest(args.Request, this.responseLength, currentHandler); + + return; + } + + // Возвращаем считанные прибором данные + if (currentHandler != null) + { + byte[] rspData = new byte[args.Response.Length - 5]; + Array.Copy(args.Response, 3, rspData, 0, rspData.Length); + currentHandler(rspData); + } + } + + + /// + /// Объект для отправки запросов и считывания ответов от удалённого прибора + /// + private RemoteConsole remoteConsole = null; + + /// + /// Длина ответа на запрос + /// + private int responseLength = 0; + + /// + /// Список обработчиков ответов + /// + LinkedList handlers = new LinkedList(); + } + + class ModBusCrc + { + /// + /// Вычисляет контрольную сумму для переданного блока данных, согласно + /// спецификации протокола ModBus (Modicon Modbus Protocol Reference Guide) + /// + /// Для расчета контрольной суммы используется модифицированный CRC-16-IBM с полиномом 0xA001. + /// В отличие от стандартного алгоритма CRC-16-IBM, начальное значение устанавливается равным 0xFFFF + /// + /// Массив байт, по которому нужно посчитать CRC + /// Начальный индекс в массиве байт + /// Количество байт, начиная со start, используемых в расчете контрольной суммы + /// Значение контрольной суммы + public static ushort Calc(IList input, int start, int length) + { + int i, j; + + if (length > input.Count) + throw new Exception(String.Format("При расчете контрольной суммы по блоку данных длиной {0} байт, указана длина {1} байт", input.Count, length)); + + // Для хранения CRC используем тип int, чтобы не заниматься приведением типов + // постоянно, а сделать это только при выходе + // При расчете CRC значение никогда не выйдет за границы 2-х младших байт (сдвигаем всегда вправо) + // поэтому при операциях сдвига, сдвиг знакового бита переменной crc не обрабатываем + int crc = 0xFFFF; + + // обнуляем 2 старших байта + for (i = start; i < start + length; i++) + { + crc = (ushort)crc & 0xFF00 + (ushort)(crc & 0x00FF) ^ input[i]; + + for (j = 0; j < 8; j++) + { + if ((crc & 0x01) > 0) + { + // Сдвигаем вправо на 1 бит и XOR-им полиномом 0xA001 + crc = (crc >> 1) ^ 0xA001; + } + else + { + // Сдвигаем вправо на 1 бит + crc = (crc >> 1); + } + } + } + + // Возвращаем 2 младших байта + return (ushort)crc; + } + + /// + /// Вычисляет контрольную сумму для переданного блока данных, согласно + /// спецификации протокола ModBus (Modicon Modbus Protocol Reference Guide) + /// + /// Для расчета контрольной суммы используется модифицированный CRC-16-IBM с полиномом 0xA001. + /// В отличие от стандартного алгоритма CRC-16-IBM, начальное значение устанавливается равным 0xFFFF + /// + /// Массив байт, по которому нужно посчитать CRC + /// Значение контрольной суммы + public static ushort Calc(IList input) + { + return ModBusCrc.Calc(input, 0, input.Count); + } + } +} \ No newline at end of file diff --git a/VKT5_RemoteConsole/Vkt5ConsoleControl.Designer.cs b/VKT5_RemoteConsole/Vkt5ConsoleControl.Designer.cs new file mode 100644 index 0000000..0e3548e --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5ConsoleControl.Designer.cs @@ -0,0 +1,222 @@ +namespace Vkt5_RemoteConsole +{ + partial class Vkt5ConsoleControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Vkt5ConsoleControl)); + this.panel1 = new System.Windows.Forms.Panel(); + this.txtLine2 = new System.Windows.Forms.Label(); + this.txtLine1 = new System.Windows.Forms.Label(); + this.btnMenu = new System.Windows.Forms.Button(); + this.btnBack = new System.Windows.Forms.Button(); + this.btnTab = new System.Windows.Forms.Button(); + this.btnLeft = new System.Windows.Forms.Button(); + this.btnEnter = new System.Windows.Forms.Button(); + this.btnDown = new System.Windows.Forms.Button(); + this.btnUp = new System.Windows.Forms.Button(); + this.btnRight = new System.Windows.Forms.Button(); + this.refreshTimer = new System.Windows.Forms.Timer(); + this.cursorTimer = new System.Windows.Forms.Timer(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(140)))), ((int)(((byte)(180)))), ((int)(((byte)(40))))); + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.Controls.Add(this.txtLine2); + this.panel1.Controls.Add(this.txtLine1); + this.panel1.Location = new System.Drawing.Point(12, 14); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(318, 67); + this.panel1.TabIndex = 20; + // + // txtLine2 + // + this.txtLine2.Font = new System.Drawing.Font("Lucida Console", 21.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.txtLine2.ForeColor = System.Drawing.Color.DimGray; + this.txtLine2.Location = new System.Drawing.Point(3, 35); + this.txtLine2.Name = "txtLine2"; + this.txtLine2.Size = new System.Drawing.Size(310, 29); + this.txtLine2.TabIndex = 1; + this.txtLine2.Text = "подключения"; + // + // txtLine1 + // + this.txtLine1.Font = new System.Drawing.Font("Lucida Console", 21.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.txtLine1.ForeColor = System.Drawing.Color.DimGray; + this.txtLine1.Location = new System.Drawing.Point(3, 3); + this.txtLine1.Name = "txtLine1"; + this.txtLine1.Size = new System.Drawing.Size(310, 29); + this.txtLine1.TabIndex = 0; + this.txtLine1.Text = "Нет"; + // + // btnMenu + // + this.btnMenu.BackColor = System.Drawing.Color.Gray; + this.btnMenu.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnMenu.Image = ((System.Drawing.Image)(resources.GetObject("btnMenu.Image"))); + this.btnMenu.Location = new System.Drawing.Point(222, 102); + this.btnMenu.Name = "btnMenu"; + this.btnMenu.Size = new System.Drawing.Size(108, 64); + this.btnMenu.TabIndex = 18; + this.btnMenu.UseVisualStyleBackColor = false; + this.btnMenu.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnMenu_MouseDown); + this.btnMenu.MouseUp += new System.Windows.Forms.MouseEventHandler(this.btnMenu_MouseUp); + // + // btnBack + // + this.btnBack.BackColor = System.Drawing.Color.Gray; + this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnBack.Image = ((System.Drawing.Image)(resources.GetObject("btnBack.Image"))); + this.btnBack.Location = new System.Drawing.Point(12, 102); + this.btnBack.Name = "btnBack"; + this.btnBack.Size = new System.Drawing.Size(64, 64); + this.btnBack.TabIndex = 12; + this.btnBack.UseVisualStyleBackColor = false; + this.btnBack.Click += new System.EventHandler(this.btnBack_Click); + // + // btnTab + // + this.btnTab.BackColor = System.Drawing.Color.Gray; + this.btnTab.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnTab.Image = ((System.Drawing.Image)(resources.GetObject("btnTab.Image"))); + this.btnTab.Location = new System.Drawing.Point(222, 172); + this.btnTab.Name = "btnTab"; + this.btnTab.Size = new System.Drawing.Size(108, 64); + this.btnTab.TabIndex = 19; + this.btnTab.UseVisualStyleBackColor = false; + this.btnTab.Click += new System.EventHandler(this.btnTab_Click); + // + // btnLeft + // + this.btnLeft.BackColor = System.Drawing.Color.Gray; + this.btnLeft.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnLeft.Image = ((System.Drawing.Image)(resources.GetObject("btnLeft.Image"))); + this.btnLeft.Location = new System.Drawing.Point(12, 172); + this.btnLeft.Name = "btnLeft"; + this.btnLeft.Size = new System.Drawing.Size(64, 64); + this.btnLeft.TabIndex = 15; + this.btnLeft.UseVisualStyleBackColor = false; + this.btnLeft.Click += new System.EventHandler(this.btnLeft_Click); + // + // btnEnter + // + this.btnEnter.BackColor = System.Drawing.Color.Gray; + this.btnEnter.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnEnter.Image = ((System.Drawing.Image)(resources.GetObject("btnEnter.Image"))); + this.btnEnter.Location = new System.Drawing.Point(152, 102); + this.btnEnter.Name = "btnEnter"; + this.btnEnter.Size = new System.Drawing.Size(64, 64); + this.btnEnter.TabIndex = 14; + this.btnEnter.UseVisualStyleBackColor = false; + this.btnEnter.Click += new System.EventHandler(this.btnEnter_Click); + // + // btnDown + // + this.btnDown.BackColor = System.Drawing.Color.Gray; + this.btnDown.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnDown.Image = ((System.Drawing.Image)(resources.GetObject("btnDown.Image"))); + this.btnDown.Location = new System.Drawing.Point(82, 172); + this.btnDown.Name = "btnDown"; + this.btnDown.Size = new System.Drawing.Size(64, 64); + this.btnDown.TabIndex = 16; + this.btnDown.UseVisualStyleBackColor = false; + this.btnDown.Click += new System.EventHandler(this.btnDown_Click); + // + // btnUp + // + this.btnUp.BackColor = System.Drawing.Color.Gray; + this.btnUp.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnUp.Image = ((System.Drawing.Image)(resources.GetObject("btnUp.Image"))); + this.btnUp.Location = new System.Drawing.Point(82, 102); + this.btnUp.Name = "btnUp"; + this.btnUp.Size = new System.Drawing.Size(64, 64); + this.btnUp.TabIndex = 13; + this.btnUp.UseVisualStyleBackColor = false; + this.btnUp.Click += new System.EventHandler(this.btnUp_Click); + // + // btnRight + // + this.btnRight.BackColor = System.Drawing.Color.Gray; + this.btnRight.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnRight.Image = ((System.Drawing.Image)(resources.GetObject("btnRight.Image"))); + this.btnRight.Location = new System.Drawing.Point(152, 172); + this.btnRight.Name = "btnRight"; + this.btnRight.Size = new System.Drawing.Size(64, 64); + this.btnRight.TabIndex = 17; + this.btnRight.UseVisualStyleBackColor = false; + this.btnRight.Click += new System.EventHandler(this.btnRight_Click); + // + // refreshTimer + // + this.refreshTimer.Interval = 1000; + this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick); + // + // cursorTimer + // + this.cursorTimer.Interval = 500; + this.cursorTimer.Tick += new System.EventHandler(this.cursorTimer_Tick); + // + // Vkt5ConsoleControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel1); + this.Controls.Add(this.btnMenu); + this.Controls.Add(this.btnBack); + this.Controls.Add(this.btnTab); + this.Controls.Add(this.btnLeft); + this.Controls.Add(this.btnEnter); + this.Controls.Add(this.btnDown); + this.Controls.Add(this.btnUp); + this.Controls.Add(this.btnRight); + this.Name = "Vkt5ConsoleControl"; + this.Size = new System.Drawing.Size(348, 257); + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label txtLine2; + private System.Windows.Forms.Label txtLine1; + private System.Windows.Forms.Button btnMenu; + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.Button btnTab; + private System.Windows.Forms.Button btnLeft; + private System.Windows.Forms.Button btnEnter; + private System.Windows.Forms.Button btnDown; + private System.Windows.Forms.Button btnUp; + private System.Windows.Forms.Button btnRight; + private System.Windows.Forms.Timer refreshTimer; + private System.Windows.Forms.Timer cursorTimer; + } +} diff --git a/VKT5_RemoteConsole/Vkt5ConsoleControl.cs b/VKT5_RemoteConsole/Vkt5ConsoleControl.cs new file mode 100644 index 0000000..efbaad5 --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5ConsoleControl.cs @@ -0,0 +1,382 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Drawing.Text; +using System.Runtime.InteropServices; +using Lers; +using Lers.Poll; + +namespace Vkt5_RemoteConsole +{ + /// + /// Делегат для события . + /// + public delegate void WriteLogEventHandler(Importance importance, string message); + + + /// + /// Контрол удалённого пульта ВКТ-5 + /// + public partial class Vkt5ConsoleControl : UserControl + { + /// + /// Состояния контрола + /// + private enum State + { + /// Начальное состояния + None, + + /// Отключены от прибора + Disconnected, + + /// Режим ожидания команд + Ready, + + /// Чтение буфера экрана + ReadingScreenBuffer, + + /// Отправка кода клавиши + SendingKeyCode, + + /// Ожидание обновления буфера экрана + WaitingScreenBuffer + } + + + #region События и методы для протоколирования + + public event WriteLogEventHandler WriteLog; + + private void LogMessage(string msg) + { + if (this.WriteLog != null) + { + this.WriteLog(Importance.Info, msg); + } + } + + private void LogWarning(string msg) + { + if (this.WriteLog != null) + { + this.WriteLog(Importance.Warn, msg); + } + } + + private void LogError(string msg) + { + if (this.WriteLog != null) + { + this.WriteLog(Importance.Error, msg); + } + } + + #endregion + + + /// + /// Конструктор + /// + public Vkt5ConsoleControl() + { + InitializeComponent(); + + SetState(State.Disconnected); + } + + /// + /// Инициализация контрола + /// + /// + /// + public void Initialize(RemoteConsole remoteConsole, int networkAddress) + { + this.vktConsole = new Vkt5Console(remoteConsole); + this.vktConsole.WriteLog += this.WriteLog; + this.vktConsole.RequestError += new EventHandler(vktConsole_RequestError); + this.vktConsole.NetworkAddress = networkAddress; + } + + /// + /// Изменилось состояние подключения к удалённому устройству + /// + /// + public void ConnectionChanged(bool connected) + { + if (connected) + { + SetState(State.WaitingScreenBuffer); + + this.vktConsole.Reset(); + + ReadScreenBuffer(); + } + else + { + SetState(State.Disconnected); + } + } + + + #region Обработчики событий контролов + + private void cursorTimer_Tick(object sender, EventArgs e) + { + this.displayCursor = !this.displayCursor; + + RefreshCursor(); + } + + /// + /// Таймер обновления содержимого экрана + /// + /// + /// + private void refreshTimer_Tick(object sender, EventArgs e) + { + ReadScreenBuffer(); + } + + void vktConsole_RequestError(object sender, EventArgs e) + { + // Отменяем чтение + SetState(State.Ready); + } + + private void btnUp_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Up); + } + + private void btnDown_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Down); + } + + private void btnTab_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Tab); + } + + private void btnBack_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Back); + } + + private void btnRight_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Right); + } + + private void btnLeft_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Left); + } + + private void btnEnter_Click(object sender, EventArgs e) + { + SendKeyCode(Vkt5Key.Enter); + } + + private void btnMenu_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) + { + if (!this.btnMenu.Enabled) + { + return; + } + + this.isMenuBtnDown = true; + this.menuBtnPressTime = DateTime.Now; + } + + private void btnMenu_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) + { + if (!this.btnMenu.Enabled) + { + return; + } + + if (this.isMenuBtnDown) + { + this.isMenuBtnDown = false; + DateTime now = DateTime.Now; + + int totalMs = (int)(now - this.menuBtnPressTime).TotalMilliseconds; + + if (totalMs >= 3000) + { + SendKeyCode(Vkt5Key.LongMenuPress); + } + else + { + SendKeyCode(Vkt5Key.Menu); + } + } + } + + #endregion + + + private void ReadScreenBuffer() + { + if (this.state == State.Ready || this.state == State.WaitingScreenBuffer) + { + SetState(State.ReadingScreenBuffer); + + this.vktConsole.ReadScreenBuffer(this.ReadScreenBufferCallback); + } + } + + + private void ReadScreenBufferCallback(byte[] data) + { + if (this.state != State.SendingKeyCode) + { + // Буфер экрана считан. Выставим состояние "Ready", если он пришёл не во время отправки кода клавиши. + + SetState(State.Ready); + } + + this.displayLine = Encoding.GetEncoding(866).GetString(data, 0, data.Length - 1); + this.cursorPos = data[data.Length - 1]; + + RefreshCursor(); + + if (!this.cursorTimer.Enabled) + { + this.cursorTimer.Start(); + } + + if (!this.refreshTimer.Enabled) + { + this.refreshTimer.Start(); + } + } + + private void SendKeyCode(Vkt5Key keyCode) + { + if (this.state == State.Disconnected || this.state == State.SendingKeyCode) + { + return; + } + + SetState(State.SendingKeyCode); + this.vktConsole.SendKeyCode(keyCode, SendKeyCodeCallback); + } + + private void SendKeyCodeCallback(byte[] data) + { + SetState(State.WaitingScreenBuffer); + + ReadScreenBuffer(); + } + + /// + /// Устанавливает новое состояние контрола + /// + /// + private void SetState(State newState) + { + if (newState == this.state) + { + return; + } + + + switch (newState) + { + case State.Ready: + SetReady(); + break; + + case State.Disconnected: + SetDisconnected(); + break; + + case State.SendingKeyCode: + case State.WaitingScreenBuffer: + EnableButtons(false); + break; + + case State.ReadingScreenBuffer: + break; + } + + + this.state = newState; + } + + private void SetReady() + { + EnableButtons(true); + } + + private void SetDisconnected() + { + this.cursorTimer.Stop(); + this.displayLine = ""; + this.cursorPos = 0; + } + + + + private void RefreshCursor() + { + if (string.IsNullOrEmpty(this.displayLine)) + { + return; + } + + string cursorChar = "\u2588"; + + string showLine = this.displayLine; + + if (this.displayCursor) + { + showLine = showLine.Remove(this.cursorPos, 1); + showLine = showLine.Insert(this.cursorPos, cursorChar); + } + + this.txtLine1.Text = showLine.Substring(0, 16); + this.txtLine2.Text = showLine.Substring(16, 16); + } + + private void EnableButtons(bool enable) + { + this.btnUp.Enabled = enable; + this.btnDown.Enabled = enable; + this.btnLeft.Enabled = enable; + this.btnRight.Enabled = enable; + this.btnEnter.Enabled = enable; + this.btnBack.Enabled = enable; + this.btnMenu.Enabled = enable; + this.btnTab.Enabled = enable; + } + + + + + /// + /// Объект для работы с подключенным ECL 300 + /// + private Vkt5Console vktConsole = null; + + /// + /// Текущее состояние контрола + /// + private State state = State.None; + + private string displayLine = ""; + private int cursorPos = 0; + private bool displayCursor = false; + + private bool isMenuBtnDown = false; + private DateTime menuBtnPressTime = DateTime.MinValue; + } +} diff --git a/VKT5_RemoteConsole/Vkt5ConsoleControl.resx b/VKT5_RemoteConsole/Vkt5ConsoleControl.resx new file mode 100644 index 0000000..0d08dd6 --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5ConsoleControl.resx @@ -0,0 +1,866 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + 3208vUqMAAAAAElFTkSuQmCC + + + + + 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 + 8P9abW3/DWbMf1iOz3IqAAAAAElFTkSuQmCC + + + + + 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 + SUVORK5CYII= + + + + + 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 + SUVORK5CYII= + + + + + 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 + + + + 17, 17 + + + 132, 16 + + \ No newline at end of file diff --git a/VKT5_RemoteConsole/Vkt5RemoteConsoleForm.cs b/VKT5_RemoteConsole/Vkt5RemoteConsoleForm.cs new file mode 100644 index 0000000..3969744 --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5RemoteConsoleForm.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Lers; +using Lers.UI.Tabs; + +namespace Vkt5_RemoteConsole +{ + class Vkt5RemoteConsoleForm: RemoteConsoleForm + { + /// + /// Конструктор + /// + public Vkt5RemoteConsoleForm() + { + this.Load += new EventHandler(Vkt5RemoteConsoleForm_Load); + + // Создаём контрол удалённого пульта и размещаем на пользовательской панели + this.vktConsoleControl = new Vkt5ConsoleControl(); + this.vktConsoleControl.Parent = this.UserArea; + this.vktConsoleControl.Dock = System.Windows.Forms.DockStyle.Fill; + + // Подписываемся на событие протоколирование контрола удалённого пульта. + // Каждый раз когда удалённый пульт будет протоколировать событие, будет вызываться этот метод. + this.vktConsoleControl.WriteLog += new WriteLogEventHandler(vktConsoleControl_WriteLog); + } + + + /// + /// Переопределяем инициализацию окна с удалённым пультом ВКТ-5 + /// + /// + /// + public override void Initialize(RemoteConsoleFormParams parameters, Lers.LersServer server) + { + base.Initialize(parameters, server); + + // Подписка на события подключения и отключения от удалённого устройства + + this.RemoteConsole.Connected += new EventHandler(RemoteConsole_Connected); + this.RemoteConsole.Disconnected += new EventHandler(RemoteConsole_Disconnected); + + int networkAddress = 0; + if (parameters.Device.PollSettings.Network != null) + { + Int32.TryParse(parameters.Device.NetworkAddress, out networkAddress); + } + + // Инициализируем контрол с удалённым пультом + this.vktConsoleControl.Initialize(this.RemoteConsole, networkAddress); + } + + + void vktConsoleControl_WriteLog(Importance importance, string message) + { + this.AddLogRecord(importance, DateTime.Now, message); + } + + void Vkt5RemoteConsoleForm_Load(object sender, EventArgs e) + { + this.vktConsoleControl.Enabled = false; + } + + void RemoteConsole_Connected(object sender, EventArgs e) + { + this.vktConsoleControl.Enabled = true; + this.vktConsoleControl.ConnectionChanged(true); + } + + void RemoteConsole_Disconnected(object sender, EventArgs e) + { + this.vktConsoleControl.Enabled = false; + this.vktConsoleControl.ConnectionChanged(false); + } + + + private Vkt5ConsoleControl vktConsoleControl = null; + } +} diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole.csproj b/VKT5_RemoteConsole/Vkt5_RemoteConsole.csproj new file mode 100644 index 0000000..20eb7f3 --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole.csproj @@ -0,0 +1,127 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8} + Library + Properties + Vkt5_RemoteConsole + Vkt5_RemoteConsole + v4.0 + 512 + + + true + full + false + C:\Program Files\LERS\Common\Plugins\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + + False + + + False + + + False + + + False + False + + + + + + + + + + + + UserControl + + + Vkt5ConsoleControl.cs + + + Form + + + + + True + True + Resources.resx + + + + + Vkt5ConsoleControl.cs + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole.sln b/VKT5_RemoteConsole/Vkt5_RemoteConsole.sln new file mode 100644 index 0000000..25e3d08 --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vkt5_RemoteConsole", "Vkt5_RemoteConsole.csproj", "{5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|x64.ActiveCfg = Debug|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|x86.ActiveCfg = Debug|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.Build.0 = Release|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|x64.ActiveCfg = Release|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.csproj b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.csproj new file mode 100644 index 0000000..8bdd364 --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.csproj @@ -0,0 +1,134 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8} + Library + Properties + Vkt5_RemoteConsole + Vkt5_RemoteConsole + v4.0 + 512 + + + true + full + false + C:\Program Files\LERS\Common\Plugins\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + + False + ..\..\Framework\Lers.Plugins\bin\Debug\Lers.Plugins.dll + False + + + False + ..\..\Framework\Lers.Plugins.Attributes\bin\Debug\Lers.Plugins.Attributes.dll + False + + + False + ..\..\Framework\Lers.System\bin\Debug\Lers.System.dll + False + + + False + ..\..\Framework\Lers.UI\bin\Debug\Lers.UI.dll + False + + + + + + + + + + + + UserControl + + + Vkt5ConsoleControl.cs + + + Form + + + + + True + True + Resources.resx + + + + + Vkt5ConsoleControl.cs + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.sln b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.sln new file mode 100644 index 0000000..8f6701d --- /dev/null +++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vkt5_RemoteConsole_debug", "Vkt5_RemoteConsole_debug.csproj", "{5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal