From 869dc25fb43af7bf231e83cc9aac94ffc1e51985 Mon Sep 17 00:00:00 2001 From: Alexander Babaev Date: Sat, 13 Nov 2021 15:39:16 +0300 Subject: [PATCH 01/51] 20211113 C#10 Update --- anbs_cp/CountFormatter.cs | 63 ++++---- anbs_cp/FileSizeFormatter.cs | 101 +++++++------ anbs_cp/IValueFormatter.cs | 131 ++++++++--------- anbs_cp/LikeDelphi.cs | 76 +++++----- anbs_cp/TypeConverter.cs | 217 ++++++++++++++-------------- anbs_cp/anbs_cp.csproj | 6 +- demo/CountValueTest.Designer.cs | 245 ++++++++++++++++---------------- demo/CountValueTest.cs | 60 ++++---- demo/Program.cs | 21 ++- 9 files changed, 448 insertions(+), 472 deletions(-) diff --git a/anbs_cp/CountFormatter.cs b/anbs_cp/CountFormatter.cs index 05bba3a..569e748 100644 --- a/anbs_cp/CountFormatter.cs +++ b/anbs_cp/CountFormatter.cs @@ -1,34 +1,33 @@ -namespace anbs_cp -{ - /// - /// Форматирует число элементов в понятную строку - /// - public class CountFormatter : IValueFormatter - { - #region Cвойства класса - /// - /// Имена чисел (тысяч, миллионов, миллиардов и т.п.) - /// - public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." }; - /// - /// Знаков после запятой - /// - public byte DecimalPlaces { get; set; } = 1; - /// - /// Делители чисел - /// - public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 }; - #endregion +namespace anbs_cp; - #region Реализация интерфейса - /// - /// Реализация интерфейса - /// - public string[] ValueNames { get => CountNames; set => CountNames = value; } - /// - /// Реализация интерфейса - /// - public long[] MaxSizes { get => Delimeters; set => Delimeters = value; } - #endregion - } +/// +/// Форматирует число элементов в понятную строку +/// +public class CountFormatter: IValueFormatter +{ + #region Cвойства класса + /// + /// Имена чисел (тысяч, миллионов, миллиардов и т.п.) + /// + public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." }; + /// + /// Знаков после запятой + /// + public byte DecimalPlaces { get; set; } = 1; + /// + /// Делители чисел + /// + public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 }; + #endregion + + #region Реализация интерфейса + /// + /// Реализация интерфейса + /// + public string[] ValueNames { get => CountNames; set => CountNames = value; } + /// + /// Реализация интерфейса + /// + public long[] MaxSizes { get => Delimeters; set => Delimeters = value; } + #endregion } \ No newline at end of file diff --git a/anbs_cp/FileSizeFormatter.cs b/anbs_cp/FileSizeFormatter.cs index a4cbd33..d7bc608 100644 --- a/anbs_cp/FileSizeFormatter.cs +++ b/anbs_cp/FileSizeFormatter.cs @@ -1,56 +1,55 @@ -namespace anbs_cp -{ - /// - /// Форматирует размер файла/папки в понятную строку - /// - public class FileSizeFormatter : IValueFormatter - { - #region Cвойства класса - /// - /// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт) - /// - public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" }; - /// - /// Знаков после запятой - /// - public byte DecimalPlaces { get; set; } = 2; - /// - /// Максимально байт (далее идут Кбайты) - /// - public long ByteMax { get; set; } = 1024; - /// - /// Максимально Кбайт (далее идут Мбайты) - /// - public long KByteMax { get; set; } = 1048576; - /// - /// Максимально Мбайт (далее идут Гбайты) - /// - public long MByteMax { get; set; } = 1073741824; - /// - /// Максимально Гбайт (далее идут Тбайты) - /// - public long GByteMax { get; set; } = 1099511627776; - #endregion +namespace anbs_cp; - #region Реализация интерфейса - /// - /// Реализация интерфейса - /// - public string[] ValueNames { get => SizeNames; set => SizeNames = value; } - /// - /// Реализация интерфейса - /// - public long[] MaxSizes +/// +/// Форматирует размер файла/папки в понятную строку +/// +public class FileSizeFormatter: IValueFormatter +{ + #region Cвойства класса + /// + /// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт) + /// + public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" }; + /// + /// Знаков после запятой + /// + public byte DecimalPlaces { get; set; } = 2; + /// + /// Максимально байт (далее идут Кбайты) + /// + public long ByteMax { get; set; } = 1024; + /// + /// Максимально Кбайт (далее идут Мбайты) + /// + public long KByteMax { get; set; } = 1048576; + /// + /// Максимально Мбайт (далее идут Гбайты) + /// + public long MByteMax { get; set; } = 1073741824; + /// + /// Максимально Гбайт (далее идут Тбайты) + /// + public long GByteMax { get; set; } = 1099511627776; + #endregion + + #region Реализация интерфейса + /// + /// Реализация интерфейса + /// + public string[] ValueNames { get => SizeNames; set => SizeNames = value; } + /// + /// Реализация интерфейса + /// + public long[] MaxSizes + { + get => new long[] { ByteMax, KByteMax, MByteMax, GByteMax }; + set { - get => new long[] { ByteMax, KByteMax, MByteMax, GByteMax }; - set - { - ByteMax = value[0]; - KByteMax = value[1]; - MByteMax = value[2]; - GByteMax = value[3]; - } + ByteMax = value[0]; + KByteMax = value[1]; + MByteMax = value[2]; + GByteMax = value[3]; } - #endregion } + #endregion } \ No newline at end of file diff --git a/anbs_cp/IValueFormatter.cs b/anbs_cp/IValueFormatter.cs index 36e0d3b..ec2cd98 100644 --- a/anbs_cp/IValueFormatter.cs +++ b/anbs_cp/IValueFormatter.cs @@ -1,82 +1,75 @@ -namespace anbs_cp +namespace anbs_cp; + +/// +/// Форматирует размерности в понятную строку +/// +public interface IValueFormatter { + + #region Определения интерфейса /// - /// Форматирует размерности в понятную строку + /// Имена размерностей /// - public interface IValueFormatter + public string[] ValueNames { get; set; } + /// + /// Знаков после запятой + /// + public byte DecimalPlaces { get; set; } + /// + /// Максимальные размеры (массив ulong[4]) + /// + public long[] MaxSizes { get; set; } + #endregion + + #region Методы интерфейса + /// + /// Форматирование размерности + /// + /// Размерность, требующая форматирования + /// Форматированная размерность (например, 20 Мб) + public string Format (long value) { + //Левая граница + long leftnum; + //Правая граница + long rightnum; - #region Определения интерфейса - /// - /// Имена размерностей - /// - public string[] ValueNames { get; set; } - /// - /// Знаков после запятой - /// - public byte DecimalPlaces { get; set; } - /// - /// Максимальные размеры (массив ulong[4]) - /// - public long[] MaxSizes { get; set; } - #endregion - - #region Методы интерфейса - /// - /// Форматирование размерности - /// - /// Размерность, требующая форматирования - /// Форматированная размерность (например, 20 Мб) - public string Format(long value) + for (int i = 0; i <= MaxSizes.Length; i++) { - //Левая граница - long leftnum; - //Правая граница - long rightnum; + leftnum = i == 0 ? 0 : MaxSizes[i - 1]; - for (int i = 0; i <= MaxSizes.Length; i++) - { - if (i == 0) - leftnum = 0; - else - leftnum = MaxSizes[i - 1]; + rightnum = i == MaxSizes.Length ? long.MaxValue : MaxSizes[i]; - if (i == MaxSizes.Length) - rightnum = long.MaxValue; - else - rightnum = MaxSizes[i]; + if ((value >= leftnum) && (value < rightnum)) + return $"{FormatValue(value, leftnum)} {ValueNames[i]}"; - if ((value >= leftnum) && (value < rightnum)) - return $"{FormatValue(value, leftnum)} {ValueNames[i]}"; - - } - - return value.ToString(); } - /// - /// Деление числа на число с DecimalPlaces знаками после запятой - /// - /// Делимое число - /// Число-делитель - /// Частное (с DecimalPlaces знаками после запятой) - private string FormatValue(long dividend, long divider) - { - if (divider == 0) - { - return $"{dividend}"; - } - long delim = 1; - - for (int i = 0; i <= DecimalPlaces; i++) - { - delim *= 10; - } - - decimal value = Math.Round((decimal)(dividend * delim / divider)) / delim; - - return $"{value}"; - } - #endregion + return value.ToString(); } + /// + /// Деление числа на число с DecimalPlaces знаками после запятой + /// + /// Делимое число + /// Число-делитель + /// Частное (с DecimalPlaces знаками после запятой) + private string FormatValue (long dividend, long divider) + { + if (divider == 0) + { + return $"{dividend}"; + } + + long delim = 1; + + for (int i = 0; i <= DecimalPlaces; i++) + { + delim *= 10; + } + + decimal value = Math.Round((decimal)(dividend * delim / divider)) / delim; + + return $"{value}"; + } + #endregion } \ No newline at end of file diff --git a/anbs_cp/LikeDelphi.cs b/anbs_cp/LikeDelphi.cs index bf6831d..59d694b 100644 --- a/anbs_cp/LikeDelphi.cs +++ b/anbs_cp/LikeDelphi.cs @@ -1,48 +1,46 @@ -using System.Collections.Generic; -namespace anbs_cp +namespace anbs_cp; + +/// +/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. +/// +public static class LikeDelphi { /// - /// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. + /// Аналог функции IncludeTrailingBackslash /// - public static class LikeDelphi + /// Путь, к которому нужно добавить slash + /// Путь со slash в конце + public static string IncludeTrailingBackslash (string path) { - /// - /// Аналог функции IncludeTrailingBackslash - /// - /// Путь, к которому нужно добавить slash - /// Путь со slash в конце - public static string IncludeTrailingBackslash(string path) + string result = path; + int Index = path.Length - 1; + if (path[Index] != '\\') { - string result = path; - int Index = path.Length - 1; - if (path[Index] != '\\') - { - result = $"{path}\\"; - } - return result; + result = $"{path}\\"; } - /// - /// Парсер строки в множество строк - /// - /// Строка, которую нужно разбить - /// Символ-делитель строки - /// Массив строк - public static List ParseString(string astring, char delim) + return result; + } + /// + /// Парсер строки в множество строк + /// + /// Строка, которую нужно разбить + /// Символ-делитель строки + /// Массив строк + public static List ParseString (string astring, char delim) + { + int from = -1; + int to; + List result = new(); + do { - int from = -1; - int to; - List result = new(); - do - { - from++; - to = astring.IndexOf(delim, from); - if (to <= 0) - to = astring.Length; - if (from != to) - result.Add(astring[from..(to-from)]); - from = to; - } while (to != astring.Length); - return result; - } + from++; + to = astring.IndexOf(delim, from); + if (to <= 0) + to = astring.Length; + if (from != to) + result.Add(astring[from..(to - from)]); + from = to; + } while (to != astring.Length); + return result; } } \ No newline at end of file diff --git a/anbs_cp/TypeConverter.cs b/anbs_cp/TypeConverter.cs index 3ab4951..5542364 100644 --- a/anbs_cp/TypeConverter.cs +++ b/anbs_cp/TypeConverter.cs @@ -1,114 +1,113 @@ -namespace anbs_cp -{ - /// - /// Конвертер типов на манер Delphi - /// - public static class TypeConverter - { - #region Конвертация числа в строку - /// - /// Преобразование int в string - /// - /// Число - /// Строка - public static string IntToStr(int AInt) => AInt.ToString(); - /// - /// Преобразование uint в string - /// - /// Число - /// Строка - public static string IntToStr(uint AInt) => AInt.ToString(); - /// - /// Преобразование long в string - /// - /// Число - /// Строка - public static string IntToStr(long AInt) => AInt.ToString(); - /// - /// Преобразование ulong в string - /// - /// Число - /// Строка - public static string IntToStr(ulong AInt) => AInt.ToString(); - /// - /// Преобразование byte в string - /// - /// Число - /// Строка - public static string IntToStr(byte AInt) => AInt.ToString(); - #endregion +namespace anbs_cp; - #region Конвертация строки в число - /// - /// Преобразование строки в число - /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static int StrToInt(string AStr, int ADefault = 0) +/// +/// Конвертер типов на манер Delphi +/// +public static class TypeConverter +{ + #region Конвертация числа в строку + /// + /// Преобразование int в string + /// + /// Число + /// Строка + public static string IntToStr (int AInt) => AInt.ToString(); + /// + /// Преобразование uint в string + /// + /// Число + /// Строка + public static string IntToStr (uint AInt) => AInt.ToString(); + /// + /// Преобразование long в string + /// + /// Число + /// Строка + public static string IntToStr (long AInt) => AInt.ToString(); + /// + /// Преобразование ulong в string + /// + /// Число + /// Строка + public static string IntToStr (ulong AInt) => AInt.ToString(); + /// + /// Преобразование byte в string + /// + /// Число + /// Строка + public static string IntToStr (byte AInt) => AInt.ToString(); + #endregion + + #region Конвертация строки в число + /// + /// Преобразование строки в число + /// + /// Строка + /// Значение по умолчанию (по умолчанию, 0) + /// Число + public static int StrToInt (string AStr, int ADefault = 0) + { + if (!int.TryParse(AStr, out int result)) { - if (!int.TryParse(AStr, out int result)) - { - result = ADefault; - } - return result; + result = ADefault; } - /// - /// Преобразование строки в число - /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static uint StrToUInt(string AStr, uint ADefault = 0) - { - if (!uint.TryParse(AStr, out uint result)) - { - result = ADefault; - } - return result; - } - /// - /// Преобразование строки в число - /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static long StrToInt64(string AStr, long ADefault = 0) - { - if (!long.TryParse(AStr, out long result)) - { - result = ADefault; - } - return result; - } - /// - /// Преобразование строки в число - /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static ulong StrToUInt64(string AStr, ulong ADefault = 0) - { - if (!ulong.TryParse(AStr, out ulong result)) - { - result = ADefault; - } - return result; - } - /// - /// Преобразование строки в число - /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static byte StrToByte(string AStr, byte ADefault = 0) - { - if (!byte.TryParse(AStr, out byte result)) - { - result = ADefault; - } - return result; - } - #endregion + return result; } + /// + /// Преобразование строки в число + /// + /// Строка + /// Значение по умолчанию (по умолчанию, 0) + /// Число + public static uint StrToUInt (string AStr, uint ADefault = 0) + { + if (!uint.TryParse(AStr, out uint result)) + { + result = ADefault; + } + return result; + } + /// + /// Преобразование строки в число + /// + /// Строка + /// Значение по умолчанию (по умолчанию, 0) + /// Число + public static long StrToInt64 (string AStr, long ADefault = 0) + { + if (!long.TryParse(AStr, out long result)) + { + result = ADefault; + } + return result; + } + /// + /// Преобразование строки в число + /// + /// Строка + /// Значение по умолчанию (по умолчанию, 0) + /// Число + public static ulong StrToUInt64 (string AStr, ulong ADefault = 0) + { + if (!ulong.TryParse(AStr, out ulong result)) + { + result = ADefault; + } + return result; + } + /// + /// Преобразование строки в число + /// + /// Строка + /// Значение по умолчанию (по умолчанию, 0) + /// Число + public static byte StrToByte (string AStr, byte ADefault = 0) + { + if (!byte.TryParse(AStr, out byte result)) + { + result = ADefault; + } + return result; + } + #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 8d583a6..919d18c 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.20211111.0 + 1.2021.1113 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ False https://github.com/GoodBoyAlex/anbsoftware_componentspack https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2021.1111 - 1.2021.1111 + 1.2021.1113 + 1.2021.1113 diff --git a/demo/CountValueTest.Designer.cs b/demo/CountValueTest.Designer.cs index 6656a3b..5b54914 100644 --- a/demo/CountValueTest.Designer.cs +++ b/demo/CountValueTest.Designer.cs @@ -1,134 +1,133 @@ -namespace demo +namespace demo; + +partial class CountValueTest { - partial class CountValueTest + /// + /// 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) { - /// - /// 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)) { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); + components.Dispose(); } + base.Dispose(disposing); + } - #region Windows Form Designer generated code + #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.InsertDataLabel = new System.Windows.Forms.Label(); - this.InsertDataBox = new System.Windows.Forms.TextBox(); - this.ResultLabel = new System.Windows.Forms.Label(); - this.CalculateButton = new System.Windows.Forms.Button(); - this.SelectFormatterLabel = new System.Windows.Forms.Label(); - this.SelectFormatterBox = new System.Windows.Forms.ComboBox(); - this.SuspendLayout(); - // - // InsertDataLabel - // - this.InsertDataLabel.AutoSize = true; - this.InsertDataLabel.Location = new System.Drawing.Point(12, 66); - this.InsertDataLabel.Name = "InsertDataLabel"; - this.InsertDataLabel.Size = new System.Drawing.Size(197, 17); - this.InsertDataLabel.TabIndex = 0; - this.InsertDataLabel.Text = "&Insert any int value:"; - // - // InsertDataBox - // - this.InsertDataBox.Location = new System.Drawing.Point(12, 86); - this.InsertDataBox.Name = "InsertDataBox"; - this.InsertDataBox.Size = new System.Drawing.Size(246, 24); - this.InsertDataBox.TabIndex = 1; - // - // ResultLabel - // - this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Bottom; - this.ResultLabel.Location = new System.Drawing.Point(0, 143); - this.ResultLabel.Margin = new System.Windows.Forms.Padding(5); - this.ResultLabel.Name = "ResultLabel"; - this.ResultLabel.Padding = new System.Windows.Forms.Padding(5); - this.ResultLabel.Size = new System.Drawing.Size(270, 79); - this.ResultLabel.TabIndex = 2; - this.ResultLabel.Text = "&Insert any int value to insert box above and press \"Calculate\" button to see res" + - "ult..."; - this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // CalculateButton - // - this.CalculateButton.Location = new System.Drawing.Point(81, 116); - this.CalculateButton.Name = "CalculateButton"; - this.CalculateButton.Size = new System.Drawing.Size(103, 23); - this.CalculateButton.TabIndex = 3; - this.CalculateButton.Text = "Calc&ulate"; - this.CalculateButton.UseVisualStyleBackColor = true; - this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click); - // - // SelectFormatterLabel - // - this.SelectFormatterLabel.AutoSize = true; - this.SelectFormatterLabel.Location = new System.Drawing.Point(12, 9); - this.SelectFormatterLabel.Name = "SelectFormatterLabel"; - this.SelectFormatterLabel.Size = new System.Drawing.Size(161, 17); - this.SelectFormatterLabel.TabIndex = 4; - this.SelectFormatterLabel.Text = "&Select formatter:"; - // - // SelectFormatterBox - // - this.SelectFormatterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.SelectFormatterBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.SelectFormatterBox.FormattingEnabled = true; - this.SelectFormatterBox.Items.AddRange(new object[] { + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + this.InsertDataLabel = new System.Windows.Forms.Label(); + this.InsertDataBox = new System.Windows.Forms.TextBox(); + this.ResultLabel = new System.Windows.Forms.Label(); + this.CalculateButton = new System.Windows.Forms.Button(); + this.SelectFormatterLabel = new System.Windows.Forms.Label(); + this.SelectFormatterBox = new System.Windows.Forms.ComboBox(); + this.SuspendLayout(); + // + // InsertDataLabel + // + this.InsertDataLabel.AutoSize = true; + this.InsertDataLabel.Location = new System.Drawing.Point(12, 66); + this.InsertDataLabel.Name = "InsertDataLabel"; + this.InsertDataLabel.Size = new System.Drawing.Size(197, 17); + this.InsertDataLabel.TabIndex = 0; + this.InsertDataLabel.Text = "&Insert any int value:"; + // + // InsertDataBox + // + this.InsertDataBox.Location = new System.Drawing.Point(12, 86); + this.InsertDataBox.Name = "InsertDataBox"; + this.InsertDataBox.Size = new System.Drawing.Size(246, 24); + this.InsertDataBox.TabIndex = 1; + // + // ResultLabel + // + this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.ResultLabel.Location = new System.Drawing.Point(0, 143); + this.ResultLabel.Margin = new System.Windows.Forms.Padding(5); + this.ResultLabel.Name = "ResultLabel"; + this.ResultLabel.Padding = new System.Windows.Forms.Padding(5); + this.ResultLabel.Size = new System.Drawing.Size(270, 79); + this.ResultLabel.TabIndex = 2; + this.ResultLabel.Text = "&Insert any int value to insert box above and press \"Calculate\" button to see res" + +"ult..."; + this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // CalculateButton + // + this.CalculateButton.Location = new System.Drawing.Point(81, 116); + this.CalculateButton.Name = "CalculateButton"; + this.CalculateButton.Size = new System.Drawing.Size(103, 23); + this.CalculateButton.TabIndex = 3; + this.CalculateButton.Text = "Calc&ulate"; + this.CalculateButton.UseVisualStyleBackColor = true; + this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click); + // + // SelectFormatterLabel + // + this.SelectFormatterLabel.AutoSize = true; + this.SelectFormatterLabel.Location = new System.Drawing.Point(12, 9); + this.SelectFormatterLabel.Name = "SelectFormatterLabel"; + this.SelectFormatterLabel.Size = new System.Drawing.Size(161, 17); + this.SelectFormatterLabel.TabIndex = 4; + this.SelectFormatterLabel.Text = "&Select formatter:"; + // + // SelectFormatterBox + // + this.SelectFormatterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.SelectFormatterBox.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.SelectFormatterBox.FormattingEnabled = true; + this.SelectFormatterBox.Items.AddRange(new object[] { "CountFormatter", "FileSizeFormatter"}); - this.SelectFormatterBox.Location = new System.Drawing.Point(12, 29); - this.SelectFormatterBox.Name = "SelectFormatterBox"; - this.SelectFormatterBox.Size = new System.Drawing.Size(246, 25); - this.SelectFormatterBox.TabIndex = 5; - // - // CountValueTest - // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(270, 222); - this.Controls.Add(this.SelectFormatterBox); - this.Controls.Add(this.SelectFormatterLabel); - this.Controls.Add(this.CalculateButton); - this.Controls.Add(this.ResultLabel); - this.Controls.Add(this.InsertDataBox); - this.Controls.Add(this.InsertDataLabel); - this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "CountValueTest"; - this.ShowIcon = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Formatter Test Unit"; - this.Load += new System.EventHandler(this.CountValueTest_Load); - this.ResumeLayout(false); - this.PerformLayout(); + this.SelectFormatterBox.Location = new System.Drawing.Point(12, 29); + this.SelectFormatterBox.Name = "SelectFormatterBox"; + this.SelectFormatterBox.Size = new System.Drawing.Size(246, 25); + this.SelectFormatterBox.TabIndex = 5; + // + // CountValueTest + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(270, 222); + this.Controls.Add(this.SelectFormatterBox); + this.Controls.Add(this.SelectFormatterLabel); + this.Controls.Add(this.CalculateButton); + this.Controls.Add(this.ResultLabel); + this.Controls.Add(this.InsertDataBox); + this.Controls.Add(this.InsertDataLabel); + this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CountValueTest"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Formatter Test Unit"; + this.Load += new System.EventHandler(this.CountValueTest_Load); + this.ResumeLayout(false); + this.PerformLayout(); - } - - #endregion - - private Label InsertDataLabel; - private TextBox InsertDataBox; - private Label ResultLabel; - private Button CalculateButton; - private Label SelectFormatterLabel; - private ComboBox SelectFormatterBox; } + + #endregion + + private Label InsertDataLabel; + private TextBox InsertDataBox; + private Label ResultLabel; + private Button CalculateButton; + private Label SelectFormatterLabel; + private ComboBox SelectFormatterBox; } \ No newline at end of file diff --git a/demo/CountValueTest.cs b/demo/CountValueTest.cs index defe9b7..e6ad7e5 100644 --- a/demo/CountValueTest.cs +++ b/demo/CountValueTest.cs @@ -1,42 +1,32 @@ using anbs_cp; -namespace demo + +namespace demo; + +public partial class CountValueTest: Form { - public partial class CountValueTest : Form + public CountValueTest () { - public CountValueTest() + InitializeComponent(); + } + + private void CalculateButton_Click (object sender, EventArgs e) + { + + if (string.IsNullOrEmpty(InsertDataBox.Text)) + return; + + long value = TypeConverter.StrToInt64(InsertDataBox.Text); + IValueFormatter formatter = SelectFormatterBox.SelectedIndex switch { - InitializeComponent(); - } + 0 => new CountFormatter(), + 1 => new FileSizeFormatter(), + _ => new CountFormatter(), + }; + ResultLabel.Text = formatter.Format(value); + } - private void CalculateButton_Click(object sender, EventArgs e) - { - - if (string.IsNullOrEmpty(InsertDataBox.Text)) - return; - - IValueFormatter formatter; - - long value = TypeConverter.StrToInt64(InsertDataBox.Text); - - switch (SelectFormatterBox.SelectedIndex) - { - case 0: - formatter = new CountFormatter(); - break; - case 1: - formatter = new FileSizeFormatter(); - break; - default: - formatter = new CountFormatter(); - break; - } - - ResultLabel.Text = formatter.Format(value); - } - - private void CountValueTest_Load(object sender, EventArgs e) - { - SelectFormatterBox.SelectedIndex = 0; - } + private void CountValueTest_Load (object sender, EventArgs e) + { + SelectFormatterBox.SelectedIndex = 0; } } \ No newline at end of file diff --git a/demo/Program.cs b/demo/Program.cs index 47c0157..bcf1871 100644 --- a/demo/Program.cs +++ b/demo/Program.cs @@ -1,15 +1,14 @@ -namespace demo +namespace demo; + +internal static class Program { - internal static class Program + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main () { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - ApplicationConfiguration.Initialize(); - Application.Run(new CountValueTest()); - } + ApplicationConfiguration.Initialize(); + Application.Run(new CountValueTest()); } } \ No newline at end of file From ac2909084d685e021268b3798a6754b0e4d87315 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Dec 2021 15:52:29 +0300 Subject: [PATCH 02/51] 20211215 --- anbs_cp/CountFormatter.cs | 37 +++++++++----- anbs_cp/FileSizeFormatter.cs | 40 +++++++++++----- anbs_cp/IValueFormatter.cs | 39 ++++++++------- anbs_cp/LikeDelphi.cs | 17 ++++--- anbs_cp/TimestampValidator.cs | 90 +++++++++++++++++++++++++++++++++++ anbs_cp/TypeConverter.cs | 79 +++++++++++++++--------------- 6 files changed, 208 insertions(+), 94 deletions(-) create mode 100644 anbs_cp/TimestampValidator.cs diff --git a/anbs_cp/CountFormatter.cs b/anbs_cp/CountFormatter.cs index 569e748..b152fd8 100644 --- a/anbs_cp/CountFormatter.cs +++ b/anbs_cp/CountFormatter.cs @@ -1,33 +1,48 @@ namespace anbs_cp; /// -/// Форматирует число элементов в понятную строку +/// Форматирует число элементов в понятную строку /// -public class CountFormatter: IValueFormatter +public sealed class CountFormatter : IValueFormatter { #region Cвойства класса + /// - /// Имена чисел (тысяч, миллионов, миллиардов и т.п.) + /// Имена чисел (тысяч, миллионов, миллиардов и т.п.) /// - public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." }; + public string[] CountNames { get; set; } = {"", "тыс.", "млн.", "млрд."}; + /// - /// Знаков после запятой + /// Знаков после запятой /// public byte DecimalPlaces { get; set; } = 1; + /// - /// Делители чисел + /// Делители чисел /// - public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 }; + public long[] Delimeters { get; set; } = {1000, 1000000, 1000000000}; + #endregion #region Реализация интерфейса + /// - /// Реализация интерфейса + /// Реализация интерфейса /// - public string[] ValueNames { get => CountNames; set => CountNames = value; } + public string[] ValueNames + { + get => CountNames; + set => CountNames = value; + } + /// - /// Реализация интерфейса + /// Реализация интерфейса /// - public long[] MaxSizes { get => Delimeters; set => Delimeters = value; } + public long[] MaxSizes + { + get => Delimeters; + set => Delimeters = value; + } + #endregion } \ No newline at end of file diff --git a/anbs_cp/FileSizeFormatter.cs b/anbs_cp/FileSizeFormatter.cs index d7bc608..b2f5efd 100644 --- a/anbs_cp/FileSizeFormatter.cs +++ b/anbs_cp/FileSizeFormatter.cs @@ -1,48 +1,61 @@ namespace anbs_cp; /// -/// Форматирует размер файла/папки в понятную строку +/// Форматирует размер файла/папки в понятную строку /// -public class FileSizeFormatter: IValueFormatter +public class FileSizeFormatter : IValueFormatter { #region Cвойства класса + /// - /// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт) + /// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт) /// - public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" }; + public string[] SizeNames { get; set; } = {"Байт", "Кб", "Мб", "Гб", "Тб"}; + /// - /// Знаков после запятой + /// Знаков после запятой /// public byte DecimalPlaces { get; set; } = 2; + /// - /// Максимально байт (далее идут Кбайты) + /// Максимально байт (далее идут Кбайты) /// public long ByteMax { get; set; } = 1024; + /// - /// Максимально Кбайт (далее идут Мбайты) + /// Максимально Кбайт (далее идут Мбайты) /// public long KByteMax { get; set; } = 1048576; + /// - /// Максимально Мбайт (далее идут Гбайты) + /// Максимально Мбайт (далее идут Гбайты) /// public long MByteMax { get; set; } = 1073741824; + /// - /// Максимально Гбайт (далее идут Тбайты) + /// Максимально Гбайт (далее идут Тбайты) /// public long GByteMax { get; set; } = 1099511627776; + #endregion #region Реализация интерфейса + /// - /// Реализация интерфейса + /// Реализация интерфейса /// - public string[] ValueNames { get => SizeNames; set => SizeNames = value; } + public string[] ValueNames + { + get => SizeNames; + set => SizeNames = value; + } + /// - /// Реализация интерфейса + /// Реализация интерфейса /// public long[] MaxSizes { - get => new long[] { ByteMax, KByteMax, MByteMax, GByteMax }; + get => new[] {ByteMax, KByteMax, MByteMax, GByteMax}; set { ByteMax = value[0]; @@ -51,5 +64,6 @@ public class FileSizeFormatter: IValueFormatter GByteMax = value[3]; } } + #endregion } \ No newline at end of file diff --git a/anbs_cp/IValueFormatter.cs b/anbs_cp/IValueFormatter.cs index ec2cd98..a58a225 100644 --- a/anbs_cp/IValueFormatter.cs +++ b/anbs_cp/IValueFormatter.cs @@ -1,33 +1,37 @@ namespace anbs_cp; /// -/// Форматирует размерности в понятную строку +/// Форматирует размерности в понятную строку /// public interface IValueFormatter { - #region Определения интерфейса + /// - /// Имена размерностей + /// Имена размерностей /// public string[] ValueNames { get; set; } + /// - /// Знаков после запятой + /// Знаков после запятой /// public byte DecimalPlaces { get; set; } + /// - /// Максимальные размеры (массив ulong[4]) + /// Максимальные размеры (массив ulong[4]) /// public long[] MaxSizes { get; set; } + #endregion #region Методы интерфейса + /// - /// Форматирование размерности + /// Форматирование размерности /// /// Размерность, требующая форматирования /// Форматированная размерность (например, 20 Мб) - public string Format (long value) + public string Format(long value) { //Левая граница long leftnum; @@ -40,36 +44,31 @@ public interface IValueFormatter rightnum = i == MaxSizes.Length ? long.MaxValue : MaxSizes[i]; - if ((value >= leftnum) && (value < rightnum)) + if (value >= leftnum && value < rightnum) return $"{FormatValue(value, leftnum)} {ValueNames[i]}"; - } return value.ToString(); } + /// - /// Деление числа на число с DecimalPlaces знаками после запятой + /// Деление числа на число с DecimalPlaces знаками после запятой /// /// Делимое число /// Число-делитель /// Частное (с DecimalPlaces знаками после запятой) - private string FormatValue (long dividend, long divider) + private string FormatValue(long dividend, long divider) { - if (divider == 0) - { - return $"{dividend}"; - } + if (divider == 0) return $"{dividend}"; long delim = 1; - for (int i = 0; i <= DecimalPlaces; i++) - { - delim *= 10; - } + for (int i = 0; i <= DecimalPlaces; i++) delim *= 10; - decimal value = Math.Round((decimal)(dividend * delim / divider)) / delim; + decimal value = Math.Round((decimal) (dividend * delim / divider)) / delim; return $"{value}"; } + #endregion } \ No newline at end of file diff --git a/anbs_cp/LikeDelphi.cs b/anbs_cp/LikeDelphi.cs index 59d694b..962b8fc 100644 --- a/anbs_cp/LikeDelphi.cs +++ b/anbs_cp/LikeDelphi.cs @@ -1,32 +1,30 @@ namespace anbs_cp; /// -/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. +/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. /// public static class LikeDelphi { /// - /// Аналог функции IncludeTrailingBackslash + /// Аналог функции IncludeTrailingBackslash /// /// Путь, к которому нужно добавить slash /// Путь со slash в конце - public static string IncludeTrailingBackslash (string path) + public static string IncludeTrailingBackslash(string path) { string result = path; int Index = path.Length - 1; - if (path[Index] != '\\') - { - result = $"{path}\\"; - } + if (path[Index] != '\\') result = $"{path}\\"; return result; } + /// - /// Парсер строки в множество строк + /// Парсер строки в множество строк /// /// Строка, которую нужно разбить /// Символ-делитель строки /// Массив строк - public static List ParseString (string astring, char delim) + public static List ParseString(string astring, char delim) { int from = -1; int to; @@ -41,6 +39,7 @@ public static class LikeDelphi result.Add(astring[from..(to - from)]); from = to; } while (to != astring.Length); + return result; } } \ No newline at end of file diff --git a/anbs_cp/TimestampValidator.cs b/anbs_cp/TimestampValidator.cs new file mode 100644 index 0000000..ebe29bd --- /dev/null +++ b/anbs_cp/TimestampValidator.cs @@ -0,0 +1,90 @@ +namespace anbs_cp; + +/// +/// Класс проверки временного интервала +/// +public static class TimestampValidator +{ + /// + /// Проверка попадания в заданный интервал (в мс) + /// + /// Временной интервал + /// Проверяемый временной интервал + /// Временная дельта в миллисекундах + /// + /// Попал ли в промежуток + + /// + /// + public static bool Validate(long timestamp, long checkedstamp, ulong deltams) => + new TimeSpan(timestamp) + TimeSpan.FromMilliseconds(deltams) > new TimeSpan(checkedstamp); + + /// + /// Проверка попадания текущего времени в заданный интервал (в мс) + /// + /// Временной интервал + /// Временная дельта в миллисекундах + /// Попадает ли текущее время в промежуток + + public static bool ValidateNow(long timestamp, ulong deltams) => + Validate(timestamp, DateTime.UtcNow.Ticks, deltams); + + /// + /// Проверка временного интервала (в сек) + /// + /// Временной интервал + /// Проверяемый временной интервал + /// Временная дельта в секундах + /// Попал ли в промежуток + public static bool ValidateFromSec(long timestamp, long checkedstamp, ulong deltasec) => + Validate(timestamp, checkedstamp, checked(deltasec * 1000UL)); + + /// + /// Проверка попадания текущего времени в заданный интервал (в сек) + /// + /// Временной интервал + /// Временная дельта в секундах + /// Попадает ли текущее время в промежуток + + public static bool ValidateFromSecNow(long timestamp, ulong deltasec) => + ValidateFromSec(timestamp, DateTime.UtcNow.Ticks, deltasec); + + /// + /// Проверка временного интервала (в мин) + /// + /// Временной интервал + /// Проверяемый временной интервал + /// Временная дельта в минутах + /// + /// Попал ли в промежуток + + /// + public static bool ValidateFromMin(long timestamp, long checkedstamp, ulong deltamin) => + Validate(timestamp, checkedstamp, checked(deltamin * 60000UL)); + + /// + /// Проверка попадания текущего времени в заданный интервал (в мин) + /// + /// Временной интервал + /// Временная дельта в минутах + /// Попадает ли текущее время в промежуток + + public static bool ValidateFromMinNow(long timestamp, ulong deltamin) => + ValidateFromMin(timestamp, DateTime.UtcNow.Ticks, deltamin); + + /// + /// Проверка временного интервала (в час) + /// + /// Временной интервал + /// Проверяемый временной интервал + /// Временная дельта в часах + /// + /// Попал ли в промежуток + + /// + public static bool ValidateFromHour(long timestamp, long checkedstamp, ulong deltahr) => + Validate(timestamp, checkedstamp, checked(deltahr * 3600000UL)); + + /// + /// Проверка попадания текущего времени в заданный интервал (в час) + /// + /// Временной интервал + /// Временная дельта в часах + /// Попадает ли текущее время в промежуток + + public static bool ValidateFromHourNow(long timestamp, ulong deltahr) => + ValidateFromHour(timestamp, DateTime.UtcNow.Ticks, deltahr); +} \ No newline at end of file diff --git a/anbs_cp/TypeConverter.cs b/anbs_cp/TypeConverter.cs index 5542364..c1205eb 100644 --- a/anbs_cp/TypeConverter.cs +++ b/anbs_cp/TypeConverter.cs @@ -1,113 +1,110 @@ namespace anbs_cp; /// -/// Конвертер типов на манер Delphi +/// Конвертер типов на манер Delphi /// public static class TypeConverter { #region Конвертация числа в строку + /// - /// Преобразование int в string + /// Преобразование int в string /// /// Число /// Строка - public static string IntToStr (int AInt) => AInt.ToString(); + public static string IntToStr(int AInt) => AInt.ToString(); + /// - /// Преобразование uint в string + /// Преобразование uint в string /// /// Число /// Строка - public static string IntToStr (uint AInt) => AInt.ToString(); + public static string IntToStr(uint AInt) => AInt.ToString(); + /// - /// Преобразование long в string + /// Преобразование long в string /// /// Число /// Строка - public static string IntToStr (long AInt) => AInt.ToString(); + public static string IntToStr(long AInt) => AInt.ToString(); + /// - /// Преобразование ulong в string + /// Преобразование ulong в string /// /// Число /// Строка - public static string IntToStr (ulong AInt) => AInt.ToString(); + public static string IntToStr(ulong AInt) => AInt.ToString(); + /// - /// Преобразование byte в string + /// Преобразование byte в string /// /// Число /// Строка - public static string IntToStr (byte AInt) => AInt.ToString(); + public static string IntToStr(byte AInt) => AInt.ToString(); + #endregion #region Конвертация строки в число + /// - /// Преобразование строки в число + /// Преобразование строки в число /// /// Строка /// Значение по умолчанию (по умолчанию, 0) /// Число - public static int StrToInt (string AStr, int ADefault = 0) + public static int StrToInt(string AStr, int ADefault = 0) { - if (!int.TryParse(AStr, out int result)) - { - result = ADefault; - } + if (!int.TryParse(AStr, out int result)) result = ADefault; return result; } + /// - /// Преобразование строки в число + /// Преобразование строки в число /// /// Строка /// Значение по умолчанию (по умолчанию, 0) /// Число - public static uint StrToUInt (string AStr, uint ADefault = 0) + public static uint StrToUInt(string AStr, uint ADefault = 0) { - if (!uint.TryParse(AStr, out uint result)) - { - result = ADefault; - } + if (!uint.TryParse(AStr, out uint result)) result = ADefault; return result; } + /// - /// Преобразование строки в число + /// Преобразование строки в число /// /// Строка /// Значение по умолчанию (по умолчанию, 0) /// Число - public static long StrToInt64 (string AStr, long ADefault = 0) + public static long StrToInt64(string AStr, long ADefault = 0) { - if (!long.TryParse(AStr, out long result)) - { - result = ADefault; - } + if (!long.TryParse(AStr, out long result)) result = ADefault; return result; } + /// - /// Преобразование строки в число + /// Преобразование строки в число /// /// Строка /// Значение по умолчанию (по умолчанию, 0) /// Число - public static ulong StrToUInt64 (string AStr, ulong ADefault = 0) + public static ulong StrToUInt64(string AStr, ulong ADefault = 0) { - if (!ulong.TryParse(AStr, out ulong result)) - { - result = ADefault; - } + if (!ulong.TryParse(AStr, out ulong result)) result = ADefault; return result; } + /// - /// Преобразование строки в число + /// Преобразование строки в число /// /// Строка /// Значение по умолчанию (по умолчанию, 0) /// Число - public static byte StrToByte (string AStr, byte ADefault = 0) + public static byte StrToByte(string AStr, byte ADefault = 0) { - if (!byte.TryParse(AStr, out byte result)) - { - result = ADefault; - } + if (!byte.TryParse(AStr, out byte result)) result = ADefault; return result; } + #endregion } \ No newline at end of file From 979ccd16b879b4be14676204fe5ef2bafa23d843 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Dec 2021 17:51:36 +0300 Subject: [PATCH 03/51] 20211215-1 --- anbs_cp/anbs_cp.csproj | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 919d18c..80aa38b 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.2021.1113 + 1.2021.1215 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,11 @@ False https://github.com/GoodBoyAlex/anbsoftware_componentspack https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2021.1113 - 1.2021.1113 + 1.2021.1215 + 1.2021.1215 + ANB.SoftwareComponentsPack + MIT + 6.0 From e08aeca7aaddb2bba60a434041e467a9eaebb4c4 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Dec 2021 18:02:49 +0300 Subject: [PATCH 04/51] 20211215-2 --- anbs_cp/anbs_cp.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 80aa38b..bb30827 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -17,7 +17,7 @@ https://github.com/GoodBoyAlex/anbsoftware_componentspack 1.2021.1215 1.2021.1215 - ANB.SoftwareComponentsPack + ANBSoftware.ComponentsPack MIT 6.0 From bff4cb735cdd140020ea292e7ae4140d114be2cf Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 23 Feb 2022 19:58:03 +0300 Subject: [PATCH 05/51] 20220223 --- anbs_cp/SimpleMapper.cs | 132 ++++++++++++++++++++++++++++++++++++++++ anbs_cp/anbs_cp.csproj | 8 +-- 2 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 anbs_cp/SimpleMapper.cs diff --git a/anbs_cp/SimpleMapper.cs b/anbs_cp/SimpleMapper.cs new file mode 100644 index 0000000..cf949ba --- /dev/null +++ b/anbs_cp/SimpleMapper.cs @@ -0,0 +1,132 @@ +using System.Reflection; + +namespace anbs_cp; + +/// +/// Класс перевода одинаковых свойств из класса TF в класс T. +/// Оригинальные автор(-ы): keenthinker и Avtandil Kavrelishvili. +/// Улучшения: А. Н. Бабаев +/// URL: https://stackoverflow.com/questions/20410234/how-to-automatically-map-the-values-between-instances-of-two-different-classes-i +/// +public static class SimpleMapper +{ + /// + /// Перевод одинаковых свойств из класса F в класс TT. + /// + /// Экземпляр класса F + /// Ссылка на экземпляр класса T + /// Тип сопоставления + /// Список параметров для сопоставления + /// Класс-родитель + /// Класс-приёмник + public static void MapEx (TF from, ref T to, MapMode mode, List list) + { + //Копирую поля + Type typeOfA = typeof(TF); + Type typeOfB = typeof(T); + foreach (FieldInfo fieldOfA in typeOfA.GetFields()) + { + //Проверяем выполнение условия и прерываем, если не выполняется + if (CheckCondition(fieldOfA.Name, fieldOfA.GetValue(from), mode, list)) + continue; + + //Получаем FieldInfo для b по имени поля a + FieldInfo? fieldOfB = typeOfB.GetField(fieldOfA.Name); + + //Присваиваю поля типа B значение поля типа A + fieldOfB?.SetValue(to, fieldOfA.GetValue(from)); + } + + //Копирую свойства + foreach (PropertyInfo propertyOfA in typeOfA.GetProperties()) + { + //Проверяем выполнение условия и прерываем, если не выполняется + if (CheckCondition(propertyOfA.Name, propertyOfA.GetValue(from), mode, list)) + continue; + + //Получаем PropertyInfo для b по имени свойства a + PropertyInfo? propertyOfB = typeOfB.GetProperty(propertyOfA.Name); + //Присваиваю свойству типа B значение свойства типа A + propertyOfB?.SetValue(to, propertyOfA.GetValue(from)); + } + } + + /// + /// Перевод одинаковых свойств из класса F в класс TT (режим "сопоставление всех параметров"). + /// + /// Параметр класса F + /// Класс-родитель + /// Класс-приёмник + /// Элемент класса T + public static T Map (TF from) + { + //Создаю элемент + // ReSharper disable once NullableWarningSuppressionIsUsed + T result = (T)Activator.CreateInstance(typeof(T))!; + //Сопоставляю по принципу "сопоставление всех параметров" + MapEx(from, ref result, MapMode.MapFull, new()); + //Вывожу в результат + return result; + } + + /// + /// Проверка выполнения условия + /// + /// Имя элемента + /// Значение элемента + /// Режим проверки + /// Список игнорирования/добавления + /// + private static bool CheckCondition (string itemName, object? itemValue, MapMode mode, ICollection list) + { + //Если режим "Только список" и поля нет в списке, + //либо режим "Только не в списке" и поле есть в списке + //или режим "Только не пустые" и значение поля пустое, + //или режим "Только не по умолчанию" и значение по умолчанию + //то пропускаем + bool result = + mode switch { + MapMode.MapFull => true, + MapMode.MapNotNull => itemValue != null, + MapMode.MapByList => list.Contains(itemName), + MapMode.MapIgnoreList => !list.Contains(itemName), + MapMode.MapNotDefault => itemValue != default, + MapMode.MapNotNullOrDefault => itemValue != null || itemValue != default, + _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null) + }; + + //Возвращаем результат + return result; + } + + /// + /// Перечисление типов сопоставления + /// + public enum MapMode + { + /// + /// Сопоставление всех параметров + /// + MapFull = 0, + /// + /// Сопоставление не пустых параметров + /// + MapNotNull = 1, + /// + /// Сопоставление по списку + /// + MapByList = 2, + /// + /// Сопоставление исключая список + /// + MapIgnoreList = 3, + /// + /// Сопоставление параметров, которые не равны значению по умолчанию + /// + MapNotDefault = 4, + /// + /// Сопоставление не пустых параметров, которые не равны значению по умолчанию (NotNull и NotDefault одновременно) + /// + MapNotNullOrDefault = 5, + } +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index bb30827..0e403bf 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.2021.1215 + 1.2022.223 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ False https://github.com/GoodBoyAlex/anbsoftware_componentspack https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2021.1215 - 1.2021.1215 + 1.2022.0223 + 1.2022.223 ANBSoftware.ComponentsPack MIT 6.0 @@ -33,7 +33,7 @@ - + From 87128879a575a8b00e6551bbc7b3fad7dbf9650f Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 25 Feb 2022 07:10:09 +0300 Subject: [PATCH 06/51] 20220225 --- anbs_cp/SimpleMapper.cs | 12 +- anbs_cp/anbs_cp.csproj | 6 +- demo/MainMenu.Designer.cs | 75 ++++++++++++ demo/MainMenu.cs | 30 +++++ demo/MainMenu.resx | 60 ++++++++++ demo/Program.cs | 2 +- demo/SampleMapperTest.Designer.cs | 189 ++++++++++++++++++++++++++++++ demo/SampleMapperTest.cs | 73 ++++++++++++ demo/SampleMapperTest.resx | 65 ++++++++++ demo/demo.csproj | 16 ++- demo/demo.csproj.DotSettings | 2 + 11 files changed, 519 insertions(+), 11 deletions(-) create mode 100644 demo/MainMenu.Designer.cs create mode 100644 demo/MainMenu.cs create mode 100644 demo/MainMenu.resx create mode 100644 demo/SampleMapperTest.Designer.cs create mode 100644 demo/SampleMapperTest.cs create mode 100644 demo/SampleMapperTest.resx create mode 100644 demo/demo.csproj.DotSettings diff --git a/anbs_cp/SimpleMapper.cs b/anbs_cp/SimpleMapper.cs index cf949ba..f6a19d5 100644 --- a/anbs_cp/SimpleMapper.cs +++ b/anbs_cp/SimpleMapper.cs @@ -18,7 +18,7 @@ public static class SimpleMapper /// Тип сопоставления /// Список параметров для сопоставления /// Класс-родитель - /// Класс-приёмник + /// Класс-приемник public static void MapEx (TF from, ref T to, MapMode mode, List list) { //Копирую поля @@ -27,7 +27,7 @@ public static class SimpleMapper foreach (FieldInfo fieldOfA in typeOfA.GetFields()) { //Проверяем выполнение условия и прерываем, если не выполняется - if (CheckCondition(fieldOfA.Name, fieldOfA.GetValue(from), mode, list)) + if (!CheckCondition(fieldOfA.Name, fieldOfA.GetValue(from), mode, list)) continue; //Получаем FieldInfo для b по имени поля a @@ -41,7 +41,7 @@ public static class SimpleMapper foreach (PropertyInfo propertyOfA in typeOfA.GetProperties()) { //Проверяем выполнение условия и прерываем, если не выполняется - if (CheckCondition(propertyOfA.Name, propertyOfA.GetValue(from), mode, list)) + if (!CheckCondition(propertyOfA.Name, propertyOfA.GetValue(from), mode, list)) continue; //Получаем PropertyInfo для b по имени свойства a @@ -56,7 +56,7 @@ public static class SimpleMapper /// /// Параметр класса F /// Класс-родитель - /// Класс-приёмник + /// Класс-приемник /// Элемент класса T public static T Map (TF from) { @@ -77,7 +77,7 @@ public static class SimpleMapper /// Режим проверки /// Список игнорирования/добавления /// - private static bool CheckCondition (string itemName, object? itemValue, MapMode mode, ICollection list) + private static bool CheckCondition (string itemName, object? itemValue, MapMode mode, ICollection list) { //Если режим "Только список" и поля нет в списке, //либо режим "Только не в списке" и поле есть в списке @@ -91,7 +91,7 @@ public static class SimpleMapper MapMode.MapByList => list.Contains(itemName), MapMode.MapIgnoreList => !list.Contains(itemName), MapMode.MapNotDefault => itemValue != default, - MapMode.MapNotNullOrDefault => itemValue != null || itemValue != default, + MapMode.MapNotNullOrDefault => !Equals(itemValue, default(T)), _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null) }; diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 0e403bf..5c3a4ed 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.2022.223 + 1.2022.225 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ False https://github.com/GoodBoyAlex/anbsoftware_componentspack https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2022.0223 - 1.2022.223 + 1.2022.0225 + 1.2022.225 ANBSoftware.ComponentsPack MIT 6.0 diff --git a/demo/MainMenu.Designer.cs b/demo/MainMenu.Designer.cs new file mode 100644 index 0000000..9f45d05 --- /dev/null +++ b/demo/MainMenu.Designer.cs @@ -0,0 +1,75 @@ +namespace demo; + +sealed partial class MainMenu +{ + /// + /// 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 Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + this.CountValueTest = new System.Windows.Forms.Button(); + this.SimpleMapperTest = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // CountValueTest + // + this.CountValueTest.Location = new System.Drawing.Point(12, 12); + this.CountValueTest.Name = "CountValueTest"; + this.CountValueTest.Size = new System.Drawing.Size(337, 53); + this.CountValueTest.TabIndex = 0; + this.CountValueTest.Text = "New CountValue Test"; + this.CountValueTest.UseVisualStyleBackColor = true; + this.CountValueTest.Click += new System.EventHandler(this.button1_Click); + // + // SimpleMapperTest + // + this.SimpleMapperTest.Location = new System.Drawing.Point(12, 71); + this.SimpleMapperTest.Name = "SimpleMapperTest"; + this.SimpleMapperTest.Size = new System.Drawing.Size(335, 51); + this.SimpleMapperTest.TabIndex = 1; + this.SimpleMapperTest.Text = "New SimpleMapper test"; + this.SimpleMapperTest.UseVisualStyleBackColor = true; + this.SimpleMapperTest.Click += new System.EventHandler(this.SimpleMapperTest_Click); + // + // MainMenu + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(361, 252); + this.Controls.Add(this.SimpleMapperTest); + this.Controls.Add(this.CountValueTest); + this.Font = new System.Drawing.Font("Times New Roman", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Margin = new System.Windows.Forms.Padding(4); + this.Name = "MainMenu"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Main menu"; + this.ResumeLayout(false); + + } + + #endregion + + private Button CountValueTest; + private Button SimpleMapperTest; +} diff --git a/demo/MainMenu.cs b/demo/MainMenu.cs new file mode 100644 index 0000000..1d5505b --- /dev/null +++ b/demo/MainMenu.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace demo; +public sealed partial class MainMenu: Form +{ + public MainMenu () + { + InitializeComponent(); + } + + private void button1_Click (object sender, EventArgs e) + { + CountValueTest formCountValueTest = new(); + formCountValueTest.ShowDialog(); + } + + private void SimpleMapperTest_Click (object sender, EventArgs e) + { + SampleMapperTest formSampleMapperTest = new(); + formSampleMapperTest.ShowDialog(); + } +} diff --git a/demo/MainMenu.resx b/demo/MainMenu.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/demo/MainMenu.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/demo/Program.cs b/demo/Program.cs index bcf1871..44dabc6 100644 --- a/demo/Program.cs +++ b/demo/Program.cs @@ -9,6 +9,6 @@ internal static class Program static void Main () { ApplicationConfiguration.Initialize(); - Application.Run(new CountValueTest()); + Application.Run(new MainMenu()); } } \ No newline at end of file diff --git a/demo/SampleMapperTest.Designer.cs b/demo/SampleMapperTest.Designer.cs new file mode 100644 index 0000000..f1cc47e --- /dev/null +++ b/demo/SampleMapperTest.Designer.cs @@ -0,0 +1,189 @@ +namespace demo; + +sealed partial class SampleMapperTest +{ + /// + /// 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 Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + this.DemoBoolEdt = new System.Windows.Forms.CheckBox(); + this.DemoStringEdt = new System.Windows.Forms.TextBox(); + this.DemoIntEdt = new System.Windows.Forms.NumericUpDown(); + this.DemoDateTimeEdt = new System.Windows.Forms.DateTimePicker(); + this.MapBtn = new System.Windows.Forms.Button(); + this.ResultArea = new System.Windows.Forms.TextBox(); + this.DemoStringLabel = new System.Windows.Forms.Label(); + this.DemoIntLabel = new System.Windows.Forms.Label(); + this.DemoDateTimeLabel = new System.Windows.Forms.Label(); + this.MapModeEdit = new System.Windows.Forms.ComboBox(); + this.MapModeLabel = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.DemoIntEdt)).BeginInit(); + this.SuspendLayout(); + // + // DemoBoolEdt + // + this.DemoBoolEdt.AutoSize = true; + this.DemoBoolEdt.Location = new System.Drawing.Point(32, 144); + this.DemoBoolEdt.Name = "DemoBoolEdt"; + this.DemoBoolEdt.Size = new System.Drawing.Size(65, 25); + this.DemoBoolEdt.TabIndex = 0; + this.DemoBoolEdt.Text = "Bool"; + this.DemoBoolEdt.UseVisualStyleBackColor = true; + // + // DemoStringEdt + // + this.DemoStringEdt.Location = new System.Drawing.Point(32, 42); + this.DemoStringEdt.Name = "DemoStringEdt"; + this.DemoStringEdt.Size = new System.Drawing.Size(737, 29); + this.DemoStringEdt.TabIndex = 1; + // + // DemoIntEdt + // + this.DemoIntEdt.Location = new System.Drawing.Point(32, 109); + this.DemoIntEdt.Name = "DemoIntEdt"; + this.DemoIntEdt.Size = new System.Drawing.Size(737, 29); + this.DemoIntEdt.TabIndex = 2; + // + // DemoDateTimeEdt + // + this.DemoDateTimeEdt.CustomFormat = "dd.MM.yyyy HH:mm:ss"; + this.DemoDateTimeEdt.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.DemoDateTimeEdt.Location = new System.Drawing.Point(32, 193); + this.DemoDateTimeEdt.Name = "DemoDateTimeEdt"; + this.DemoDateTimeEdt.Size = new System.Drawing.Size(737, 29); + this.DemoDateTimeEdt.TabIndex = 3; + // + // MapBtn + // + this.MapBtn.Location = new System.Drawing.Point(32, 306); + this.MapBtn.Name = "MapBtn"; + this.MapBtn.Size = new System.Drawing.Size(737, 57); + this.MapBtn.TabIndex = 5; + this.MapBtn.Text = "MAP"; + this.MapBtn.UseVisualStyleBackColor = true; + this.MapBtn.Click += new System.EventHandler(this.MapBtn_Click); + // + // ResultArea + // + this.ResultArea.Dock = System.Windows.Forms.DockStyle.Right; + this.ResultArea.Location = new System.Drawing.Point(811, 0); + this.ResultArea.Multiline = true; + this.ResultArea.Name = "ResultArea"; + this.ResultArea.ReadOnly = true; + this.ResultArea.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.ResultArea.Size = new System.Drawing.Size(332, 378); + this.ResultArea.TabIndex = 6; + // + // DemoStringLabel + // + this.DemoStringLabel.AutoSize = true; + this.DemoStringLabel.Location = new System.Drawing.Point(32, 18); + this.DemoStringLabel.Name = "DemoStringLabel"; + this.DemoStringLabel.Size = new System.Drawing.Size(54, 21); + this.DemoStringLabel.TabIndex = 7; + this.DemoStringLabel.Text = "String"; + // + // DemoIntLabel + // + this.DemoIntLabel.AutoSize = true; + this.DemoIntLabel.Location = new System.Drawing.Point(32, 85); + this.DemoIntLabel.Name = "DemoIntLabel"; + this.DemoIntLabel.Size = new System.Drawing.Size(30, 21); + this.DemoIntLabel.TabIndex = 8; + this.DemoIntLabel.Text = "Int"; + // + // DemoDateTimeLabel + // + this.DemoDateTimeLabel.AutoSize = true; + this.DemoDateTimeLabel.Location = new System.Drawing.Point(32, 169); + this.DemoDateTimeLabel.Name = "DemoDateTimeLabel"; + this.DemoDateTimeLabel.Size = new System.Drawing.Size(81, 21); + this.DemoDateTimeLabel.TabIndex = 9; + this.DemoDateTimeLabel.Text = "DateTime"; + // + // MapModeEdit + // + this.MapModeEdit.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.MapModeEdit.FormattingEnabled = true; + this.MapModeEdit.Items.AddRange(new object[] { + "Full", + "Not null", + "Not default", + "Not null or default"}); + this.MapModeEdit.Location = new System.Drawing.Point(32, 254); + this.MapModeEdit.Name = "MapModeEdit"; + this.MapModeEdit.Size = new System.Drawing.Size(737, 29); + this.MapModeEdit.TabIndex = 10; + // + // MapModeLabel + // + this.MapModeLabel.AutoSize = true; + this.MapModeLabel.Location = new System.Drawing.Point(32, 230); + this.MapModeLabel.Name = "MapModeLabel"; + this.MapModeLabel.Size = new System.Drawing.Size(91, 21); + this.MapModeLabel.TabIndex = 11; + this.MapModeLabel.Text = "Map mode"; + // + // SampleMapperTest + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1143, 378); + this.Controls.Add(this.MapModeLabel); + this.Controls.Add(this.MapModeEdit); + this.Controls.Add(this.DemoDateTimeLabel); + this.Controls.Add(this.DemoIntLabel); + this.Controls.Add(this.DemoStringLabel); + this.Controls.Add(this.ResultArea); + this.Controls.Add(this.MapBtn); + this.Controls.Add(this.DemoDateTimeEdt); + this.Controls.Add(this.DemoIntEdt); + this.Controls.Add(this.DemoStringEdt); + this.Controls.Add(this.DemoBoolEdt); + this.Font = new System.Drawing.Font("Times New Roman", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Margin = new System.Windows.Forms.Padding(4); + this.Name = "SampleMapperTest"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "SampleMapper test"; + ((System.ComponentModel.ISupportInitialize)(this.DemoIntEdt)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private CheckBox DemoBoolEdt; + private TextBox DemoStringEdt; + private NumericUpDown DemoIntEdt; + private DateTimePicker DemoDateTimeEdt; + private Button MapBtn; + private TextBox ResultArea; + private Label DemoStringLabel; + private Label DemoIntLabel; + private Label DemoDateTimeLabel; + private ComboBox MapModeEdit; + private Label MapModeLabel; +} diff --git a/demo/SampleMapperTest.cs b/demo/SampleMapperTest.cs new file mode 100644 index 0000000..361f998 --- /dev/null +++ b/demo/SampleMapperTest.cs @@ -0,0 +1,73 @@ +using anbs_cp; + +using Newtonsoft.Json; + +namespace demo; +public sealed partial class SampleMapperTest: Form +{ + public SampleMapperTest () + { + InitializeComponent(); + } + + private void MapBtn_Click (object sender, EventArgs e) + { + Demo1Class demo1 = new() + { + DemoString = DemoStringEdt.Text, + DemoInt = (int)DemoIntEdt.Value, + DemoBool = DemoBoolEdt.Checked, + DemoDateTime = DemoDateTimeEdt.Value + }; + + Demo1Class demo2 = new() + { + DemoInt = 20220224, + DemoBool = true, + DemoDateTime = default + }; + + string serialize1 = JsonConvert.SerializeObject(demo2); + + SimpleMapper.MapMode mode = MapModeEdit.SelectedIndex switch + { + 0 => SimpleMapper.MapMode.MapFull, + 1 => SimpleMapper.MapMode.MapNotNull, + 2 => SimpleMapper.MapMode.MapNotDefault, + 3 => SimpleMapper.MapMode.MapNotNullOrDefault, + _ => SimpleMapper.MapMode.MapFull + }; + + SimpleMapper.MapEx(demo1, ref demo2, mode, new List()); + + string serialize2 = JsonConvert.SerializeObject(demo2); + + ResultArea.Text = $@"Demo2 Class before map: + {serialize1} + and after:{serialize2}"; + } +} + +public sealed class Demo1Class +{ + public string? DemoString { get; set; } + + public int DemoInt { get; set; } + + public bool DemoBool { get; set; } + + public DateTime DemoDateTime { get; set; } +} + +public class Demo2Class +{ + public string? DemoString { get; set; } + + public int DemoInt { get; set; } + + public bool DemoBool { get; set; } + + public DateTime DemoDateTime { get; set; } + + public string? DemoStringNotMapped { get; set; } +} \ No newline at end of file diff --git a/demo/SampleMapperTest.resx b/demo/SampleMapperTest.resx new file mode 100644 index 0000000..65463ee --- /dev/null +++ b/demo/SampleMapperTest.resx @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + Demo2 Class before map: +{0} +and after:{1} + + \ No newline at end of file diff --git a/demo/demo.csproj b/demo/demo.csproj index 10977d6..37355f4 100644 --- a/demo/demo.csproj +++ b/demo/demo.csproj @@ -2,13 +2,27 @@ WinExe - net6.0-windows + net6.0-windows10.0.22000.0 enable true enable Release;Debug.CNF + 7.0 + + + True + + + + True + + + + + + diff --git a/demo/demo.csproj.DotSettings b/demo/demo.csproj.DotSettings new file mode 100644 index 0000000..4887f94 --- /dev/null +++ b/demo/demo.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp100 \ No newline at end of file From 1a45750f271e9ae9e055af27ef36086ccfa0f6cb Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 23 Jul 2022 12:36:44 +0300 Subject: [PATCH 07/51] 20220723 --- anbs_cp/LikeDelphi.cs | 40 ++++++++-------------- anbs_cp/anbs_cp.csproj | 6 ++-- anbsoftware.componentspack.sln.DotSettings | 4 +++ 3 files changed, 21 insertions(+), 29 deletions(-) create mode 100644 anbsoftware.componentspack.sln.DotSettings diff --git a/anbs_cp/LikeDelphi.cs b/anbs_cp/LikeDelphi.cs index 962b8fc..07fcfe0 100644 --- a/anbs_cp/LikeDelphi.cs +++ b/anbs_cp/LikeDelphi.cs @@ -1,45 +1,33 @@ namespace anbs_cp; /// -/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. +/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. /// public static class LikeDelphi { /// - /// Аналог функции IncludeTrailingBackslash + /// Аналог функции IncludeTrailingBackslash /// /// Путь, к которому нужно добавить slash /// Путь со slash в конце - public static string IncludeTrailingBackslash(string path) + public static string IncludeTrailingBackslash (string path) { + //По умолчанию сохраняем путь string result = path; - int Index = path.Length - 1; - if (path[Index] != '\\') result = $"{path}\\"; + + //Если последний символ не "\", то добавим "\" в конце + if (path[^1] != '\\') + result = $@"{path}\"; + + //Вернём результат return result; } /// - /// Парсер строки в множество строк + /// Парсер строки в множество строк /// - /// Строка, которую нужно разбить - /// Символ-делитель строки + /// Строка, которую нужно разбить + /// Символ-делитель строки /// Массив строк - public static List ParseString(string astring, char delim) - { - int from = -1; - int to; - List result = new(); - do - { - from++; - to = astring.IndexOf(delim, from); - if (to <= 0) - to = astring.Length; - if (from != to) - result.Add(astring[from..(to - from)]); - from = to; - } while (to != astring.Length); - - return result; - } + public static List ParseString (string str, char delimiter) => str.Split (delimiter).ToList(); } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 5c3a4ed..58b5ff9 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.2022.225 + 1.2022.723 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ False https://github.com/GoodBoyAlex/anbsoftware_componentspack https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2022.0225 - 1.2022.225 + 1.2022.723 + 1.2022.723 ANBSoftware.ComponentsPack MIT 6.0 diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings new file mode 100644 index 0000000..acbae49 --- /dev/null +++ b/anbsoftware.componentspack.sln.DotSettings @@ -0,0 +1,4 @@ + + True + True + True \ No newline at end of file From 5872049cc7bac2e9d58d57518ce93a6cd4e65dcf Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 28 Oct 2022 10:02:17 +0300 Subject: [PATCH 08/51] 20221028 --- anbs_cp/TypeConverter.cs | 29 +++++++++++++++++++++- anbs_cp/anbs_cp.csproj | 11 ++++---- anbsoftware.componentspack.sln.DotSettings | 3 ++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/anbs_cp/TypeConverter.cs b/anbs_cp/TypeConverter.cs index c1205eb..2f988e7 100644 --- a/anbs_cp/TypeConverter.cs +++ b/anbs_cp/TypeConverter.cs @@ -1,4 +1,7 @@ -namespace anbs_cp; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Html; + +namespace anbs_cp; /// /// Конвертер типов на манер Delphi @@ -107,4 +110,28 @@ public static class TypeConverter } #endregion + + #region Конвернтация IHtmlContent + /// + /// Преобразует тип в строку . + /// + /// Значение, которое нужно преобразовать. + /// + public static string HtmlContentToString (IHtmlContent content) + { + //Создаём writer + using StringWriter writer = new(); + //Конвертируем IHtmlContent в string + content.WriteTo(writer, HtmlEncoder.Default); + //Возвращаем результат + return writer.ToString(); + } + + /// + /// Преобразует строку в тип . + /// + /// Значение, которое нужно преобразовать. + /// + public static IHtmlContent StringToHtmlContent(string content) => new HtmlContentBuilder().AppendHtml(content); + #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 58b5ff9..95deaa4 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.2022.723 + 1.2022.1028 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -13,10 +13,10 @@ enable True False - https://github.com/GoodBoyAlex/anbsoftware_componentspack - https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2022.723 - 1.2022.723 + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + 1.2022.1028 + 1.2022.1028 ANBSoftware.ComponentsPack MIT 6.0 @@ -33,6 +33,7 @@ + diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index acbae49..5d94243 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -1,4 +1,5 @@  True True - True \ No newline at end of file + True + True \ No newline at end of file From f0acfce2f3466a0d3c25e265c0ed610cecc2676d Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 30 Nov 2022 13:36:29 +0300 Subject: [PATCH 09/51] 20221130 --- anbs_cp/Classes/ActionError.cs | 63 +++++ anbs_cp/Classes/ActionInfo.cs | 49 ++++ anbs_cp/Classes/ActionState.cs | 299 ++++++++++++++++++++ anbs_cp/Classes/ActionWarning.cs | 49 ++++ anbs_cp/{ => Classes}/CountFormatter.cs | 6 +- anbs_cp/{ => Classes}/FileSizeFormatter.cs | 6 +- anbs_cp/{ => Classes}/IValueFormatter.cs | 4 +- anbs_cp/{ => Classes}/LikeDelphi.cs | 6 +- anbs_cp/{ => Classes}/SimpleMapper.cs | 11 +- anbs_cp/{ => Classes}/TimestampValidator.cs | 14 +- anbs_cp/{ => Classes}/TypeConverter.cs | 4 +- anbs_cp/Interfaces/IActionError.cs | 14 + anbs_cp/Interfaces/IActionInfo.cs | 12 + anbs_cp/Interfaces/IActionStateMessage.cs | 24 ++ anbs_cp/Interfaces/IActionWarning.cs | 12 + anbs_cp/anbs_cp.csproj | 18 +- anbs_cp/anbs_cp.csproj.DotSettings | 2 + demo/CountValueTest.Designer.cs | 2 +- demo/CountValueTest.cs | 4 +- demo/MainMenu.cs | 12 +- demo/SampleMapperTest.Designer.cs | 4 +- demo/SampleMapperTest.cs | 3 +- demo/SampleMapperTest.resx | 5 - demo/demo.csproj | 7 +- 24 files changed, 570 insertions(+), 60 deletions(-) create mode 100644 anbs_cp/Classes/ActionError.cs create mode 100644 anbs_cp/Classes/ActionInfo.cs create mode 100644 anbs_cp/Classes/ActionState.cs create mode 100644 anbs_cp/Classes/ActionWarning.cs rename anbs_cp/{ => Classes}/CountFormatter.cs (84%) rename anbs_cp/{ => Classes}/FileSizeFormatter.cs (90%) rename anbs_cp/{ => Classes}/IValueFormatter.cs (95%) rename anbs_cp/{ => Classes}/LikeDelphi.cs (85%) rename anbs_cp/{ => Classes}/SimpleMapper.cs (95%) rename anbs_cp/{ => Classes}/TimestampValidator.cs (93%) rename anbs_cp/{ => Classes}/TypeConverter.cs (98%) create mode 100644 anbs_cp/Interfaces/IActionError.cs create mode 100644 anbs_cp/Interfaces/IActionInfo.cs create mode 100644 anbs_cp/Interfaces/IActionStateMessage.cs create mode 100644 anbs_cp/Interfaces/IActionWarning.cs create mode 100644 anbs_cp/anbs_cp.csproj.DotSettings diff --git a/anbs_cp/Classes/ActionError.cs b/anbs_cp/Classes/ActionError.cs new file mode 100644 index 0000000..fd6906e --- /dev/null +++ b/anbs_cp/Classes/ActionError.cs @@ -0,0 +1,63 @@ +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; + +/// +/// Класс ошибки +/// +public sealed class ActionError: IActionError +{ + /// + /// Критичность ошибки: + /// при некритичных ошибках продолжение выполнения операции возможно, + /// а при критичных -- нет + /// + public bool IsCritical { get; init; } + + /// + /// Объект ошибки + /// + public object Object { get; set; } + + /// + /// Сообщение об ошибке + /// + public string Message { get; set; } + + #region Конструкторы + /// + /// Конструктор по умолчанию + /// + public ActionError () + { + IsCritical = true; + Object = "Not Implemented"; + Message = "Not Implemented"; + } + + /// + /// Конструктор с 2 параметрами + /// + /// Сообщение + /// Критичность ошибки + public ActionError (string message, bool isCritical = true) + { + IsCritical = isCritical; + Object = ""; + Message = message; + } + + /// + /// Конструктор с 3 параметрами + /// + /// Объект ошибки + /// Сообщение + /// Критичность ошибки + public ActionError (object eObject, string message, bool isCritical = true) + { + IsCritical = isCritical; + Object = eObject; + Message = message; + } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Classes/ActionInfo.cs b/anbs_cp/Classes/ActionInfo.cs new file mode 100644 index 0000000..e2acadf --- /dev/null +++ b/anbs_cp/Classes/ActionInfo.cs @@ -0,0 +1,49 @@ +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; + +/// +/// Класс предупреждения +/// +public sealed class ActionInfo: IActionInfo +{ + #region Конструкторы + /// + /// Конструктор по умолчанию + /// + public ActionInfo () + { + IsStatusInfo = false; + Object = string.Empty; + Message = string.Empty; + } + + /// + /// Конструктор + /// + /// Объект + /// Сообщение + /// Является статусной информацией? + public ActionInfo (string eObject, string message, bool isStatus = false) + { + IsStatusInfo = isStatus; + Object = eObject; + Message = message; + } + #endregion + + #region Реализация интерфейса + /// + /// Объект + /// + public object Object { get; set; } + /// + /// Сообщение + /// + public string Message { get; set; } + /// + /// Статусная информация (например, начало работы) + /// + public bool IsStatusInfo { get; init; } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Classes/ActionState.cs b/anbs_cp/Classes/ActionState.cs new file mode 100644 index 0000000..f8b5401 --- /dev/null +++ b/anbs_cp/Classes/ActionState.cs @@ -0,0 +1,299 @@ +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; + +/// +/// Состояние действия +/// +public sealed class ActionState +{ + /// + /// Конструктор + /// + public ActionState () + { + Info = new(); + Warnings = new(); + Errors = new(); + } + + /// + /// Список информации + /// + public List Info { get; } + + /// + /// Список предупреждений + /// + public List Warnings { get; } + + /// + /// Список ошибок + /// + public List Errors { get; } + + #region Методы + + #region Очистка + /// + /// Очищает список ошибок + /// + public void ClearErrors () + { + Errors.Clear(); + Errors.TrimExcess(); + } + + /// + /// Очищает список предупреждений + /// + public void ClearWarnings () + { + Warnings.Clear(); + Warnings.TrimExcess(); + } + + /// + /// Очищает список информации + /// + public void ClearInfo () + { + Info.Clear(); + Info.TrimExcess(); + } + + /// + /// Очищает все списки + /// + public void Clear () + { + ClearInfo(); + ClearWarnings(); + ClearErrors(); + } + #endregion + + #region Добавление ошибки + /// + /// Добавление ошибки + /// + /// Ошибка + // ReSharper disable once MemberCanBeMadeStatic.Global + // ReSharper disable once FunctionRecursiveOnAllPaths + public void AddError (IActionError error) => AddError(error); + + /// + /// Добавляет ошибки в список + /// + /// Список ошибок + public void AddErrors(IEnumerable errors) => Errors.AddRange(errors); + + /// + /// Добавление ошибки + /// + /// Является ли ошибка критической + public void AddError (bool critical = true) + { + //Создаю ошибку + ActionError error = new("", critical); + + //Добавляю ошибку + AddError(error); + } + + /// + /// Добавление ошибки + /// + /// Сообщение об ошибке + /// Является ли ошибка критической + public void AddError (string message, bool critical = true) + { + //Создаю ошибку + ActionError error = new(message, critical); + + //Добавляю ошибку + AddError(error); + } + + /// + /// Добавление ошибки + /// + /// Объект ошибки + /// Сообщение об ошибке + /// /// Является ли ошибка критической + public void AddError (string errorObject, string message, bool critical = true) + { + //Создаю ошибку + ActionError error = new(errorObject, message, critical); + + //Добавляю ошибку + AddError(error); + } + #endregion + + #region Добавление предупреждения + /// + /// Добавление предупреждения + /// + /// Предупреждение + public void AddWarning (IActionWarning warning) => Warnings.Add(warning); + + /// + /// Добавление предупреждений + /// + /// Список предупреждений + public void AddWarnings(IEnumerable warnings) => Warnings.AddRange(warnings); + + /// + /// Добавление предупреждение + /// + /// Текст предупреждения + /// Объект предупреждения + public void AddWarning (string message, string warningObject = "") + { + //Создаю предупреждение + ActionWarning warning = new(warningObject, message); + + //Добавляю предупреждение + AddWarning(warning); + } + #endregion + + #region Добавление информации + /// + /// Добавление информации + /// + /// Информация + public void AddInfo (IActionInfo info) => Info.Add(info); + + /// + /// Добавление информации + /// + /// Список информации + public void AddInfos (IEnumerable infos) => Info.AddRange(infos); + + /// + /// Добавление информации + /// + /// Текст информации + /// Объект информации + public void AddInfo (string message, string warningObject = "") + { + //Создаю информацию + ActionInfo info = new(warningObject, message); + + //Добавляю информацию + AddInfo(info); + } + #endregion + + #region Печать + /// + /// Печать списка ошибок + /// + /// Формат списка + /// Формат элемента списка + /// Список ошибок в текстовой форме + public string PrintErrorList (string formatList, string formatItem) + { + string elements = +#pragma warning disable CS8625 + Errors.Aggregate(null, (current, error) => current + error.PrintMessage(formatItem)); +#pragma warning restore CS8625 + + return string.Format(formatList, elements); + } + + /// + /// Печать списка предупреждений + /// + /// Формат списка + /// Формат элемента списка + /// Список предупреждений в текстовой форме + public string PrintWarningList (string formatList, string formatItem) + { + string elements = +#pragma warning disable CS8625 + Warnings.Aggregate(null, +#pragma warning restore CS8625 + (current, warning) => current + warning.PrintMessage(formatItem)); + + return string.Format(formatList, elements); + } + + /// + /// Печать списка информации + /// + /// Формат списка + /// Формат элемента списка + /// Список информации в текстовой форме + public string PrintInfoList (string formatList, string formatItem) + { + string elements = +#pragma warning disable CS8625 + Info.Aggregate(null, (current, info) => current + info.PrintMessage(formatItem)); +#pragma warning restore CS8625 + + return string.Format(formatList, elements); + } + #endregion + + #region Проверка на наличие + /// + /// Проверяет, есть ли ошибки + /// + /// Игнорировать не критические + /// Наличие ошибок + public bool HasErrors (bool ignoreNonCritical = false) => + ignoreNonCritical ? Errors.Any(static error => error.IsCritical) : Errors.Any(); + + /// + /// Проверяет, есть ли предупреждения + /// + /// Игнорировать информационные предупреждения + /// Наличие предупреждений + public bool HasWarnings (bool ignoreInformWarning = false) => ignoreInformWarning + ? Warnings.Any(static warning => !warning.IsInformWarning) + : Warnings.Any(); + + /// + /// Проверяет, есть ли сообщения + /// + /// Игнорировать статусные сообщения + /// Наличие сообщений + public bool HasInfo (bool ignoreStatus) => ignoreStatus ? Info.Any(static info => !info.IsStatusInfo) : Info.Any(); + + /// + /// Успешно ли завершилось + /// + public bool IsSuccess (bool ignoreNonCriticalErrors = false) => + !HasErrors(ignoreNonCriticalErrors) && !HasWarnings(true); + #endregion + + #region Количество сообщений + /// + /// Количество ошибок + /// + /// Игнорировать не критические + /// Количество ошибок + public int ErrorsCount (bool ignoreNonCritical = false) => + ignoreNonCritical ? Errors.Count(static error => error.IsCritical) : Errors.Count; + + /// + /// Количество предупреждений + /// + /// Игнорировать информационные предупреждения + /// Количество предупреждений + public int WarningsCount (bool ignoreInformWarning = false) => ignoreInformWarning + ? Warnings.Count(static warning => !warning.IsInformWarning) + : Warnings.Count; + + /// + /// Количество информационных сообщений + /// + /// Игнорировать статусные сообщения + /// Количество информационных сообщений + public int InfoCount (bool ignoreStatus) => ignoreStatus ? Info.Count(static info => !info.IsStatusInfo) : Info.Count; + #endregion + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Classes/ActionWarning.cs b/anbs_cp/Classes/ActionWarning.cs new file mode 100644 index 0000000..e25a6c7 --- /dev/null +++ b/anbs_cp/Classes/ActionWarning.cs @@ -0,0 +1,49 @@ +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; + +/// +/// Класс предупреждения +/// +public sealed class ActionWarning: IActionWarning +{ + #region Конструкторы + /// + /// Конструктор по умолчанию + /// + public ActionWarning () + { + IsInformWarning = false; + Object = string.Empty; + Message = string.Empty; + } + + /// + /// Конструктор + /// + /// Объект + /// Сообщение + /// Является ли информирующим предупреждением + public ActionWarning (string eObject, string message, bool isInform = false) + { + IsInformWarning = isInform; + Object = eObject; + Message = message; + } + #endregion + + #region Реализация интерфейса + /// + /// Объект + /// + public object Object { get; set; } + /// + /// Сообщение + /// + public string Message { get; set; } + /// + /// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию. + /// + public bool IsInformWarning { get; init; } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/CountFormatter.cs b/anbs_cp/Classes/CountFormatter.cs similarity index 84% rename from anbs_cp/CountFormatter.cs rename to anbs_cp/Classes/CountFormatter.cs index b152fd8..c908651 100644 --- a/anbs_cp/CountFormatter.cs +++ b/anbs_cp/Classes/CountFormatter.cs @@ -1,4 +1,4 @@ -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Форматирует число элементов в понятную строку @@ -10,7 +10,7 @@ public sealed class CountFormatter : IValueFormatter /// /// Имена чисел (тысяч, миллионов, миллиардов и т.п.) /// - public string[] CountNames { get; set; } = {"", "тыс.", "млн.", "млрд."}; + public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." }; /// /// Знаков после запятой @@ -20,7 +20,7 @@ public sealed class CountFormatter : IValueFormatter /// /// Делители чисел /// - public long[] Delimeters { get; set; } = {1000, 1000000, 1000000000}; + public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 }; #endregion diff --git a/anbs_cp/FileSizeFormatter.cs b/anbs_cp/Classes/FileSizeFormatter.cs similarity index 90% rename from anbs_cp/FileSizeFormatter.cs rename to anbs_cp/Classes/FileSizeFormatter.cs index b2f5efd..1cae56d 100644 --- a/anbs_cp/FileSizeFormatter.cs +++ b/anbs_cp/Classes/FileSizeFormatter.cs @@ -1,4 +1,4 @@ -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Форматирует размер файла/папки в понятную строку @@ -10,7 +10,7 @@ public class FileSizeFormatter : IValueFormatter /// /// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт) /// - public string[] SizeNames { get; set; } = {"Байт", "Кб", "Мб", "Гб", "Тб"}; + public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" }; /// /// Знаков после запятой @@ -55,7 +55,7 @@ public class FileSizeFormatter : IValueFormatter /// public long[] MaxSizes { - get => new[] {ByteMax, KByteMax, MByteMax, GByteMax}; + get => new[] { ByteMax, KByteMax, MByteMax, GByteMax }; set { ByteMax = value[0]; diff --git a/anbs_cp/IValueFormatter.cs b/anbs_cp/Classes/IValueFormatter.cs similarity index 95% rename from anbs_cp/IValueFormatter.cs rename to anbs_cp/Classes/IValueFormatter.cs index a58a225..eb1f2bd 100644 --- a/anbs_cp/IValueFormatter.cs +++ b/anbs_cp/Classes/IValueFormatter.cs @@ -1,4 +1,4 @@ -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Форматирует размерности в понятную строку @@ -65,7 +65,7 @@ public interface IValueFormatter for (int i = 0; i <= DecimalPlaces; i++) delim *= 10; - decimal value = Math.Round((decimal) (dividend * delim / divider)) / delim; + decimal value = Math.Round((decimal)(dividend * delim / divider)) / delim; return $"{value}"; } diff --git a/anbs_cp/LikeDelphi.cs b/anbs_cp/Classes/LikeDelphi.cs similarity index 85% rename from anbs_cp/LikeDelphi.cs rename to anbs_cp/Classes/LikeDelphi.cs index 07fcfe0..9776f1a 100644 --- a/anbs_cp/LikeDelphi.cs +++ b/anbs_cp/Classes/LikeDelphi.cs @@ -1,4 +1,4 @@ -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. @@ -10,7 +10,7 @@ public static class LikeDelphi /// /// Путь, к которому нужно добавить slash /// Путь со slash в конце - public static string IncludeTrailingBackslash (string path) + public static string IncludeTrailingBackslash(string path) { //По умолчанию сохраняем путь string result = path; @@ -29,5 +29,5 @@ public static class LikeDelphi /// Строка, которую нужно разбить /// Символ-делитель строки /// Массив строк - public static List ParseString (string str, char delimiter) => str.Split (delimiter).ToList(); + public static List ParseString(string str, char delimiter) => str.Split(delimiter).ToList(); } \ No newline at end of file diff --git a/anbs_cp/SimpleMapper.cs b/anbs_cp/Classes/SimpleMapper.cs similarity index 95% rename from anbs_cp/SimpleMapper.cs rename to anbs_cp/Classes/SimpleMapper.cs index f6a19d5..6195d0f 100644 --- a/anbs_cp/SimpleMapper.cs +++ b/anbs_cp/Classes/SimpleMapper.cs @@ -1,6 +1,6 @@ using System.Reflection; -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Класс перевода одинаковых свойств из класса TF в класс T. @@ -19,7 +19,7 @@ public static class SimpleMapper /// Список параметров для сопоставления /// Класс-родитель /// Класс-приемник - public static void MapEx (TF from, ref T to, MapMode mode, List list) + public static void MapEx(TF from, ref T to, MapMode mode, List list) { //Копирую поля Type typeOfA = typeof(TF); @@ -58,7 +58,7 @@ public static class SimpleMapper /// Класс-родитель /// Класс-приемник /// Элемент класса T - public static T Map (TF from) + public static T Map(TF from) { //Создаю элемент // ReSharper disable once NullableWarningSuppressionIsUsed @@ -77,7 +77,7 @@ public static class SimpleMapper /// Режим проверки /// Список игнорирования/добавления /// - private static bool CheckCondition (string itemName, object? itemValue, MapMode mode, ICollection list) + private static bool CheckCondition(string itemName, object? itemValue, MapMode mode, ICollection list) { //Если режим "Только список" и поля нет в списке, //либо режим "Только не в списке" и поле есть в списке @@ -85,7 +85,8 @@ public static class SimpleMapper //или режим "Только не по умолчанию" и значение по умолчанию //то пропускаем bool result = - mode switch { + mode switch + { MapMode.MapFull => true, MapMode.MapNotNull => itemValue != null, MapMode.MapByList => list.Contains(itemName), diff --git a/anbs_cp/TimestampValidator.cs b/anbs_cp/Classes/TimestampValidator.cs similarity index 93% rename from anbs_cp/TimestampValidator.cs rename to anbs_cp/Classes/TimestampValidator.cs index ebe29bd..910c325 100644 --- a/anbs_cp/TimestampValidator.cs +++ b/anbs_cp/Classes/TimestampValidator.cs @@ -1,4 +1,4 @@ -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Класс проверки временного интервала @@ -9,14 +9,14 @@ public static class TimestampValidator /// Проверка попадания в заданный интервал (в мс) /// /// Временной интервал - /// Проверяемый временной интервал - /// Временная дельта в миллисекундах + /// Проверяемый временной интервал + /// Временная дельта в миллисекундах /// - /// Попал ли в промежуток + - /// + /// Попал ли в промежуток + + /// /// - public static bool Validate(long timestamp, long checkedstamp, ulong deltams) => - new TimeSpan(timestamp) + TimeSpan.FromMilliseconds(deltams) > new TimeSpan(checkedstamp); + public static bool Validate(long timestamp, long checkedStamp, ulong deltaMs) => + new TimeSpan(timestamp) + TimeSpan.FromMilliseconds(deltaMs) > new TimeSpan(checkedStamp); /// /// Проверка попадания текущего времени в заданный интервал (в мс) diff --git a/anbs_cp/TypeConverter.cs b/anbs_cp/Classes/TypeConverter.cs similarity index 98% rename from anbs_cp/TypeConverter.cs rename to anbs_cp/Classes/TypeConverter.cs index 2f988e7..6139a0f 100644 --- a/anbs_cp/TypeConverter.cs +++ b/anbs_cp/Classes/TypeConverter.cs @@ -1,7 +1,7 @@ using System.Text.Encodings.Web; using Microsoft.AspNetCore.Html; -namespace anbs_cp; +namespace anbs_cp.Classes; /// /// Конвертер типов на манер Delphi @@ -117,7 +117,7 @@ public static class TypeConverter /// /// Значение, которое нужно преобразовать. /// - public static string HtmlContentToString (IHtmlContent content) + public static string HtmlContentToString(IHtmlContent content) { //Создаём writer using StringWriter writer = new(); diff --git a/anbs_cp/Interfaces/IActionError.cs b/anbs_cp/Interfaces/IActionError.cs new file mode 100644 index 0000000..38cf7bb --- /dev/null +++ b/anbs_cp/Interfaces/IActionError.cs @@ -0,0 +1,14 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс ошибки +/// +public interface IActionError : IActionStateMessage +{ + /// + /// Критичность ошибки: + /// при некритичных ошибках продолжение выполнения операции возможно, + /// а при критичных -- нет + /// + public bool IsCritical { get; init; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IActionInfo.cs b/anbs_cp/Interfaces/IActionInfo.cs new file mode 100644 index 0000000..c48f47c --- /dev/null +++ b/anbs_cp/Interfaces/IActionInfo.cs @@ -0,0 +1,12 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс для информации по статусу +/// +public interface IActionInfo : IActionStateMessage +{ + /// + /// Статусная информация (например, начало работы) + /// + public bool IsStatusInfo { get; init; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IActionStateMessage.cs b/anbs_cp/Interfaces/IActionStateMessage.cs new file mode 100644 index 0000000..e6af12b --- /dev/null +++ b/anbs_cp/Interfaces/IActionStateMessage.cs @@ -0,0 +1,24 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс сообщения состояния +/// +public interface IActionStateMessage +{ + /// + /// Объект сообщения + /// + public object Object { get; set; } + + /// + /// Текст сообщения + /// + public string Message { get; set; } + + /// + /// Функция вывода сообщения + /// + /// Строка-форматирование (например, «[{0}] - {1}») + /// Отформатированную строка + public string PrintMessage (string format) => string.Format (format, Object, Message); +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IActionWarning.cs b/anbs_cp/Interfaces/IActionWarning.cs new file mode 100644 index 0000000..23ec4cc --- /dev/null +++ b/anbs_cp/Interfaces/IActionWarning.cs @@ -0,0 +1,12 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс предупреждения +/// +public interface IActionWarning : IActionStateMessage +{ + /// + /// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию. + /// + public bool IsInformWarning { get; init; } +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 95deaa4..3400fff 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -1,8 +1,8 @@ - net6.0 - 1.2022.1028 + net7.0 + 1.2022.1130 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -12,29 +12,31 @@ enable enable True - False + True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 1.2022.1028 - 1.2022.1028 + 1.2022.1130 + 1.2022.1130 ANBSoftware.ComponentsPack MIT 6.0 + git + True - 2 + 7 True - 2 + 7 True - + diff --git a/anbs_cp/anbs_cp.csproj.DotSettings b/anbs_cp/anbs_cp.csproj.DotSettings new file mode 100644 index 0000000..16c7a3d --- /dev/null +++ b/anbs_cp/anbs_cp.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp110 \ No newline at end of file diff --git a/demo/CountValueTest.Designer.cs b/demo/CountValueTest.Designer.cs index 5b54914..19fd306 100644 --- a/demo/CountValueTest.Designer.cs +++ b/demo/CountValueTest.Designer.cs @@ -1,6 +1,6 @@ namespace demo; -partial class CountValueTest +sealed partial class CountValueTest { /// /// Required designer variable. diff --git a/demo/CountValueTest.cs b/demo/CountValueTest.cs index e6ad7e5..413373c 100644 --- a/demo/CountValueTest.cs +++ b/demo/CountValueTest.cs @@ -1,8 +1,8 @@ -using anbs_cp; +using anbs_cp.Classes; namespace demo; -public partial class CountValueTest: Form +public sealed partial class CountValueTest: Form { public CountValueTest () { diff --git a/demo/MainMenu.cs b/demo/MainMenu.cs index 1d5505b..cf9b2af 100644 --- a/demo/MainMenu.cs +++ b/demo/MainMenu.cs @@ -1,14 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace demo; +namespace demo; public sealed partial class MainMenu: Form { public MainMenu () diff --git a/demo/SampleMapperTest.Designer.cs b/demo/SampleMapperTest.Designer.cs index f1cc47e..8e5fc9f 100644 --- a/demo/SampleMapperTest.Designer.cs +++ b/demo/SampleMapperTest.Designer.cs @@ -88,7 +88,7 @@ sealed partial class SampleMapperTest // ResultArea // this.ResultArea.Dock = System.Windows.Forms.DockStyle.Right; - this.ResultArea.Location = new System.Drawing.Point(811, 0); + this.ResultArea.Location = new System.Drawing.Point(819, 0); this.ResultArea.Multiline = true; this.ResultArea.Name = "ResultArea"; this.ResultArea.ReadOnly = true; @@ -150,7 +150,7 @@ sealed partial class SampleMapperTest // this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1143, 378); + this.ClientSize = new System.Drawing.Size(1151, 378); this.Controls.Add(this.MapModeLabel); this.Controls.Add(this.MapModeEdit); this.Controls.Add(this.DemoDateTimeLabel); diff --git a/demo/SampleMapperTest.cs b/demo/SampleMapperTest.cs index 361f998..cab7845 100644 --- a/demo/SampleMapperTest.cs +++ b/demo/SampleMapperTest.cs @@ -1,5 +1,4 @@ -using anbs_cp; - +using anbs_cp.Classes; using Newtonsoft.Json; namespace demo; diff --git a/demo/SampleMapperTest.resx b/demo/SampleMapperTest.resx index 65463ee..f298a7b 100644 --- a/demo/SampleMapperTest.resx +++ b/demo/SampleMapperTest.resx @@ -57,9 +57,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Demo2 Class before map: -{0} -and after:{1} - \ No newline at end of file diff --git a/demo/demo.csproj b/demo/demo.csproj index 37355f4..ac4ebca 100644 --- a/demo/demo.csproj +++ b/demo/demo.csproj @@ -2,13 +2,12 @@ WinExe - net6.0-windows10.0.22000.0 + net7.0-windows enable true enable Release;Debug.CNF - 7.0 - + demo.Program @@ -20,7 +19,7 @@ - + From f844787c265f44a789d45cbb01a7d5779afe519f Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 3 Dec 2022 14:04:02 +0300 Subject: [PATCH 10/51] 20221203 --- anbs_cp/Classes/FileExtensions.cs | 71 ++++++++ anbs_cp/anbs_cp.csproj | 10 +- anbsoftware.componentspack.sln.DotSettings | 5 +- demo/CountValueTest.Designer.cs | 183 +++++++++++---------- demo/CountValueTest.cs | 8 + demo/FileHashAndMimeTypeTest.Designer.cs | 125 ++++++++++++++ demo/FileHashAndMimeTypeTest.cs | 42 +++++ demo/FileHashAndMimeTypeTest.resx | 63 +++++++ demo/MainMenu.Designer.cs | 20 ++- demo/MainMenu.cs | 6 + demo/SampleMapperTest.Designer.cs | 8 +- demo/SampleMapperTest.cs | 5 +- demo/demo.csproj | 6 + 13 files changed, 447 insertions(+), 105 deletions(-) create mode 100644 anbs_cp/Classes/FileExtensions.cs create mode 100644 demo/FileHashAndMimeTypeTest.Designer.cs create mode 100644 demo/FileHashAndMimeTypeTest.cs create mode 100644 demo/FileHashAndMimeTypeTest.resx diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs new file mode 100644 index 0000000..7dee49b --- /dev/null +++ b/anbs_cp/Classes/FileExtensions.cs @@ -0,0 +1,71 @@ +using System.Security.Cryptography; + +using Microsoft.AspNetCore.Http; + +using MimeKit; + +namespace anbs_cp.Classes; + +/// +/// Класс -- расширение для класса File +/// +public static class FileExtension +{ + /// + /// Получение md5-хэша файла. + /// Взято с https://stackoverflow.com/a/24031467/16469671 + /// + /// Имя файла + /// Массив хэша + public static byte[] Hash (string fileName) + { + using MD5 md5 = MD5.Create(); + byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(fileName); + byte[] result = md5.ComputeHash(inputBytes); + + return result; + } + + /// + /// Получение md5-хэша загружаемого файла. + /// Взято с https://stackoverflow.com/a/67081012/16469671 + /// + /// Загружаемый файл + /// Массив хэша + public static byte[] Hash (IFormFile file) + { + using MD5 md5 = MD5.Create(); + using StreamReader streamReader = new(file.OpenReadStream()); + return md5.ComputeHash(streamReader.BaseStream); + } + + /// + /// Получение md5-хэша файла и вывод в строке. + /// + /// Имя файла + /// Срока с хэшем файла + public static string HashString (string fileName) => Convert.ToHexString(Hash(fileName)); + + /// + /// Получение md5-хэша файла и вывод в строке. + /// + /// Загружаемый файл + /// Срока с хэшем файла + public static string HashString (IFormFile file) => Convert.ToHexString(Hash(file)); + + /// + /// Получает MIME-тип файла + /// + /// Имя файла + /// MIME-тип файла + public static string MIMEType (string filename) => + MimeTypes.GetMimeType(filename); + + /// + /// Получает MIME-тип файла + /// + /// Загружаемый файл + /// MIME-тип файла + public static string MIMEType (IFormFile file) => + file.ContentType; +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 3400fff..b3ae293 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 1.2022.1130 + 2022.1203.1 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 1.2022.1130 - 1.2022.1130 + 2022.1203.1 + 2022.1203.1 ANBSoftware.ComponentsPack MIT 6.0 @@ -27,16 +27,20 @@ 7 True + none 7 True + none + + diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 5d94243..68f48c1 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -2,4 +2,7 @@ True True True - True \ No newline at end of file + True + True + True + True \ No newline at end of file diff --git a/demo/CountValueTest.Designer.cs b/demo/CountValueTest.Designer.cs index 19fd306..aef3ab5 100644 --- a/demo/CountValueTest.Designer.cs +++ b/demo/CountValueTest.Designer.cs @@ -28,97 +28,98 @@ sealed partial class CountValueTest /// private void InitializeComponent () { - this.InsertDataLabel = new System.Windows.Forms.Label(); - this.InsertDataBox = new System.Windows.Forms.TextBox(); - this.ResultLabel = new System.Windows.Forms.Label(); - this.CalculateButton = new System.Windows.Forms.Button(); - this.SelectFormatterLabel = new System.Windows.Forms.Label(); - this.SelectFormatterBox = new System.Windows.Forms.ComboBox(); - this.SuspendLayout(); - // - // InsertDataLabel - // - this.InsertDataLabel.AutoSize = true; - this.InsertDataLabel.Location = new System.Drawing.Point(12, 66); - this.InsertDataLabel.Name = "InsertDataLabel"; - this.InsertDataLabel.Size = new System.Drawing.Size(197, 17); - this.InsertDataLabel.TabIndex = 0; - this.InsertDataLabel.Text = "&Insert any int value:"; - // - // InsertDataBox - // - this.InsertDataBox.Location = new System.Drawing.Point(12, 86); - this.InsertDataBox.Name = "InsertDataBox"; - this.InsertDataBox.Size = new System.Drawing.Size(246, 24); - this.InsertDataBox.TabIndex = 1; - // - // ResultLabel - // - this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Bottom; - this.ResultLabel.Location = new System.Drawing.Point(0, 143); - this.ResultLabel.Margin = new System.Windows.Forms.Padding(5); - this.ResultLabel.Name = "ResultLabel"; - this.ResultLabel.Padding = new System.Windows.Forms.Padding(5); - this.ResultLabel.Size = new System.Drawing.Size(270, 79); - this.ResultLabel.TabIndex = 2; - this.ResultLabel.Text = "&Insert any int value to insert box above and press \"Calculate\" button to see res" + -"ult..."; - this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // CalculateButton - // - this.CalculateButton.Location = new System.Drawing.Point(81, 116); - this.CalculateButton.Name = "CalculateButton"; - this.CalculateButton.Size = new System.Drawing.Size(103, 23); - this.CalculateButton.TabIndex = 3; - this.CalculateButton.Text = "Calc&ulate"; - this.CalculateButton.UseVisualStyleBackColor = true; - this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click); - // - // SelectFormatterLabel - // - this.SelectFormatterLabel.AutoSize = true; - this.SelectFormatterLabel.Location = new System.Drawing.Point(12, 9); - this.SelectFormatterLabel.Name = "SelectFormatterLabel"; - this.SelectFormatterLabel.Size = new System.Drawing.Size(161, 17); - this.SelectFormatterLabel.TabIndex = 4; - this.SelectFormatterLabel.Text = "&Select formatter:"; - // - // SelectFormatterBox - // - this.SelectFormatterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.SelectFormatterBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.SelectFormatterBox.FormattingEnabled = true; - this.SelectFormatterBox.Items.AddRange(new object[] { - "CountFormatter", - "FileSizeFormatter"}); - this.SelectFormatterBox.Location = new System.Drawing.Point(12, 29); - this.SelectFormatterBox.Name = "SelectFormatterBox"; - this.SelectFormatterBox.Size = new System.Drawing.Size(246, 25); - this.SelectFormatterBox.TabIndex = 5; - // - // CountValueTest - // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(270, 222); - this.Controls.Add(this.SelectFormatterBox); - this.Controls.Add(this.SelectFormatterLabel); - this.Controls.Add(this.CalculateButton); - this.Controls.Add(this.ResultLabel); - this.Controls.Add(this.InsertDataBox); - this.Controls.Add(this.InsertDataLabel); - this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "CountValueTest"; - this.ShowIcon = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Formatter Test Unit"; - this.Load += new System.EventHandler(this.CountValueTest_Load); - this.ResumeLayout(false); - this.PerformLayout(); + this.InsertDataLabel = new System.Windows.Forms.Label(); + this.InsertDataBox = new System.Windows.Forms.TextBox(); + this.ResultLabel = new System.Windows.Forms.Label(); + this.CalculateButton = new System.Windows.Forms.Button(); + this.SelectFormatterLabel = new System.Windows.Forms.Label(); + this.SelectFormatterBox = new System.Windows.Forms.ComboBox(); + this.SuspendLayout(); + // + // InsertDataLabel + // + this.InsertDataLabel.AutoSize = true; + this.InsertDataLabel.Location = new System.Drawing.Point(12, 66); + this.InsertDataLabel.Name = "InsertDataLabel"; + this.InsertDataLabel.Size = new System.Drawing.Size(341, 17); + this.InsertDataLabel.TabIndex = 0; + this.InsertDataLabel.Text = "&Введите любое целочисленное значение:"; + // + // InsertDataBox + // + this.InsertDataBox.Location = new System.Drawing.Point(12, 86); + this.InsertDataBox.Name = "InsertDataBox"; + this.InsertDataBox.Size = new System.Drawing.Size(341, 24); + this.InsertDataBox.TabIndex = 1; + this.InsertDataBox.TextChanged += new System.EventHandler(this.InsertDataBox_TextChanged); + // + // ResultLabel + // + this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.ResultLabel.Location = new System.Drawing.Point(0, 143); + this.ResultLabel.Margin = new System.Windows.Forms.Padding(5); + this.ResultLabel.Name = "ResultLabel"; + this.ResultLabel.Padding = new System.Windows.Forms.Padding(5); + this.ResultLabel.Size = new System.Drawing.Size(365, 79); + this.ResultLabel.TabIndex = 2; + this.ResultLabel.Text = "&Вставьте любое целочисленное значение в поле выше и нажмите кнопку \"Вычислить\", " + + "чтобы увидеть результат..."; + this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // CalculateButton + // + this.CalculateButton.Location = new System.Drawing.Point(140, 116); + this.CalculateButton.Name = "CalculateButton"; + this.CalculateButton.Size = new System.Drawing.Size(103, 23); + this.CalculateButton.TabIndex = 3; + this.CalculateButton.Text = "В&ычислить"; + this.CalculateButton.UseVisualStyleBackColor = true; + this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click); + // + // SelectFormatterLabel + // + this.SelectFormatterLabel.AutoSize = true; + this.SelectFormatterLabel.Location = new System.Drawing.Point(12, 9); + this.SelectFormatterLabel.Name = "SelectFormatterLabel"; + this.SelectFormatterLabel.Size = new System.Drawing.Size(188, 17); + this.SelectFormatterLabel.TabIndex = 4; + this.SelectFormatterLabel.Text = "В&ыберете обработчик:"; + // + // SelectFormatterBox + // + this.SelectFormatterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.SelectFormatterBox.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.SelectFormatterBox.FormattingEnabled = true; + this.SelectFormatterBox.Items.AddRange(new object[] { + "Обработчик счёта", + "Обработчик размера файла"}); + this.SelectFormatterBox.Location = new System.Drawing.Point(12, 29); + this.SelectFormatterBox.Name = "SelectFormatterBox"; + this.SelectFormatterBox.Size = new System.Drawing.Size(341, 25); + this.SelectFormatterBox.TabIndex = 5; + // + // CountValueTest + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(365, 222); + this.Controls.Add(this.SelectFormatterBox); + this.Controls.Add(this.SelectFormatterLabel); + this.Controls.Add(this.CalculateButton); + this.Controls.Add(this.ResultLabel); + this.Controls.Add(this.InsertDataBox); + this.Controls.Add(this.InsertDataLabel); + this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CountValueTest"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Тест модуля форматирования строки"; + this.Load += new System.EventHandler(this.CountValueTest_Load); + this.ResumeLayout(false); + this.PerformLayout(); } diff --git a/demo/CountValueTest.cs b/demo/CountValueTest.cs index 413373c..e8c7202 100644 --- a/demo/CountValueTest.cs +++ b/demo/CountValueTest.cs @@ -29,4 +29,12 @@ public sealed partial class CountValueTest: Form { SelectFormatterBox.SelectedIndex = 0; } + + private void InsertDataBox_TextChanged (object sender, EventArgs e) + { + ulong value = TypeConverter.StrToUInt64(InsertDataBox.Text); + + if (value > long.MaxValue) + InsertDataBox.Text = long.MaxValue.ToString(); + } } \ No newline at end of file diff --git a/demo/FileHashAndMimeTypeTest.Designer.cs b/demo/FileHashAndMimeTypeTest.Designer.cs new file mode 100644 index 0000000..bb6e4f9 --- /dev/null +++ b/demo/FileHashAndMimeTypeTest.Designer.cs @@ -0,0 +1,125 @@ +namespace demo; + +sealed partial class FileHashAndMimeType +{ + /// + /// 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 Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + this.ResultLabel = new System.Windows.Forms.Label(); + this.SelectFileLabel = new System.Windows.Forms.Label(); + this.fileNameEdt = new System.Windows.Forms.TextBox(); + this.ViewButton = new System.Windows.Forms.Button(); + this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.topPanel = new System.Windows.Forms.Panel(); + this.topPanel.SuspendLayout(); + this.SuspendLayout(); + // + // ResultLabel + // + this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.ResultLabel.Location = new System.Drawing.Point(0, 0); + this.ResultLabel.Margin = new System.Windows.Forms.Padding(5); + this.ResultLabel.Name = "ResultLabel"; + this.ResultLabel.Padding = new System.Windows.Forms.Padding(5); + this.ResultLabel.Size = new System.Drawing.Size(412, 428); + this.ResultLabel.TabIndex = 2; + this.ResultLabel.Text = "В&ыберете файл (введите ипя файла с полным путём вверху или с помощью диалога, на" + + "жав \"Обзор\")..."; + this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // SelectFileLabel + // + this.SelectFileLabel.AutoSize = true; + this.SelectFileLabel.Location = new System.Drawing.Point(3, 11); + this.SelectFileLabel.Name = "SelectFileLabel"; + this.SelectFileLabel.Size = new System.Drawing.Size(134, 17); + this.SelectFileLabel.TabIndex = 4; + this.SelectFileLabel.Text = "В&ыберете файл:"; + // + // fileNameEdt + // + this.fileNameEdt.Location = new System.Drawing.Point(3, 38); + this.fileNameEdt.Name = "fileNameEdt"; + this.fileNameEdt.Size = new System.Drawing.Size(288, 24); + this.fileNameEdt.TabIndex = 5; + this.fileNameEdt.TextChanged += new System.EventHandler(this.fileNameEdt_TextChanged); + // + // ViewButton + // + this.ViewButton.Location = new System.Drawing.Point(297, 39); + this.ViewButton.Name = "ViewButton"; + this.ViewButton.Size = new System.Drawing.Size(103, 23); + this.ViewButton.TabIndex = 3; + this.ViewButton.Text = "&Обзор"; + this.ViewButton.UseVisualStyleBackColor = true; + this.ViewButton.Click += new System.EventHandler(this.ViewButton_Click); + // + // openFileDialog + // + this.openFileDialog.AddToRecent = false; + this.openFileDialog.Filter = "Все файлы|*.*"; + this.openFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog_FileOk); + // + // topPanel + // + this.topPanel.Controls.Add(this.SelectFileLabel); + this.topPanel.Controls.Add(this.ViewButton); + this.topPanel.Controls.Add(this.fileNameEdt); + this.topPanel.Dock = System.Windows.Forms.DockStyle.Top; + this.topPanel.Location = new System.Drawing.Point(0, 0); + this.topPanel.Name = "topPanel"; + this.topPanel.Size = new System.Drawing.Size(412, 74); + this.topPanel.TabIndex = 6; + // + // FileHashAndMimeType + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(412, 428); + this.Controls.Add(this.topPanel); + this.Controls.Add(this.ResultLabel); + this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FileHashAndMimeType"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Получение хэша и MIME-типа файла"; + this.topPanel.ResumeLayout(false); + this.topPanel.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + private Label ResultLabel; + private Label SelectFileLabel; + private TextBox fileNameEdt; + private Button ViewButton; + private OpenFileDialog openFileDialog; + private Panel topPanel; +} \ No newline at end of file diff --git a/demo/FileHashAndMimeTypeTest.cs b/demo/FileHashAndMimeTypeTest.cs new file mode 100644 index 0000000..0cc25ad --- /dev/null +++ b/demo/FileHashAndMimeTypeTest.cs @@ -0,0 +1,42 @@ +using anbs_cp.Classes; +// ReSharper disable LocalizableElement + +namespace demo; + +public sealed partial class FileHashAndMimeType: Form +{ + public FileHashAndMimeType () + { + InitializeComponent(); + } + + private void ViewButton_Click (object sender, EventArgs e) + { + openFileDialog.ShowDialog(); + } + +private void GetFileHashAndMimeType() + { + if (string.IsNullOrEmpty(fileNameEdt.Text)) + { + ResultLabel.Text = " !"; + return; + } + + string fileHash = FileExtension.HashString(fileNameEdt.Text); + string fileType = FileExtension.MIMEType(fileNameEdt.Text); + + ResultLabel.Text = + $" \r\n{fileNameEdt.Text}\r\n :\r\n{fileHash}\r\n :\r\n{fileType}"; + } + + private void openFileDialog_FileOk (object sender, System.ComponentModel.CancelEventArgs e) + { + fileNameEdt.Text = openFileDialog.FileName; + } + + private void fileNameEdt_TextChanged (object sender, EventArgs e) + { + GetFileHashAndMimeType(); + } +} \ No newline at end of file diff --git a/demo/FileHashAndMimeTypeTest.resx b/demo/FileHashAndMimeTypeTest.resx new file mode 100644 index 0000000..e6275bd --- /dev/null +++ b/demo/FileHashAndMimeTypeTest.resx @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + \ No newline at end of file diff --git a/demo/MainMenu.Designer.cs b/demo/MainMenu.Designer.cs index 9f45d05..133bf74 100644 --- a/demo/MainMenu.Designer.cs +++ b/demo/MainMenu.Designer.cs @@ -30,6 +30,7 @@ sealed partial class MainMenu { this.CountValueTest = new System.Windows.Forms.Button(); this.SimpleMapperTest = new System.Windows.Forms.Button(); + this.FileExtensionTest = new System.Windows.Forms.Button(); this.SuspendLayout(); // // CountValueTest @@ -38,7 +39,7 @@ sealed partial class MainMenu this.CountValueTest.Name = "CountValueTest"; this.CountValueTest.Size = new System.Drawing.Size(337, 53); this.CountValueTest.TabIndex = 0; - this.CountValueTest.Text = "New CountValue Test"; + this.CountValueTest.Text = "Новый тест модуля форматирования строки"; this.CountValueTest.UseVisualStyleBackColor = true; this.CountValueTest.Click += new System.EventHandler(this.button1_Click); // @@ -48,22 +49,34 @@ sealed partial class MainMenu this.SimpleMapperTest.Name = "SimpleMapperTest"; this.SimpleMapperTest.Size = new System.Drawing.Size(335, 51); this.SimpleMapperTest.TabIndex = 1; - this.SimpleMapperTest.Text = "New SimpleMapper test"; + this.SimpleMapperTest.Text = "Новый тест модуля SimpleMapper"; this.SimpleMapperTest.UseVisualStyleBackColor = true; this.SimpleMapperTest.Click += new System.EventHandler(this.SimpleMapperTest_Click); // + // FileExtensionTest + // + this.FileExtensionTest.Location = new System.Drawing.Point(12, 128); + this.FileExtensionTest.Name = "FileExtensionTest"; + this.FileExtensionTest.Size = new System.Drawing.Size(335, 51); + this.FileExtensionTest.TabIndex = 2; + this.FileExtensionTest.Text = "Новый тест модуля FileExtension"; + this.FileExtensionTest.UseVisualStyleBackColor = true; + this.FileExtensionTest.Click += new System.EventHandler(this.FileExtensionTest_Click); + // // MainMenu // this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(361, 252); + this.Controls.Add(this.FileExtensionTest); this.Controls.Add(this.SimpleMapperTest); this.Controls.Add(this.CountValueTest); this.Font = new System.Drawing.Font("Times New Roman", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Margin = new System.Windows.Forms.Padding(4); this.Name = "MainMenu"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Main menu"; + this.Text = "Главное меню"; this.ResumeLayout(false); } @@ -72,4 +85,5 @@ sealed partial class MainMenu private Button CountValueTest; private Button SimpleMapperTest; + private Button FileExtensionTest; } diff --git a/demo/MainMenu.cs b/demo/MainMenu.cs index cf9b2af..c85a8f8 100644 --- a/demo/MainMenu.cs +++ b/demo/MainMenu.cs @@ -17,4 +17,10 @@ public sealed partial class MainMenu: Form SampleMapperTest formSampleMapperTest = new(); formSampleMapperTest.ShowDialog(); } + + private void FileExtensionTest_Click (object sender, EventArgs e) + { + FileHashAndMimeType formTest = new(); + formTest.ShowDialog(); + } } diff --git a/demo/SampleMapperTest.Designer.cs b/demo/SampleMapperTest.Designer.cs index 8e5fc9f..6b6ca92 100644 --- a/demo/SampleMapperTest.Designer.cs +++ b/demo/SampleMapperTest.Designer.cs @@ -81,7 +81,7 @@ sealed partial class SampleMapperTest this.MapBtn.Name = "MapBtn"; this.MapBtn.Size = new System.Drawing.Size(737, 57); this.MapBtn.TabIndex = 5; - this.MapBtn.Text = "MAP"; + this.MapBtn.Text = "СВЯЗАТЬ"; this.MapBtn.UseVisualStyleBackColor = true; this.MapBtn.Click += new System.EventHandler(this.MapBtn_Click); // @@ -142,9 +142,9 @@ sealed partial class SampleMapperTest this.MapModeLabel.AutoSize = true; this.MapModeLabel.Location = new System.Drawing.Point(32, 230); this.MapModeLabel.Name = "MapModeLabel"; - this.MapModeLabel.Size = new System.Drawing.Size(91, 21); + this.MapModeLabel.Size = new System.Drawing.Size(167, 21); this.MapModeLabel.TabIndex = 11; - this.MapModeLabel.Text = "Map mode"; + this.MapModeLabel.Text = "Режим связывания:"; // // SampleMapperTest // @@ -166,7 +166,7 @@ sealed partial class SampleMapperTest this.Margin = new System.Windows.Forms.Padding(4); this.Name = "SampleMapperTest"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "SampleMapper test"; + this.Text = "Тест класса SampleMapper"; ((System.ComponentModel.ISupportInitialize)(this.DemoIntEdt)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/demo/SampleMapperTest.cs b/demo/SampleMapperTest.cs index cab7845..0890aa8 100644 --- a/demo/SampleMapperTest.cs +++ b/demo/SampleMapperTest.cs @@ -41,9 +41,8 @@ public sealed partial class SampleMapperTest: Form string serialize2 = JsonConvert.SerializeObject(demo2); - ResultArea.Text = $@"Demo2 Class before map: - {serialize1} - and after:{serialize2}"; + // ReSharper disable once LocalizableElement + ResultArea.Text = $"Класс Demo2 до связывания:\r\n{serialize1}\r\nи после:\r\n{serialize2}"; } } diff --git a/demo/demo.csproj b/demo/demo.csproj index ac4ebca..d1ba3bc 100644 --- a/demo/demo.csproj +++ b/demo/demo.csproj @@ -26,4 +26,10 @@ + + + Form + + + \ No newline at end of file From 747877e104a926410ef10c8a96d04f2c3c5a0943 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 3 Dec 2022 15:06:42 +0300 Subject: [PATCH 11/51] 20221203-1 --- anbs_cp/Classes/FileExtensions.cs | 2 -- anbs_cp/anbs_cp.csproj | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs index 7dee49b..87ae1ef 100644 --- a/anbs_cp/Classes/FileExtensions.cs +++ b/anbs_cp/Classes/FileExtensions.cs @@ -2,8 +2,6 @@ using Microsoft.AspNetCore.Http; -using MimeKit; - namespace anbs_cp.Classes; /// diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index b3ae293..4949877 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -40,7 +40,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From cb28634a721c9b5823e9681f5e57fc021cd227af Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 3 Dec 2022 15:07:48 +0300 Subject: [PATCH 12/51] 20221203-2 --- anbs_cp/anbs_cp.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 4949877..7278cd8 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2022.1203.1 + 2022.1203.2 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2022.1203.1 - 2022.1203.1 + 2022.1203.2 + 2022.1203.2 ANBSoftware.ComponentsPack MIT 6.0 From a0e10c27810811a88ba5bf0b20bd77c501558230 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 3 Dec 2022 15:39:28 +0300 Subject: [PATCH 13/51] 20221203-3 --- anbs_cp/Classes/ActionState.cs | 20 +++++++++++++++++--- anbs_cp/anbs_cp.csproj | 6 +++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/anbs_cp/Classes/ActionState.cs b/anbs_cp/Classes/ActionState.cs index f8b5401..c53a9c7 100644 --- a/anbs_cp/Classes/ActionState.cs +++ b/anbs_cp/Classes/ActionState.cs @@ -176,11 +176,11 @@ public sealed class ActionState /// Добавление информации /// /// Текст информации - /// Объект информации - public void AddInfo (string message, string warningObject = "") + /// Объект информации + public void AddInfo (string message, string infoObject = "") { //Создаю информацию - ActionInfo info = new(warningObject, message); + ActionInfo info = new(infoObject, message); //Добавляю информацию AddInfo(info); @@ -295,5 +295,19 @@ public sealed class ActionState /// Количество информационных сообщений public int InfoCount (bool ignoreStatus) => ignoreStatus ? Info.Count(static info => !info.IsStatusInfo) : Info.Count; #endregion + + #region Добавление другого состояния + + /// + /// Добавляет другое состояние (например, результат другого действия, который возвращает ). + /// + /// Запись состояния + public void AddState(ActionState state) + { + AddErrors(state.Errors); + AddWarnings(state.Warnings); + AddInfos(state.Info); + } + #endregion #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 7278cd8..2629cda 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2022.1203.2 + 2022.1203.3 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2022.1203.2 - 2022.1203.2 + 2022.1203.3 + 2022.1203.3 ANBSoftware.ComponentsPack MIT 6.0 From 2ea36fe8a0c12620f2076f2ba87328e4b7bc345c Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 24 Dec 2022 12:15:13 +0300 Subject: [PATCH 14/51] 20221224 --- anbs_cp/Classes/FileExtensions.cs | 12 ++++++++++++ anbs_cp/anbs_cp.csproj | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs index 87ae1ef..a0b278a 100644 --- a/anbs_cp/Classes/FileExtensions.cs +++ b/anbs_cp/Classes/FileExtensions.cs @@ -66,4 +66,16 @@ public static class FileExtension /// MIME-тип файла public static string MIMEType (IFormFile file) => file.ContentType; + + /// + /// Размер файла в байтах + /// + /// Полное имя и путь к файлу + /// Размер файла в байтах + public static long FileSize(string fileName) + { + FileInfo fileInfo = new (fileName); + + return fileInfo.Length; + } } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 2629cda..e1ecddc 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2022.1203.3 + 2022.1224.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2022.1203.3 - 2022.1203.3 + 2022.1224.0 + 2022.1224.0 ANBSoftware.ComponentsPack MIT 6.0 From af7a5dd2998a77b194b08dbc2654a3c3b31a8961 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 24 Dec 2022 15:01:07 +0300 Subject: [PATCH 15/51] 20221224-1 --- anbs_cp/Classes/CountConverter.cs | 20 ++++++ anbs_cp/Classes/CountFormatter.cs | 4 +- anbs_cp/Classes/FileSizeConverter.cs | 20 ++++++ anbs_cp/Classes/FileSizeFormatter.cs | 4 +- anbs_cp/Classes/ValueConverter.cs | 72 +++++++++++++++++++ anbs_cp/Interfaces/IValueConverter.cs | 17 +++++ .../IValueFormatter.cs | 2 +- anbs_cp/anbs_cp.csproj | 6 +- anbsoftware.componentspack.sln.DotSettings | 2 + demo/CountValueTest.Designer.cs | 27 +++++-- demo/CountValueTest.cs | 16 +++++ 11 files changed, 177 insertions(+), 13 deletions(-) create mode 100644 anbs_cp/Classes/CountConverter.cs create mode 100644 anbs_cp/Classes/FileSizeConverter.cs create mode 100644 anbs_cp/Classes/ValueConverter.cs create mode 100644 anbs_cp/Interfaces/IValueConverter.cs rename anbs_cp/{Classes => Interfaces}/IValueFormatter.cs (98%) diff --git a/anbs_cp/Classes/CountConverter.cs b/anbs_cp/Classes/CountConverter.cs new file mode 100644 index 0000000..8545849 --- /dev/null +++ b/anbs_cp/Classes/CountConverter.cs @@ -0,0 +1,20 @@ +namespace anbs_cp.Classes; + +/// +/// Конвертер количества элементов +/// +public sealed class CountConverter : ValueConverter +{ + /// + /// Имена размеров файлов по умолчанию + /// + public static readonly string[] DefaultNames = {"", "тыс.", "млн."}; + + /// + /// Конструктор класса + /// + /// Массив имён размерностей + public CountConverter (string[] valueNames) : base(valueNames, 1000) + { + } +} diff --git a/anbs_cp/Classes/CountFormatter.cs b/anbs_cp/Classes/CountFormatter.cs index c908651..29774e0 100644 --- a/anbs_cp/Classes/CountFormatter.cs +++ b/anbs_cp/Classes/CountFormatter.cs @@ -1,4 +1,6 @@ -namespace anbs_cp.Classes; +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; /// /// Форматирует число элементов в понятную строку diff --git a/anbs_cp/Classes/FileSizeConverter.cs b/anbs_cp/Classes/FileSizeConverter.cs new file mode 100644 index 0000000..dfd3155 --- /dev/null +++ b/anbs_cp/Classes/FileSizeConverter.cs @@ -0,0 +1,20 @@ +namespace anbs_cp.Classes; + +/// +/// Конвертер размеров файлов +/// +public sealed class FileSizeConverter : ValueConverter +{ + /// + /// Имена размеров файлов по умолчанию + /// + public static readonly string[] DefaultNames = {"байт", "Кб", "Мб", "Гб", "Тб"}; + + /// + /// Конструктор класса + /// + /// Массив имён размерностей + public FileSizeConverter (string[] valueNames) : base(valueNames, 1024) + { + } +} diff --git a/anbs_cp/Classes/FileSizeFormatter.cs b/anbs_cp/Classes/FileSizeFormatter.cs index 1cae56d..b3e2891 100644 --- a/anbs_cp/Classes/FileSizeFormatter.cs +++ b/anbs_cp/Classes/FileSizeFormatter.cs @@ -1,4 +1,6 @@ -namespace anbs_cp.Classes; +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; /// /// Форматирует размер файла/папки в понятную строку diff --git a/anbs_cp/Classes/ValueConverter.cs b/anbs_cp/Classes/ValueConverter.cs new file mode 100644 index 0000000..27202b6 --- /dev/null +++ b/anbs_cp/Classes/ValueConverter.cs @@ -0,0 +1,72 @@ +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes; + +/// +/// Абстрактный класс конвертера величин для отображения (улучшенный аналог ValueFormatter) +/// +public abstract class ValueConverter: IValueConverter +{ + /// + /// Конструктор + /// + /// Массив имён размерностей + /// Делитель + protected ValueConverter (string[] valueNames, long divider) + { + ValueNames = valueNames; + Divider = divider; + } + + #region Реализация интерфейса + /// + /// Массив имён размерностей + /// + public string[] ValueNames { get; init; } + + /// + /// Делитель + /// + public long Divider { get; init; } + #endregion + + #region Методы + /// + /// Функция конвертирования в строку + /// + /// Значение + /// Конвертирование значение в строку + public string Convert (long value) + { + (decimal, int) result = DivideIt(value, 0); + + return $"{result.Item1:F2} {ValueNames[result.Item2]}"; + } + + + /// + /// Рекурсивная функция деления + /// + /// Число + /// Счётчик вызова рекурсии + /// Число в остатке и количество вызовов рекурсии + private (decimal, int) DivideIt (decimal value, int count) + { + //Если счёт уже больше количества названий + if (count > ValueNames.Length) + return (value, count); + + //Если частное уже меньше делителя, то прерываем цикл + if (value < Divider) + return (value, count); + + //Увеличиваем счётчик... + count++; + + //... и продолжаем цикл + return DivideIt(value / Divider, count); + + + } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IValueConverter.cs b/anbs_cp/Interfaces/IValueConverter.cs new file mode 100644 index 0000000..56e8a1c --- /dev/null +++ b/anbs_cp/Interfaces/IValueConverter.cs @@ -0,0 +1,17 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс конвертера величин для отображения (улучшенный аналог IValueFormatter) +/// +public interface IValueConverter +{ + /// + /// Массив имён размерностей + /// + public string[] ValueNames { get; init; } + + /// + /// Делитель + /// + public long Divider { get; init; } +} \ No newline at end of file diff --git a/anbs_cp/Classes/IValueFormatter.cs b/anbs_cp/Interfaces/IValueFormatter.cs similarity index 98% rename from anbs_cp/Classes/IValueFormatter.cs rename to anbs_cp/Interfaces/IValueFormatter.cs index eb1f2bd..2ae523d 100644 --- a/anbs_cp/Classes/IValueFormatter.cs +++ b/anbs_cp/Interfaces/IValueFormatter.cs @@ -1,4 +1,4 @@ -namespace anbs_cp.Classes; +namespace anbs_cp.Interfaces; /// /// Форматирует размерности в понятную строку diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index e1ecddc..bf3f4ba 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2022.1224.0 + 2022.1224.1 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2022.1224.0 - 2022.1224.0 + 2022.1224.1 + 2022.1224.1 ANBSoftware.ComponentsPack MIT 6.0 diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 68f48c1..731bddc 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -4,5 +4,7 @@ True True True + True + True True True \ No newline at end of file diff --git a/demo/CountValueTest.Designer.cs b/demo/CountValueTest.Designer.cs index aef3ab5..2088b44 100644 --- a/demo/CountValueTest.Designer.cs +++ b/demo/CountValueTest.Designer.cs @@ -34,6 +34,7 @@ sealed partial class CountValueTest this.CalculateButton = new System.Windows.Forms.Button(); this.SelectFormatterLabel = new System.Windows.Forms.Label(); this.SelectFormatterBox = new System.Windows.Forms.ComboBox(); + this.calculateConvButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // InsertDataLabel @@ -49,7 +50,7 @@ sealed partial class CountValueTest // this.InsertDataBox.Location = new System.Drawing.Point(12, 86); this.InsertDataBox.Name = "InsertDataBox"; - this.InsertDataBox.Size = new System.Drawing.Size(341, 24); + this.InsertDataBox.Size = new System.Drawing.Size(457, 24); this.InsertDataBox.TabIndex = 1; this.InsertDataBox.TextChanged += new System.EventHandler(this.InsertDataBox_TextChanged); // @@ -60,7 +61,7 @@ sealed partial class CountValueTest this.ResultLabel.Margin = new System.Windows.Forms.Padding(5); this.ResultLabel.Name = "ResultLabel"; this.ResultLabel.Padding = new System.Windows.Forms.Padding(5); - this.ResultLabel.Size = new System.Drawing.Size(365, 79); + this.ResultLabel.Size = new System.Drawing.Size(478, 79); this.ResultLabel.TabIndex = 2; this.ResultLabel.Text = "&Вставьте любое целочисленное значение в поле выше и нажмите кнопку \"Вычислить\", " + "чтобы увидеть результат..."; @@ -68,11 +69,11 @@ sealed partial class CountValueTest // // CalculateButton // - this.CalculateButton.Location = new System.Drawing.Point(140, 116); + this.CalculateButton.Location = new System.Drawing.Point(12, 116); this.CalculateButton.Name = "CalculateButton"; - this.CalculateButton.Size = new System.Drawing.Size(103, 23); + this.CalculateButton.Size = new System.Drawing.Size(234, 23); this.CalculateButton.TabIndex = 3; - this.CalculateButton.Text = "В&ычислить"; + this.CalculateButton.Text = "В&ычислить обработчиком"; this.CalculateButton.UseVisualStyleBackColor = true; this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click); // @@ -95,14 +96,25 @@ sealed partial class CountValueTest "Обработчик размера файла"}); this.SelectFormatterBox.Location = new System.Drawing.Point(12, 29); this.SelectFormatterBox.Name = "SelectFormatterBox"; - this.SelectFormatterBox.Size = new System.Drawing.Size(341, 25); + this.SelectFormatterBox.Size = new System.Drawing.Size(457, 25); this.SelectFormatterBox.TabIndex = 5; // + // calculateConvButton + // + this.calculateConvButton.Location = new System.Drawing.Point(252, 116); + this.calculateConvButton.Name = "calculateConvButton"; + this.calculateConvButton.Size = new System.Drawing.Size(217, 23); + this.calculateConvButton.TabIndex = 6; + this.calculateConvButton.Text = "&Вычислить конвертером"; + this.calculateConvButton.UseVisualStyleBackColor = true; + this.calculateConvButton.Click += new System.EventHandler(this.calculateConvButton_Click); + // // CountValueTest // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(365, 222); + this.ClientSize = new System.Drawing.Size(478, 222); + this.Controls.Add(this.calculateConvButton); this.Controls.Add(this.SelectFormatterBox); this.Controls.Add(this.SelectFormatterLabel); this.Controls.Add(this.CalculateButton); @@ -131,4 +143,5 @@ sealed partial class CountValueTest private Button CalculateButton; private Label SelectFormatterLabel; private ComboBox SelectFormatterBox; + private Button calculateConvButton; } \ No newline at end of file diff --git a/demo/CountValueTest.cs b/demo/CountValueTest.cs index e8c7202..4afcb46 100644 --- a/demo/CountValueTest.cs +++ b/demo/CountValueTest.cs @@ -1,4 +1,5 @@ using anbs_cp.Classes; +using anbs_cp.Interfaces; namespace demo; @@ -37,4 +38,19 @@ public sealed partial class CountValueTest: Form if (value > long.MaxValue) InsertDataBox.Text = long.MaxValue.ToString(); } + + private void calculateConvButton_Click (object sender, EventArgs e) + { + if (string.IsNullOrEmpty(InsertDataBox.Text)) + return; + + long value = TypeConverter.StrToInt64(InsertDataBox.Text); + + ResultLabel.Text = SelectFormatterBox.SelectedIndex switch + { + 0 => new CountConverter(CountConverter.DefaultNames).Convert(value), + 1 => new FileSizeConverter(FileSizeConverter.DefaultNames).Convert(value), + _ => new CountConverter(CountConverter.DefaultNames).Convert(value) + }; + } } \ No newline at end of file From a2990fe1ef6308e4ef0cb9715ba95aa137ba05f7 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 2 Jan 2023 10:18:22 +0300 Subject: [PATCH 16/51] 20230102 --- anbs_cp/Classes/CountConverter.cs | 3 ++- anbs_cp/Classes/FileSizeConverter.cs | 3 ++- anbs_cp/Classes/ValueConverter.cs | 23 ++++++++++++++++++---- anbs_cp/Interfaces/IValueConverter.cs | 5 +++++ anbs_cp/anbs_cp.csproj | 7 ++++--- anbsoftware.componentspack.sln.DotSettings | 1 + 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/anbs_cp/Classes/CountConverter.cs b/anbs_cp/Classes/CountConverter.cs index 8545849..662af0b 100644 --- a/anbs_cp/Classes/CountConverter.cs +++ b/anbs_cp/Classes/CountConverter.cs @@ -14,7 +14,8 @@ public sealed class CountConverter : ValueConverter /// Конструктор класса /// /// Массив имён размерностей - public CountConverter (string[] valueNames) : base(valueNames, 1000) + /// Знаков после запятой (0, 1, 2) + public CountConverter (string[] valueNames, byte decimalPlace = 0) : base(valueNames, 1000, decimalPlace) { } } diff --git a/anbs_cp/Classes/FileSizeConverter.cs b/anbs_cp/Classes/FileSizeConverter.cs index dfd3155..5aa77ec 100644 --- a/anbs_cp/Classes/FileSizeConverter.cs +++ b/anbs_cp/Classes/FileSizeConverter.cs @@ -14,7 +14,8 @@ public sealed class FileSizeConverter : ValueConverter /// Конструктор класса /// /// Массив имён размерностей - public FileSizeConverter (string[] valueNames) : base(valueNames, 1024) + /// Знаков после запятой (0, 1, 2) + public FileSizeConverter (string[] valueNames, byte decimalPlace = 2) : base(valueNames, 1024, decimalPlace) { } } diff --git a/anbs_cp/Classes/ValueConverter.cs b/anbs_cp/Classes/ValueConverter.cs index 27202b6..8bb82ae 100644 --- a/anbs_cp/Classes/ValueConverter.cs +++ b/anbs_cp/Classes/ValueConverter.cs @@ -12,10 +12,12 @@ public abstract class ValueConverter: IValueConverter /// /// Массив имён размерностей /// Делитель - protected ValueConverter (string[] valueNames, long divider) + /// Число знаков после запятой + protected ValueConverter (string[] valueNames, long divider, byte decimalPlaces) { ValueNames = valueNames; Divider = divider; + DecimalPlaces = (byte)(decimalPlaces < 3 ? decimalPlaces : 2); } #region Реализация интерфейса @@ -28,6 +30,12 @@ public abstract class ValueConverter: IValueConverter /// Делитель /// public long Divider { get; init; } + + /// + /// Знаков после запятой (0, 1, 2) + /// + public byte DecimalPlaces { get; init; } + #endregion #region Методы @@ -38,9 +46,18 @@ public abstract class ValueConverter: IValueConverter /// Конвертирование значение в строку public string Convert (long value) { + //Получаю разделенное значение (decimal, int) result = DivideIt(value, 0); - return $"{result.Item1:F2} {ValueNames[result.Item2]}"; + //Преобразую значение в строку + string resultValue = DecimalPlaces switch { + 0 => $"{result.Item1:F0}", + 1 => $"{result.Item1:F1}", + _ => $"{result.Item1:F2}" + }; + + //Возвращаю результат + return $"{resultValue} {ValueNames[result.Item2]}"; } @@ -65,8 +82,6 @@ public abstract class ValueConverter: IValueConverter //... и продолжаем цикл return DivideIt(value / Divider, count); - - } #endregion } \ No newline at end of file diff --git a/anbs_cp/Interfaces/IValueConverter.cs b/anbs_cp/Interfaces/IValueConverter.cs index 56e8a1c..2400136 100644 --- a/anbs_cp/Interfaces/IValueConverter.cs +++ b/anbs_cp/Interfaces/IValueConverter.cs @@ -14,4 +14,9 @@ public interface IValueConverter /// Делитель /// public long Divider { get; init; } + + /// + /// Знаков после запятой (0, 1, 2) + /// + public byte DecimalPlaces { get; init; } } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index bf3f4ba..def1039 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2022.1224.1 + 2023.102.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2022.1224.1 - 2022.1224.1 + 2023.102.0 + 2023.102.0 ANBSoftware.ComponentsPack MIT 6.0 @@ -44,6 +44,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 731bddc..391c6ec 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -5,6 +5,7 @@ True True True + True True True True \ No newline at end of file From 4649373a3d5ccef7a48b891bc359190c8eec2644 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 4 Jan 2023 15:45:03 +0300 Subject: [PATCH 17/51] 20230104 --- anbs_cp/Classes/ActionState.cs | 5 ++++- anbs_cp/anbs_cp.csproj | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/anbs_cp/Classes/ActionState.cs b/anbs_cp/Classes/ActionState.cs index c53a9c7..8cda85b 100644 --- a/anbs_cp/Classes/ActionState.cs +++ b/anbs_cp/Classes/ActionState.cs @@ -4,6 +4,9 @@ namespace anbs_cp.Classes; /// /// Состояние действия +/// +/// Обновлено 2023.01.104.1: +/// * Убрана ошибка с рекурсивным вызовом AddError /// public sealed class ActionState { @@ -80,7 +83,7 @@ public sealed class ActionState /// Ошибка // ReSharper disable once MemberCanBeMadeStatic.Global // ReSharper disable once FunctionRecursiveOnAllPaths - public void AddError (IActionError error) => AddError(error); + public void AddError (IActionError error) => Errors.Add(error); /// /// Добавляет ошибки в список diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index def1039..4033045 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.102.0 + 2023.104.1 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2023.102.0 - 2023.102.0 + 2023.104.1 + 2023.104.1 ANBSoftware.ComponentsPack MIT 6.0 From d3171a1164d13a8ffc7bb8ff23b2217fabcee911 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 15 Jan 2023 15:04:00 +0300 Subject: [PATCH 18/51] 20230115 --- anbs_cp/Classes/OsInfo.cs | 340 ++++++++++++++++++ anbs_cp/Classes/OsInfos/OsDriveInfo.cs | 59 +++ anbs_cp/Classes/OsInfos/OsNetInfo.cs | 39 ++ anbs_cp/Classes/OsInfos/OsProcessorInfo.cs | 64 ++++ anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs | 82 +++++ anbs_cp/Classes/OsInfos/OsWindowsInfo.cs | 62 ++++ anbs_cp/Enums/EDriveType.cs | 17 + anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs | 27 ++ anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs | 24 ++ anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs | 17 + .../Interfaces/OsInfos/IOsProcessorInfo.cs | 31 ++ .../Interfaces/OsInfos/IOsVideoAdapterInfo.cs | 42 +++ anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs | 27 ++ anbs_cp/anbs_cp.csproj | 11 +- anbsoftware.componentspack.sln.DotSettings | 7 + demo/MainMenu.Designer.cs | 13 + demo/MainMenu.cs | 6 + demo/OsInfoFrm.Designer.cs | 65 ++++ demo/OsInfoFrm.cs | 28 ++ demo/OsInfoFrm.resx | 60 ++++ 20 files changed, 1018 insertions(+), 3 deletions(-) create mode 100644 anbs_cp/Classes/OsInfo.cs create mode 100644 anbs_cp/Classes/OsInfos/OsDriveInfo.cs create mode 100644 anbs_cp/Classes/OsInfos/OsNetInfo.cs create mode 100644 anbs_cp/Classes/OsInfos/OsProcessorInfo.cs create mode 100644 anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs create mode 100644 anbs_cp/Classes/OsInfos/OsWindowsInfo.cs create mode 100644 anbs_cp/Enums/EDriveType.cs create mode 100644 anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs create mode 100644 anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs create mode 100644 anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs create mode 100644 anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs create mode 100644 anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs create mode 100644 anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs create mode 100644 demo/OsInfoFrm.Designer.cs create mode 100644 demo/OsInfoFrm.cs create mode 100644 demo/OsInfoFrm.resx diff --git a/anbs_cp/Classes/OsInfo.cs b/anbs_cp/Classes/OsInfo.cs new file mode 100644 index 0000000..adbc3eb --- /dev/null +++ b/anbs_cp/Classes/OsInfo.cs @@ -0,0 +1,340 @@ +using System.Management; +using System.Net.NetworkInformation; +using System.Net.Sockets; + +using anbs_cp.Classes.OsInfos; +using anbs_cp.Enums; +using anbs_cp.Interfaces.OsInfos; + +namespace anbs_cp.Classes; + +/// +/// Информация о системе +/// +public static class OsInfo +{ + /// + /// Конструктор + /// + static OsInfo () + { + Windows = GetWindowsInfo(); + Processors = GetProcessors(); + RAM = GetRAMs(); + Videos = GetVideoAdapterInfos(); + Drives = GetDriveInfos(); + Net = GetNet(); + } + + /// + /// Информация о Windows + /// + public static IOsWindowsInfo Windows { get; } + + /// + /// Список с информацией о процессоре(-ах) + /// + public static List Processors { get; } + + /// + /// Количество оперативной памяти в байтах + /// + public static ulong RAM { get; } + + /// + /// Видеоадаптеры + /// + public static List Videos { get; } + + /// + /// Диски + /// + public static List Drives { get; set; } + + public static List Net { get; set; } + + #region Служебные методы + /// + /// Получает информацию о Windows + /// + /// + private static IOsWindowsInfo GetWindowsInfo () => + new OsWindowsInfo + { + Version = Environment.OSVersion.ToString(), + Is64 = Environment.Is64BitOperatingSystem, + PcName = Environment.MachineName, + WindowsFolder = Environment.SystemDirectory + }; + + /// + /// Получение процессоров + /// + /// Список информации о процессорах + private static List GetProcessors () + { + //Создаю результирующий список + List processorsList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_Processor"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число процессоров + int processorsCount = collection.Cast() + .Select(static a => a.Properties["ProcessorId"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < processorsCount; ind++) + { + //Создаю элемент информации о процессоре + OsProcessorInfo processor = new() + { + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + Manufacturer = collection.Cast() + .Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind), + MaxClockSpeed = TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["MaxClockSpeed"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + NumberOfCores = TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["NumberOfCores"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + NumberOfLogicalProcessors = TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["NumberOfLogicalProcessors"].Value.ToString()).ElementAtOrDefault(ind) ?? "0") + }; + + //Добавляю в список + processorsList.Add(processor); + } + + //Возвращаю список + return processorsList; + } + + /// + /// Получение общее количество оперативной памяти + /// + /// Список информации о количестве оперативной памяти + private static ulong GetRAMs () + { + //Создаю классы менеджмента + ManagementClass management = new("Win32_ComputerSystem"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю результат + return TypeConverter.StrToUInt64(collection.Cast() + .Select(static a => a.Properties["TotalPhysicalMemory"].Value.ToString()).FirstOrDefault() ?? "0"); + } + + /// + /// Получает список видеоадаптеров + /// + /// Список информации о видеоадаптерах + private static List GetVideoAdapterInfos () + { + //Создаю результирующий список + List videosList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_VideoController"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число адаптеров + int count = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < count; ind++) + { + //Создаю элемент информации об адаптере + OsVideoAdapterInfo adapter = new() + { + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + AdapterRAM = TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["AdapterRAM"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + DriverDate = collection.Cast() + .Select(static a => a.Properties["DriverDate"].Value.ToString()).ElementAtOrDefault(ind), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + CurrentResolution = (TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["CurrentHorizontalResolution"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["CurrentVerticalResolution"].Value.ToString()) + .ElementAtOrDefault(ind) ?? "0")), + SystemName = collection.Cast() + .Select(static a => a.Properties["SystemName"].Value.ToString()).ElementAtOrDefault(ind), + DriverVersion = collection.Cast() + .Select(static a => a.Properties["DriverVersion"].Value.ToString()).ElementAtOrDefault(ind), + InstalledDisplayDrivers = collection.Cast() + .Select(static a => a.Properties["InstalledDisplayDrivers"].Value.ToString()).ElementAtOrDefault(ind), + VideoProcessor = collection.Cast() + .Select(static a => a.Properties["VideoProcessor"].Value.ToString()).ElementAtOrDefault(ind) + }; + + //Добавляю в список + videosList.Add(adapter); + } + + //Возвращаю список + return videosList; + } + + /// + /// Получает список дисков + /// + /// Список информации о дисках + private static List GetDriveInfos () + { + //Создаю результат + List result = new(); + + //Добавление всех HDD/SSD дисков + result.AddRange(GetHDDs()); + + //Добавление всех CD/DVD/BD дисков + result.AddRange(GetCDRom()); + + //Вывожу список + return result; + } + + /// + /// Получаю список HDD/SSD дисков + /// + /// Информация обо всех HDD/SSD дисках + private static List GetHDDs () + { + //Создаю результирующий список + List driveList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_DiskDrive"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число адаптеров + int count = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < count; ind++) + { + //Создаю элемент информации об адаптере + OsDriveInfo drive = new() + { + Type = EDriveType.DtHardDisc, + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + TotalSize = TypeConverter.StrToUInt64(collection.Cast() + .Select(static a => a.Properties["Size"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + Model = collection.Cast() + .Select(static a => a.Properties["Model"].Value.ToString()).ElementAtOrDefault(ind) + }; + + //Добавляю в список + driveList.Add(drive); + } + + //Возвращаю список + return driveList; + } + + /// + /// Получаю список CD/DVD/BD дисков + /// + /// Информация обо всех CD/DVD/BD дисках + private static List GetCDRom () + { + //Создаю результирующий список + List driveList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_CDROMDrive"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число адаптеров + int count = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < count; ind++) + { + //Создаю элемент информации об адаптере + OsDriveInfo drive = new() + { + Type = EDriveType.DtCDRom, + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + //Ставится 0, чтобы не проверять корректность загрузки и читаемость диска, а также избежать удлинения получения информации + TotalSize = 0, + Model = collection.Cast() + .Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind) + }; + + //Добавляю в список + driveList.Add(drive); + } + + //Возвращаю список + return driveList; + } + + /// + /// Получаю информацию о сети интернет + /// + /// Информация о сети интернет + private static List GetNet () + { + //Создаю результирующий список + List netList = new(); + + //Получаю информацию о всех сетевых интерфейсах + foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) + { + //Создаю элемент + OsNetInfo netInfo = new() + { + Name = adapter.Name, + Description = adapter.Description, + MacAddress = adapter.OperationalStatus == OperationalStatus.Up ? adapter.GetPhysicalAddress().ToString() : null + }; + + //Получаю IP-адрес + foreach (UnicastIPAddressInformation info in adapter.GetIPProperties().UnicastAddresses.Where(static info => + info.Address.AddressFamily == AddressFamily.InterNetwork && info.IsDnsEligible)) + { + if (!string.IsNullOrWhiteSpace(netInfo.IPAddress)) + netInfo.IPAddress += ";"; + netInfo.IPAddress += info.Address.ToString(); + } + + //Добавляю адаптер + netList.Add(netInfo); + } + + //Возвращаю список + return netList; + } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Classes/OsInfos/OsDriveInfo.cs b/anbs_cp/Classes/OsInfos/OsDriveInfo.cs new file mode 100644 index 0000000..b64ef67 --- /dev/null +++ b/anbs_cp/Classes/OsInfos/OsDriveInfo.cs @@ -0,0 +1,59 @@ +using anbs_cp.Enums; +using anbs_cp.Interfaces.OsInfos; + +namespace anbs_cp.Classes.OsInfos; + +/// +/// Информация о дисках +/// +public class OsDriveInfo : IOsDriveInfo +{ + /// + /// Конструктор + /// + public OsDriveInfo() + { + Type = EDriveType.DtHardDisc; + Caption = null; + Description = null; + DeviceId = null; + Name = null; + Model = null; + TotalSize = 0; + } + + /// + /// Тип диска + /// + public EDriveType Type { get; set; } + + /// + /// Заголовок + /// + public string? Caption { get; set; } + + /// + /// Описание + /// + public string? Description { get; set; } + + /// + /// Идентификатор устройства + /// + public string? DeviceId { get; set; } + + /// + /// Имя устройства + /// + public string? Name { get; set; } + + /// + /// Модель + /// + public string? Model { get; set; } + + /// + /// Общий размер + /// + public ulong TotalSize { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Classes/OsInfos/OsNetInfo.cs b/anbs_cp/Classes/OsInfos/OsNetInfo.cs new file mode 100644 index 0000000..5e0eb5f --- /dev/null +++ b/anbs_cp/Classes/OsInfos/OsNetInfo.cs @@ -0,0 +1,39 @@ +using anbs_cp.Interfaces.OsInfos; + +namespace anbs_cp.Classes.OsInfos; + +/// +/// Информация об интернет-соединении +/// +public sealed class OsNetInfo: IOsNetInfo +{ + /// + /// Заголовок + /// + public string? Caption { get => Name; set => _ = value; } + + /// + /// Описание + /// + public string? Description { get; set; } + + /// + /// Идентификатор устройства + /// + public string? DeviceId { get => Name; set => _ = value; } + + /// + /// Имя устройства + /// + public string? Name { get; set; } + + /// + /// IP-адрес + /// + public string? IPAddress { get; set; } + + /// + /// MAC-адрес + /// + public string? MacAddress { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Classes/OsInfos/OsProcessorInfo.cs b/anbs_cp/Classes/OsInfos/OsProcessorInfo.cs new file mode 100644 index 0000000..b99e6af --- /dev/null +++ b/anbs_cp/Classes/OsInfos/OsProcessorInfo.cs @@ -0,0 +1,64 @@ +using anbs_cp.Interfaces.OsInfos; + +namespace anbs_cp.Classes.OsInfos; + +/// +/// Класс информации о процессоре +/// +public sealed class OsProcessorInfo : IOsProcessorInfo +{ + /// + /// Конструктор + /// + public OsProcessorInfo() + { + Caption = null; + Description = null; + DeviceId = null; + Manufacturer = null; + MaxClockSpeed = 0; + Name = null; + NumberOfCores = 0; + NumberOfLogicalProcessors = 0; + } + + /// + /// Заголовок + /// + public string? Caption { get; set; } + + /// + /// Описание + /// + public string? Description { get; set; } + + /// + /// Идентификатор процессора в системе + /// + public string? DeviceId { get; set; } + + /// + /// Производитель + /// + public string? Manufacturer { get; set; } + + /// + /// Максимальная тактовая частота + /// + public int MaxClockSpeed { get; set; } + + /// + /// Имя процессора + /// + public string? Name { get; set; } + + /// + /// Число ядер + /// + public int NumberOfCores { get; set; } + + /// + /// Число потоков + /// + public int NumberOfLogicalProcessors { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs b/anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs new file mode 100644 index 0000000..59ede17 --- /dev/null +++ b/anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs @@ -0,0 +1,82 @@ +using anbs_cp.Interfaces.OsInfos; + +namespace anbs_cp.Classes.OsInfos; + +/// +/// Информация о видеокарте +/// +internal sealed class OsVideoAdapterInfo : IOsVideoAdapterInfo +{ + /// + /// Конструктор + /// + public OsVideoAdapterInfo() + { + AdapterRAM = 0; + Caption = null; + CurrentResolution = (0, 0); + Description = null; + DeviceId = null; + DriverDate = null; + DriverVersion = null; + InstalledDisplayDrivers = null; + Name = null; + SystemName = null; + VideoProcessor = null; + } + + /// + /// Память + /// + public int AdapterRAM { get; set; } + + /// + /// Заголовок + /// + public string? Caption { get; set; } + + /// + /// Текущее разрешение + /// + public (int, int) CurrentResolution { get; set; } + + /// + /// Описание + /// + public string? Description { get; set; } + + /// + /// Идентификатор устройства + /// + public string? DeviceId { get; set; } + + /// + /// Дата установки драйвера + /// + public string? DriverDate { get; set; } + + /// + /// Версия драйвера + /// + public string? DriverVersion { get; set; } + + /// + /// Название драйверов + /// + public string? InstalledDisplayDrivers { get; set; } + + /// + /// Имя + /// + public string? Name { get; set; } + + /// + /// Имя в системе + /// + public string? SystemName { get; set; } + + /// + /// Видео процессор + /// + public string? VideoProcessor { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Classes/OsInfos/OsWindowsInfo.cs b/anbs_cp/Classes/OsInfos/OsWindowsInfo.cs new file mode 100644 index 0000000..e16e1aa --- /dev/null +++ b/anbs_cp/Classes/OsInfos/OsWindowsInfo.cs @@ -0,0 +1,62 @@ +using anbs_cp.Interfaces.OsInfos; + +namespace anbs_cp.Classes.OsInfos; + +/// +/// Информация о Windows +/// +public sealed class OsWindowsInfo : IOsWindowsInfo +{ + /// + /// Конструктор + /// + public OsWindowsInfo() + { + Version = null; + Is64 = true; + PcName = null; + WindowsFolder = null; + } + + /// + /// Версия + /// + public string? Version { get; set; } + + /// + /// 64-разрядная ОС + /// + public bool Is64 { get; set; } + + /// + /// Имя компьютера + /// + public string? PcName { get; set; } + + /// + /// Путь к папке Windows + /// + public string? WindowsFolder { get; set; } + + #region Реализация интерфейса IBasicInfo + /// + /// Заголовок + /// + public string? Caption { get => Version; set => _= value; } + + /// + /// Описание + /// + public string? Description { get => Version; set => _= value; } + + /// + /// Идентификатор + /// + public string? DeviceId { get => Version; set => _= value; } + + /// + /// Имя + /// + public string? Name { get => Version; set => _= value; } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Enums/EDriveType.cs b/anbs_cp/Enums/EDriveType.cs new file mode 100644 index 0000000..7b8c049 --- /dev/null +++ b/anbs_cp/Enums/EDriveType.cs @@ -0,0 +1,17 @@ +namespace anbs_cp.Enums; + +/// +/// Тип носителя +/// +public enum EDriveType +{ + /// + /// HDD/SSD/M2 + /// + DtHardDisc = 0, + + /// + /// Диск CD/DVD/BD + /// + DtCDRom = 1 +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs b/anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs new file mode 100644 index 0000000..986dffd --- /dev/null +++ b/anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs @@ -0,0 +1,27 @@ +namespace anbs_cp.Interfaces.OsInfos; + +/// +/// Базовые параметры устройства +/// +public interface IOsBasicInfo +{ + /// + /// Заголовок + /// + public string? Caption { get; set; } + + /// + /// Описание + /// + public string? Description { get; set; } + + /// + /// Идентификатор устройства + /// + public string? DeviceId { get; set; } + + /// + /// Имя устройства + /// + public string? Name { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs b/anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs new file mode 100644 index 0000000..522dba6 --- /dev/null +++ b/anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs @@ -0,0 +1,24 @@ +using anbs_cp.Enums; + +namespace anbs_cp.Interfaces.OsInfos; + +/// +/// Информация о дисках +/// +public interface IOsDriveInfo : IOsBasicInfo +{ + /// + /// Тип диска + /// + public EDriveType Type { get; set; } + + /// + /// Модель + /// + public string? Model { get; set; } + + /// + /// Общий размер + /// + public ulong TotalSize { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs b/anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs new file mode 100644 index 0000000..6efac09 --- /dev/null +++ b/anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs @@ -0,0 +1,17 @@ +namespace anbs_cp.Interfaces.OsInfos; + +/// +/// Информация об интернет-соединении +/// +public interface IOsNetInfo: IOsBasicInfo +{ + /// + /// IP-адрес + /// + public string? IPAddress { get; set; } + + /// + /// MAC-адрес + /// + public string? MacAddress { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs b/anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs new file mode 100644 index 0000000..87ddc7e --- /dev/null +++ b/anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs @@ -0,0 +1,31 @@ +namespace anbs_cp.Interfaces.OsInfos; + +/// +/// Информация о процессоре +/// +public interface IOsProcessorInfo : IOsBasicInfo +{ + /// + /// Заголовок + /// + + /// + /// Производитель + /// + public string? Manufacturer { get; set; } + + /// + /// Максимальная тактовая частота + /// + public int MaxClockSpeed { get; set; } + + /// + /// Число ядер + /// + public int NumberOfCores { get; set; } + + /// + /// Число потоков + /// + public int NumberOfLogicalProcessors { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs b/anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs new file mode 100644 index 0000000..26fced1 --- /dev/null +++ b/anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs @@ -0,0 +1,42 @@ +namespace anbs_cp.Interfaces.OsInfos; + +/// +/// Информация о видеокарте +/// +public interface IOsVideoAdapterInfo : IOsBasicInfo +{ + /// + /// Память + /// + public int AdapterRAM { get; set; } + + /// + /// Текущее разрешение + /// + public (int, int) CurrentResolution { get; set; } + + /// + /// Дата установки драйвера + /// + public string? DriverDate { get; set; } + + /// + /// Версия драйвера + /// + public string? DriverVersion { get; set; } + + /// + /// Название драйверов + /// + public string? InstalledDisplayDrivers { get; set; } + + /// + /// Имя в системе + /// + public string? SystemName { get; set; } + + /// + /// Видео процессор + /// + public string? VideoProcessor { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs b/anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs new file mode 100644 index 0000000..3e3fae4 --- /dev/null +++ b/anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs @@ -0,0 +1,27 @@ +namespace anbs_cp.Interfaces.OsInfos; + +/// +/// Информация о Windows +/// +public interface IOsWindowsInfo: IOsBasicInfo +{ + /// + /// Версия + /// + public string? Version { get; set; } + + /// + /// 64-разрядная ОС + /// + public bool Is64 { get; set; } + + /// + /// Имя компьютера + /// + public string? PcName { get; set; } + + /// + /// Путь к папке Windows + /// + public string? WindowsFolder { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 4033045..dc0c637 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.104.1 + 2023.115.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2023.104.1 - 2023.104.1 + 2023.115.0 + 2023.115.0 ANBSoftware.ComponentsPack MIT 6.0 @@ -40,6 +40,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -47,4 +48,8 @@ + + + + diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 391c6ec..f451ee2 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -1,9 +1,16 @@  + CD + HD + HDD + RA + RAM True True + True True True True + True True True True diff --git a/demo/MainMenu.Designer.cs b/demo/MainMenu.Designer.cs index 133bf74..a13600a 100644 --- a/demo/MainMenu.Designer.cs +++ b/demo/MainMenu.Designer.cs @@ -31,6 +31,7 @@ sealed partial class MainMenu this.CountValueTest = new System.Windows.Forms.Button(); this.SimpleMapperTest = new System.Windows.Forms.Button(); this.FileExtensionTest = new System.Windows.Forms.Button(); + this.OsInfoBtn = new System.Windows.Forms.Button(); this.SuspendLayout(); // // CountValueTest @@ -63,11 +64,22 @@ sealed partial class MainMenu this.FileExtensionTest.UseVisualStyleBackColor = true; this.FileExtensionTest.Click += new System.EventHandler(this.FileExtensionTest_Click); // + // OsInfoBtn + // + this.OsInfoBtn.Location = new System.Drawing.Point(12, 185); + this.OsInfoBtn.Name = "OsInfoBtn"; + this.OsInfoBtn.Size = new System.Drawing.Size(335, 51); + this.OsInfoBtn.TabIndex = 3; + this.OsInfoBtn.Text = "Информация о системе"; + this.OsInfoBtn.UseVisualStyleBackColor = true; + this.OsInfoBtn.Click += new System.EventHandler(this.OsInfoBtn_Click); + // // MainMenu // this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(361, 252); + this.Controls.Add(this.OsInfoBtn); this.Controls.Add(this.FileExtensionTest); this.Controls.Add(this.SimpleMapperTest); this.Controls.Add(this.CountValueTest); @@ -86,4 +98,5 @@ sealed partial class MainMenu private Button CountValueTest; private Button SimpleMapperTest; private Button FileExtensionTest; + private Button OsInfoBtn; } diff --git a/demo/MainMenu.cs b/demo/MainMenu.cs index c85a8f8..e4acabc 100644 --- a/demo/MainMenu.cs +++ b/demo/MainMenu.cs @@ -23,4 +23,10 @@ public sealed partial class MainMenu: Form FileHashAndMimeType formTest = new(); formTest.ShowDialog(); } + + private void OsInfoBtn_Click (object sender, EventArgs e) + { + OsInfoFrm formTest = new(); + formTest.ShowDialog(); + } } diff --git a/demo/OsInfoFrm.Designer.cs b/demo/OsInfoFrm.Designer.cs new file mode 100644 index 0000000..3602c5a --- /dev/null +++ b/demo/OsInfoFrm.Designer.cs @@ -0,0 +1,65 @@ +namespace demo; + +sealed partial class OsInfoFrm +{ + /// + /// 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 Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + this.textBox = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // textBox + // + this.textBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBox.Location = new System.Drawing.Point(0, 0); + this.textBox.Multiline = true; + this.textBox.Name = "textBox"; + this.textBox.Size = new System.Drawing.Size(1029, 510); + this.textBox.TabIndex = 0; + // + // OsInfoFrm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1029, 510); + this.Controls.Add(this.textBox); + this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "OsInfoFrm"; + this.Text = "Информация о системе"; + this.Load += new System.EventHandler(this.OsInfoFrm_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private TextBox textBox; +} \ No newline at end of file diff --git a/demo/OsInfoFrm.cs b/demo/OsInfoFrm.cs new file mode 100644 index 0000000..df8694b --- /dev/null +++ b/demo/OsInfoFrm.cs @@ -0,0 +1,28 @@ +using anbs_cp.Classes; + +using Newtonsoft.Json; + +namespace demo; +public sealed partial class OsInfoFrm: Form +{ + public OsInfoFrm () + { + InitializeComponent(); + } + + private void OsInfoFrm_Load (object sender, EventArgs e) + { + textBox.Text = @"Процессор(ы) | "; + textBox.Text += JsonConvert.SerializeObject(OsInfo.Processors); + textBox.Text += @"Оперативная память | "; + textBox.Text += JsonConvert.SerializeObject(OsInfo.RAM); + textBox.Text += @"Видеокарта | "; + textBox.Text += JsonConvert.SerializeObject(OsInfo.Videos); + textBox.Text += @"Диски | "; + textBox.Text += JsonConvert.SerializeObject(OsInfo.Drives); + textBox.Text += @"Windows | "; + textBox.Text += JsonConvert.SerializeObject(OsInfo.Windows); + textBox.Text += @"Net | "; + textBox.Text += JsonConvert.SerializeObject(OsInfo.Net); + } +} diff --git a/demo/OsInfoFrm.resx b/demo/OsInfoFrm.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/demo/OsInfoFrm.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file From c89a6b2a7176e205e9d58ee2d50a66a8b0113eff Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 20 Jan 2023 16:22:37 +0300 Subject: [PATCH 19/51] 20230120 --- anbs_cp/Classes/Encrypt/EncriptKey.cs | 48 ++++++++++++++++++++++ anbs_cp/Classes/Encrypt/StringEncrypt.cs | 48 ++++++++++++++++++++++ anbs_cp/Interfaces/IEncryptKey.cs | 12 ++++++ anbs_cp/anbs_cp.csproj | 6 +-- anbsoftware.componentspack.sln.DotSettings | 1 + 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 anbs_cp/Classes/Encrypt/EncriptKey.cs create mode 100644 anbs_cp/Classes/Encrypt/StringEncrypt.cs create mode 100644 anbs_cp/Interfaces/IEncryptKey.cs diff --git a/anbs_cp/Classes/Encrypt/EncriptKey.cs b/anbs_cp/Classes/Encrypt/EncriptKey.cs new file mode 100644 index 0000000..92b0cda --- /dev/null +++ b/anbs_cp/Classes/Encrypt/EncriptKey.cs @@ -0,0 +1,48 @@ +using System.Text; + +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes.Encrypt; + +/// +/// Ключ шифровки / расшифровки +/// +public class EncryptKey: IEncryptKey +{ + /// + /// Конструктор по умолчанию + /// + /// Ключ в формате массива + public EncryptKey (byte[] key) => Key = key; + + /// + /// Конструктор, принимающий строку и преобразующий в нужный формат + /// + /// Ключ в формате + public EncryptKey (string key) => Key = Encoding.ASCII.GetBytes(key); + + /// + /// Ключ + /// + public byte[] Key { get; set; } + + /// + /// Получение ключа по умолчанию + /// + /// + public static EncryptKey GetDefault () => new(Enumerable.Range(0, 32).Select(static x => (byte)x).ToArray()); + + /// + /// Получение класса ключа + /// + /// Ключ в формате массива + /// + public static EncryptKey GetKey (byte[]? key) => key != null ? new(key) : GetDefault(); + + /// + /// Получение класса ключа + /// + /// Ключ в формате массива + /// + public static EncryptKey GetKey (string key) => !string.IsNullOrWhiteSpace(key) ? new(key) : GetDefault(); +} \ No newline at end of file diff --git a/anbs_cp/Classes/Encrypt/StringEncrypt.cs b/anbs_cp/Classes/Encrypt/StringEncrypt.cs new file mode 100644 index 0000000..f0e7444 --- /dev/null +++ b/anbs_cp/Classes/Encrypt/StringEncrypt.cs @@ -0,0 +1,48 @@ +using System.Security.Cryptography; +using System.Text; + +namespace anbs_cp.Classes.Encrypt; + +/// +/// Класс для шифровки строк +/// +public static class StringEncrypt +{ + /// + /// Метод для шифрования строки с помощью ключа + /// + /// Строка, которая должна быть зашифрована + /// Ключ шифрования (в случае null) + /// Этот статический метод возвращает зашифрованную строку с помощью ключа шифрования + public static string Encrypt (string text, EncryptKey? key = null) + { + using Aes aes = Aes.Create(); + aes.Key = key?.Key ?? EncryptKey.GetDefault().Key; + using MemoryStream ms = new(); + ms.Write(aes.IV); + using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) + cs.Write(Encoding.UTF8.GetBytes(text)); + + return Convert.ToBase64String(ms.ToArray()); + } + + /// + /// Метод для дешифрования строки с помощью ключа + /// + /// Строка, которая должна быть дешифрована + /// Ключ шифрования (в случае null) + /// Этот статический метод возвращает дешифрованную строку с помощью ключа шифрования + public static string Decrypt (string text, EncryptKey? key = null) + { + using MemoryStream ms = new(Convert.FromBase64String(text)); + byte[] iv = new byte[16]; + int _ = ms.Read(iv); + using Aes aes = Aes.Create(); + aes.Key = key?.Key ?? EncryptKey.GetDefault().Key; + aes.IV = iv; + using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); + using MemoryStream output = new(); + cs.CopyTo(output); + return Encoding.UTF8.GetString(output.ToArray()); + } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IEncryptKey.cs b/anbs_cp/Interfaces/IEncryptKey.cs new file mode 100644 index 0000000..fedd43a --- /dev/null +++ b/anbs_cp/Interfaces/IEncryptKey.cs @@ -0,0 +1,12 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс ключа +/// +public interface IEncryptKey +{ + /// + /// Ключ + /// + public byte[] Key { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index dc0c637..59766de 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.115.0 + 2023.120.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ True https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack - 2023.115.0 - 2023.115.0 + + ANBSoftware.ComponentsPack MIT 6.0 diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index f451ee2..ebbe1a7 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -11,6 +11,7 @@ True True True + True True True True From e010f93b07492517bbfd67083e6cc4783964f33d Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 21 Jan 2023 17:04:00 +0300 Subject: [PATCH 20/51] 20230121 --- anbs_cp/Classes/Encrypt/EncriptKey.cs | 20 +++----------------- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/anbs_cp/Classes/Encrypt/EncriptKey.cs b/anbs_cp/Classes/Encrypt/EncriptKey.cs index 92b0cda..134c69f 100644 --- a/anbs_cp/Classes/Encrypt/EncriptKey.cs +++ b/anbs_cp/Classes/Encrypt/EncriptKey.cs @@ -7,7 +7,7 @@ namespace anbs_cp.Classes.Encrypt; /// /// Ключ шифровки / расшифровки /// -public class EncryptKey: IEncryptKey +public sealed class EncryptKey: IEncryptKey { /// /// Конструктор по умолчанию @@ -18,8 +18,8 @@ public class EncryptKey: IEncryptKey /// /// Конструктор, принимающий строку и преобразующий в нужный формат /// - /// Ключ в формате - public EncryptKey (string key) => Key = Encoding.ASCII.GetBytes(key); + /// Ключ в формате и в кодировке utf8 + public EncryptKey (string utf8Key) => Key = Encoding.UTF8.GetBytes(utf8Key); /// /// Ключ @@ -31,18 +31,4 @@ public class EncryptKey: IEncryptKey /// /// public static EncryptKey GetDefault () => new(Enumerable.Range(0, 32).Select(static x => (byte)x).ToArray()); - - /// - /// Получение класса ключа - /// - /// Ключ в формате массива - /// - public static EncryptKey GetKey (byte[]? key) => key != null ? new(key) : GetDefault(); - - /// - /// Получение класса ключа - /// - /// Ключ в формате массива - /// - public static EncryptKey GetKey (string key) => !string.IsNullOrWhiteSpace(key) ? new(key) : GetDefault(); } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 59766de..ae60b44 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.120.0 + 2023.121.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From 5b82e8034de13bb5c1e5b2c60d73c2e20b583e6e Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 21 Jan 2023 20:27:27 +0300 Subject: [PATCH 21/51] 20230121-1 --- anbs_cp/Classes/ActionState.cs | 22 +++++++++++----------- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/anbs_cp/Classes/ActionState.cs b/anbs_cp/Classes/ActionState.cs index 8cda85b..0a72407 100644 --- a/anbs_cp/Classes/ActionState.cs +++ b/anbs_cp/Classes/ActionState.cs @@ -5,8 +5,8 @@ namespace anbs_cp.Classes; /// /// Состояние действия /// -/// Обновлено 2023.01.104.1: -/// * Убрана ошибка с рекурсивным вызовом AddError +/// Обновлено 2023.01.121.1: +/// * Заменены интерфейсы IAction* на соответствующие классы /// public sealed class ActionState { @@ -23,17 +23,17 @@ public sealed class ActionState /// /// Список информации /// - public List Info { get; } + public List Info { get; } /// /// Список предупреждений /// - public List Warnings { get; } + public List Warnings { get; } /// /// Список ошибок /// - public List Errors { get; } + public List Errors { get; } #region Методы @@ -83,13 +83,13 @@ public sealed class ActionState /// Ошибка // ReSharper disable once MemberCanBeMadeStatic.Global // ReSharper disable once FunctionRecursiveOnAllPaths - public void AddError (IActionError error) => Errors.Add(error); + public void AddError (ActionError error) => Errors.Add(error); /// /// Добавляет ошибки в список /// /// Список ошибок - public void AddErrors(IEnumerable errors) => Errors.AddRange(errors); + public void AddErrors(IEnumerable errors) => Errors.AddRange(errors); /// /// Добавление ошибки @@ -139,13 +139,13 @@ public sealed class ActionState /// Добавление предупреждения /// /// Предупреждение - public void AddWarning (IActionWarning warning) => Warnings.Add(warning); + public void AddWarning (ActionWarning warning) => Warnings.Add(warning); /// /// Добавление предупреждений /// /// Список предупреждений - public void AddWarnings(IEnumerable warnings) => Warnings.AddRange(warnings); + public void AddWarnings(IEnumerable warnings) => Warnings.AddRange(warnings); /// /// Добавление предупреждение @@ -167,13 +167,13 @@ public sealed class ActionState /// Добавление информации /// /// Информация - public void AddInfo (IActionInfo info) => Info.Add(info); + public void AddInfo (ActionInfo info) => Info.Add(info); /// /// Добавление информации /// /// Список информации - public void AddInfos (IEnumerable infos) => Info.AddRange(infos); + public void AddInfos (IEnumerable infos) => Info.AddRange(infos); /// /// Добавление информации diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index ae60b44..b115968 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.121.0 + 2023.121.1 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From 480e88473330e89e5b23a3394dd28057ff40bceb Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 22 Jan 2023 15:47:19 +0300 Subject: [PATCH 22/51] 20230122 --- anbs_cp/Classes/Encrypt/EncriptKey.cs | 34 ---------------------- anbs_cp/Classes/Encrypt/StringEncrypt.cs | 37 +++++++----------------- anbs_cp/anbs_cp.csproj | 5 ++-- 3 files changed, 14 insertions(+), 62 deletions(-) delete mode 100644 anbs_cp/Classes/Encrypt/EncriptKey.cs diff --git a/anbs_cp/Classes/Encrypt/EncriptKey.cs b/anbs_cp/Classes/Encrypt/EncriptKey.cs deleted file mode 100644 index 134c69f..0000000 --- a/anbs_cp/Classes/Encrypt/EncriptKey.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Text; - -using anbs_cp.Interfaces; - -namespace anbs_cp.Classes.Encrypt; - -/// -/// Ключ шифровки / расшифровки -/// -public sealed class EncryptKey: IEncryptKey -{ - /// - /// Конструктор по умолчанию - /// - /// Ключ в формате массива - public EncryptKey (byte[] key) => Key = key; - - /// - /// Конструктор, принимающий строку и преобразующий в нужный формат - /// - /// Ключ в формате и в кодировке utf8 - public EncryptKey (string utf8Key) => Key = Encoding.UTF8.GetBytes(utf8Key); - - /// - /// Ключ - /// - public byte[] Key { get; set; } - - /// - /// Получение ключа по умолчанию - /// - /// - public static EncryptKey GetDefault () => new(Enumerable.Range(0, 32).Select(static x => (byte)x).ToArray()); -} \ No newline at end of file diff --git a/anbs_cp/Classes/Encrypt/StringEncrypt.cs b/anbs_cp/Classes/Encrypt/StringEncrypt.cs index f0e7444..87c46c2 100644 --- a/anbs_cp/Classes/Encrypt/StringEncrypt.cs +++ b/anbs_cp/Classes/Encrypt/StringEncrypt.cs @@ -1,5 +1,6 @@ -using System.Security.Cryptography; -using System.Text; +using System.Text; + +using gfoidl.Base64; namespace anbs_cp.Classes.Encrypt; @@ -9,40 +10,24 @@ namespace anbs_cp.Classes.Encrypt; public static class StringEncrypt { /// - /// Метод для шифрования строки с помощью ключа + /// Метод для шифрования строки /// /// Строка, которая должна быть зашифрована - /// Ключ шифрования (в случае null) /// Этот статический метод возвращает зашифрованную строку с помощью ключа шифрования - public static string Encrypt (string text, EncryptKey? key = null) + public static string Encrypt(string text) { - using Aes aes = Aes.Create(); - aes.Key = key?.Key ?? EncryptKey.GetDefault().Key; - using MemoryStream ms = new(); - ms.Write(aes.IV); - using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) - cs.Write(Encoding.UTF8.GetBytes(text)); - - return Convert.ToBase64String(ms.ToArray()); + byte[] byteText = Encoding.UTF8.GetBytes(text); + return Base64.Url.Encode(byteText); } /// - /// Метод для дешифрования строки с помощью ключа + /// Метод для дешифрования строки /// /// Строка, которая должна быть дешифрована - /// Ключ шифрования (в случае null) /// Этот статический метод возвращает дешифрованную строку с помощью ключа шифрования - public static string Decrypt (string text, EncryptKey? key = null) + public static string Decrypt (string text) { - using MemoryStream ms = new(Convert.FromBase64String(text)); - byte[] iv = new byte[16]; - int _ = ms.Read(iv); - using Aes aes = Aes.Create(); - aes.Key = key?.Key ?? EncryptKey.GetDefault().Key; - aes.IV = iv; - using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); - using MemoryStream output = new(); - cs.CopyTo(output); - return Encoding.UTF8.GetString(output.ToArray()); + string guidBase64Url = text.Replace('+', '-').Replace('/', '_').TrimEnd('='); + return Encoding.UTF8.GetString(Base64.Url.Decode(guidBase64Url)); } } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index b115968..7c28528 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -1,8 +1,8 @@ - + net7.0 - 2023.121.1 + 2023.122.1 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -37,6 +37,7 @@ + From 9afdd62f243ccfac5ff72cbd2c20ae3b104cdce5 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 29 Jan 2023 19:29:41 +0300 Subject: [PATCH 23/51] 20230129 --- anbs_cp/Classes/Encrypt/StringEncrypt.cs | 24 +++++++++++++++++++++--- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/anbs_cp/Classes/Encrypt/StringEncrypt.cs b/anbs_cp/Classes/Encrypt/StringEncrypt.cs index 87c46c2..71f11f2 100644 --- a/anbs_cp/Classes/Encrypt/StringEncrypt.cs +++ b/anbs_cp/Classes/Encrypt/StringEncrypt.cs @@ -13,21 +13,39 @@ public static class StringEncrypt /// Метод для шифрования строки /// /// Строка, которая должна быть зашифрована - /// Этот статический метод возвращает зашифрованную строку с помощью ключа шифрования - public static string Encrypt(string text) + /// Этот статический метод возвращает зашифрованную строку + public static string Encrypt (string text) { byte[] byteText = Encoding.UTF8.GetBytes(text); return Base64.Url.Encode(byteText); } + /// + /// Метод для шифрования массива строк + /// + /// Массив строк + /// Этот статический метод возвращает зашифрованную строку из массива + public static string EncryptBytes (byte[] bytes) => Base64.Url.Encode(bytes); + /// /// Метод для дешифрования строки /// /// Строка, которая должна быть дешифрована - /// Этот статический метод возвращает дешифрованную строку с помощью ключа шифрования + /// Этот статический метод возвращает дешифрованную строку public static string Decrypt (string text) { string guidBase64Url = text.Replace('+', '-').Replace('/', '_').TrimEnd('='); return Encoding.UTF8.GetString(Base64.Url.Decode(guidBase64Url)); } + + /// + /// Метод для дешифрования в массив byte + /// + /// Строка, которая должна быть дешифрована + /// Этот статический метод возвращает дешифрованный массива byte[] + public static byte[] DecryptBytes (string text) + { + string guidBase64Url = text.Replace('+', '-').Replace('/', '_').TrimEnd('='); + return Base64.Url.Decode(guidBase64Url); + } } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 7c28528..7e963ea 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.122.1 + 2023.129.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From 63b5cfeed8d1773eb1b6c5ac078f6a8c526fe93d Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 1 Feb 2023 21:19:41 +0300 Subject: [PATCH 24/51] 20230201 --- anbs_cp/Classes/Exceptions/RenameException.cs | 37 ++++++ anbs_cp/Classes/LikeDelphi.cs | 120 +++++++++++++++++- anbs_cp/Classes/ValueConverter.cs | 2 +- anbs_cp/Enums/EOnExistAction.cs | 32 +++++ anbs_cp/anbs_cp.csproj | 2 +- anbsoftware.componentspack.sln.DotSettings | 2 + 6 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 anbs_cp/Classes/Exceptions/RenameException.cs create mode 100644 anbs_cp/Enums/EOnExistAction.cs diff --git a/anbs_cp/Classes/Exceptions/RenameException.cs b/anbs_cp/Classes/Exceptions/RenameException.cs new file mode 100644 index 0000000..e8eb5d5 --- /dev/null +++ b/anbs_cp/Classes/Exceptions/RenameException.cs @@ -0,0 +1,37 @@ +namespace anbs_cp.Classes.Exceptions; + +/// +/// Класс-исключение для переименования папок/файлов +/// +public sealed class RenameException : Exception +{ + /// + /// Имя файла/папки + /// + public string FileName { get; } + + /// + /// Описание ошибки + /// + public string? ErrorMessage { get; } + + /// + /// Конструктор + /// + /// Имя файла/папки + /// Описание ошибки + public RenameException(string fileName, string? errorMessage) : base(GetMessage(fileName, errorMessage ?? string.Empty)) + { + FileName = fileName; + ErrorMessage = errorMessage; + } + + /// + /// Получение текстового представление ошибки + /// + /// Имя файла/папки + /// Описание ошибки + /// Текстовое представление ошибки + private static string GetMessage(string fileName, string errorMessage) => + $"При переименовании файла/папки {fileName} возникла следующая ошибка: {errorMessage}"; +} \ No newline at end of file diff --git a/anbs_cp/Classes/LikeDelphi.cs b/anbs_cp/Classes/LikeDelphi.cs index 9776f1a..09a8afc 100644 --- a/anbs_cp/Classes/LikeDelphi.cs +++ b/anbs_cp/Classes/LikeDelphi.cs @@ -1,4 +1,7 @@ -namespace anbs_cp.Classes; +using anbs_cp.Classes.Exceptions; +using anbs_cp.Enums; + +namespace anbs_cp.Classes; /// /// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#. @@ -10,7 +13,7 @@ public static class LikeDelphi /// /// Путь, к которому нужно добавить slash /// Путь со slash в конце - public static string IncludeTrailingBackslash(string path) + public static string IncludeTrailingBackslash (string path) { //По умолчанию сохраняем путь string result = path; @@ -29,5 +32,116 @@ public static class LikeDelphi /// Строка, которую нужно разбить /// Символ-делитель строки /// Массив строк - public static List ParseString(string str, char delimiter) => str.Split(delimiter).ToList(); + public static List ParseString (string str, char delimiter) => str.Split(delimiter).ToList(); + + /// + /// Переименовываю файл + /// + /// Старое имя файла (с полным путём) + /// Новое имя файла (с полным путём) + /// Что делать, если существует + /// Если имеет значение RaiseException, то генерируется ошибка переименования файла + public static void RenameFile (string oldName, string newName, + EOnExistAction ifExist = EOnExistAction.RaiseException) + { + //Если целевой файл существует + if (File.Exists(newName)) + switch (ifExist) + { + //Возбуждать исключение + case EOnExistAction.RaiseException: + throw new RenameException(newName, "Файл уже существует!"); + //Прерываю + case EOnExistAction.Abort: + return; + //Игнорирую и перезаписываю файл + case EOnExistAction.Ignore: + break; + //Только для папок (для файлов равносилен RaiseException) + case EOnExistAction.RaiseExceptionIfNotEmpty: + throw new RenameException(newName, "Файл уже существует!"); + //Только для папок (для файлов равносилен Abort) + case EOnExistAction.AbortIfNotEmpty: + return; + //по умолчанию - RaiseException + default: + throw new RenameException(newName, "Файл уже существует!"); + } + + //Перемещаю файл + File.Move(oldName, newName, true); + + //Если начальный файл существует + if (File.Exists(oldName)) + //- удаляю его + File.Delete(oldName); + } + + /// + /// Удаление папки + /// + /// Папка + public static void RemoveDir (string dir) => Directory.Delete(dir, true); + + /// + /// Проверяет папку на пустоту + /// Оригинальный ответ от OwenGlendower (https://www.cyberforum.ru/windows-forms/thread1995240.html) + /// + /// Проверяемая папка + /// Пуста (true) или не пуста (false) папка + public static bool IsDirEmpty (string dir) => !Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories).Any(); + + /// + /// Переименовывает папку + /// + /// Старое имя папки (с полным путём) + /// Новое имя папки (с полным путём) + /// Что делать, если существует + /// Если имеет значение RaiseException, то генерируется ошибка переименования папки + public static void RenameDir (string oldName, string newName, + EOnExistAction ifExist = EOnExistAction.RaiseException) + { + //Если целевая папка существует + if (Directory.Exists(newName)) + { + switch (ifExist) + { + //Возбуждать исключение + case EOnExistAction.RaiseException: + throw new RenameException(newName, "Папка уже существует!"); + //Прерывать + case EOnExistAction.Abort: + return; + //Игнорировать и перезаписывать папку + case EOnExistAction.Ignore: + break; + //Возбуждать исключение, если не пустая + case EOnExistAction.RaiseExceptionIfNotEmpty: + if (!IsDirEmpty(newName)) + throw new RenameException(newName, "Папка уже существует и не пуста!"); + + break; + //Прерывать, если не пустая + case EOnExistAction.AbortIfNotEmpty: + if (!IsDirEmpty(newName)) + return; + + break; + //по умолчанию - RaiseException + default: + throw new RenameException(newName, "Папка уже существует!"); + } + + //Удаляю целевую папку + RemoveDir(newName); + } + + //Перемещаю папку + Directory.Move(oldName, newName); + + //Если начальная папка существует + if (Directory.Exists(oldName)) + //- удаляю его + RemoveDir(oldName); + } } \ No newline at end of file diff --git a/anbs_cp/Classes/ValueConverter.cs b/anbs_cp/Classes/ValueConverter.cs index 8bb82ae..ca89b23 100644 --- a/anbs_cp/Classes/ValueConverter.cs +++ b/anbs_cp/Classes/ValueConverter.cs @@ -17,7 +17,7 @@ public abstract class ValueConverter: IValueConverter { ValueNames = valueNames; Divider = divider; - DecimalPlaces = (byte)(decimalPlaces < 3 ? decimalPlaces : 2); + DecimalPlaces = (byte)(decimalPlaces < 3 ? decimalPlaces : 2); } #region Реализация интерфейса diff --git a/anbs_cp/Enums/EOnExistAction.cs b/anbs_cp/Enums/EOnExistAction.cs new file mode 100644 index 0000000..345050d --- /dev/null +++ b/anbs_cp/Enums/EOnExistAction.cs @@ -0,0 +1,32 @@ +namespace anbs_cp.Enums; + +/// +/// Действия при операции переименования, если файл существует +/// +public enum EOnExistAction +{ + /// + /// Возбуждать исключение + /// + RaiseException = 0, + + /// + /// Прервать операцию + /// + Abort = 1, + + /// + /// Продолжить операцию + /// + Ignore = 2, + + /// + /// Возбуждать исключение, если папка не пуста (только для папок) + /// + RaiseExceptionIfNotEmpty = 3, + + /// + /// Прервать операцию, если папка не пуста (только для папок) + /// + AbortIfNotEmpty = 4 +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 7e963ea..b3185b3 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.129.0 + 2023.201.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index ebbe1a7..08f8a10 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -5,6 +5,7 @@ RA RAM True + True True True True @@ -13,6 +14,7 @@ True True True + True True True True From 6fd3f41e31de2261942cfbe63e8dce44a5e3bbd2 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 4 Feb 2023 12:02:16 +0300 Subject: [PATCH 25/51] 20230204 --- anbs_cp/Classes/FileExtensions.cs | 42 --------------------------- anbs_cp/Classes/FileHash.cs | 48 +++++++++++++++++++++++++++++++ anbs_cp/anbs_cp.csproj | 2 +- demo/FileHashAndMimeTypeTest.cs | 2 +- 4 files changed, 50 insertions(+), 44 deletions(-) create mode 100644 anbs_cp/Classes/FileHash.cs diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs index a0b278a..478586f 100644 --- a/anbs_cp/Classes/FileExtensions.cs +++ b/anbs_cp/Classes/FileExtensions.cs @@ -9,48 +9,6 @@ namespace anbs_cp.Classes; /// public static class FileExtension { - /// - /// Получение md5-хэша файла. - /// Взято с https://stackoverflow.com/a/24031467/16469671 - /// - /// Имя файла - /// Массив хэша - public static byte[] Hash (string fileName) - { - using MD5 md5 = MD5.Create(); - byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(fileName); - byte[] result = md5.ComputeHash(inputBytes); - - return result; - } - - /// - /// Получение md5-хэша загружаемого файла. - /// Взято с https://stackoverflow.com/a/67081012/16469671 - /// - /// Загружаемый файл - /// Массив хэша - public static byte[] Hash (IFormFile file) - { - using MD5 md5 = MD5.Create(); - using StreamReader streamReader = new(file.OpenReadStream()); - return md5.ComputeHash(streamReader.BaseStream); - } - - /// - /// Получение md5-хэша файла и вывод в строке. - /// - /// Имя файла - /// Срока с хэшем файла - public static string HashString (string fileName) => Convert.ToHexString(Hash(fileName)); - - /// - /// Получение md5-хэша файла и вывод в строке. - /// - /// Загружаемый файл - /// Срока с хэшем файла - public static string HashString (IFormFile file) => Convert.ToHexString(Hash(file)); - /// /// Получает MIME-тип файла /// diff --git a/anbs_cp/Classes/FileHash.cs b/anbs_cp/Classes/FileHash.cs new file mode 100644 index 0000000..b1453be --- /dev/null +++ b/anbs_cp/Classes/FileHash.cs @@ -0,0 +1,48 @@ +using System.Security.Cryptography; + +using Microsoft.AspNetCore.Http; + +namespace anbs_cp.Classes; + +/// +/// Класс для работы с хэшем файла +/// +public class FileHash +{ + /// + /// Получение md5-хэша файла. + /// Взято с https://stackoverflow.com/a/24031467/16469671 + /// + /// Имя файла + /// Массив хэша + public FileHash (string fileName) + { + using MD5 md5 = MD5.Create(); + using FileStream stream = File.OpenRead(fileName); + Hash = md5.ComputeHash(stream); + } + + /// + /// Получение md5-хэша загружаемого файла. + /// Взято с https://stackoverflow.com/a/67081012/16469671 + /// + /// Загружаемый файл + /// Массив хэша + public FileHash (IFormFile file) + { + using MD5 md5 = MD5.Create(); + using StreamReader streamReader = new(file.OpenReadStream()); + Hash = md5.ComputeHash(streamReader.BaseStream); + } + + /// + /// Хэш файла + /// + public byte[] Hash { get; } + + /// + /// Вывод в строку + /// + /// Строка хэша файла + public override string ToString () => BitConverter.ToString(Hash).Replace("-", "").ToLowerInvariant(); +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index b3185b3..bdbb49c 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.201.0 + 2023.204.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. diff --git a/demo/FileHashAndMimeTypeTest.cs b/demo/FileHashAndMimeTypeTest.cs index 0cc25ad..69f7cf4 100644 --- a/demo/FileHashAndMimeTypeTest.cs +++ b/demo/FileHashAndMimeTypeTest.cs @@ -23,7 +23,7 @@ private void GetFileHashAndMimeType() return; } - string fileHash = FileExtension.HashString(fileNameEdt.Text); + string fileHash = new FileHash(fileNameEdt.Text).ToString(); string fileType = FileExtension.MIMEType(fileNameEdt.Text); ResultLabel.Text = From 553b5b0ec3e3283471bce016a34555c72b6e298c Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 11 Feb 2023 08:15:03 +0300 Subject: [PATCH 26/51] 20230211 --- anbs_cp/Classes/FileHash.cs | 23 +++++++++++++++++++++-- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/anbs_cp/Classes/FileHash.cs b/anbs_cp/Classes/FileHash.cs index b1453be..73ca448 100644 --- a/anbs_cp/Classes/FileHash.cs +++ b/anbs_cp/Classes/FileHash.cs @@ -1,4 +1,5 @@ using System.Security.Cryptography; +using System.Text; using Microsoft.AspNetCore.Http; @@ -7,7 +8,7 @@ namespace anbs_cp.Classes; /// /// Класс для работы с хэшем файла /// -public class FileHash +public sealed class FileHash { /// /// Получение md5-хэша файла. @@ -35,14 +36,32 @@ public class FileHash Hash = md5.ComputeHash(streamReader.BaseStream); } + /// + /// Простой конструктор + /// + public FileHash () + { + Hash = new byte[] { }; + } + /// /// Хэш файла /// - public byte[] Hash { get; } + public byte[] Hash { get; private set; } /// /// Вывод в строку /// /// Строка хэша файла public override string ToString () => BitConverter.ToString(Hash).Replace("-", "").ToLowerInvariant(); + + /// + /// Конвертирует строку в хэш + /// + /// Строка + public void FromString (string value) + { + UTF8Encoding utf8 = new(); + Hash = utf8.GetBytes(value); + } } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index bdbb49c..2003061 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.204.0 + 2023.211.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From 05bf341ba42056fe69a6951bf5bbec3b639972ae Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 13 Feb 2023 13:13:26 +0300 Subject: [PATCH 27/51] 20230212 --- anbs_cp/Classes/OsInfo.cs | 438 ++++++++++++++++++++++---------------- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 251 insertions(+), 189 deletions(-) diff --git a/anbs_cp/Classes/OsInfo.cs b/anbs_cp/Classes/OsInfo.cs index adbc3eb..ad059bc 100644 --- a/anbs_cp/Classes/OsInfo.cs +++ b/anbs_cp/Classes/OsInfo.cs @@ -51,6 +51,9 @@ public static class OsInfo /// public static List Drives { get; set; } + /// + /// Сеть + /// public static List Net { get; set; } #region Служебные методы @@ -73,47 +76,61 @@ public static class OsInfo /// Список информации о процессорах private static List GetProcessors () { - //Создаю результирующий список - List processorsList = new(); - - //Создаю классы менеджмента - ManagementClass management = new("Win32_Processor"); - ManagementObjectCollection collection = management.GetInstances(); - - //Получаю число процессоров - int processorsCount = collection.Cast() - .Select(static a => a.Properties["ProcessorId"].Value.ToString()).Count(); - - //Перебираю массив данных - for (int ind = 0; ind < processorsCount; ind++) + try { - //Создаю элемент информации о процессоре - OsProcessorInfo processor = new() + //Создаю результирующий список + List processorsList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_Processor"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число процессоров + int processorsCount = collection.Cast() + .Select(static a => a.Properties["ProcessorId"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < processorsCount; ind++) { - Caption = collection.Cast() - .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), - Description = collection.Cast() - .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), - DeviceId = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), - Manufacturer = collection.Cast() - .Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind), - MaxClockSpeed = TypeConverter.StrToInt(collection.Cast() - .Select(static a => a.Properties["MaxClockSpeed"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), - Name = collection.Cast() - .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), - NumberOfCores = TypeConverter.StrToInt(collection.Cast() - .Select(static a => a.Properties["NumberOfCores"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), - NumberOfLogicalProcessors = TypeConverter.StrToInt(collection.Cast() - .Select(static a => a.Properties["NumberOfLogicalProcessors"].Value.ToString()).ElementAtOrDefault(ind) ?? "0") - }; + //Создаю элемент информации о процессоре + OsProcessorInfo processor = new() + { + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + Manufacturer = collection.Cast() + .Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind), + MaxClockSpeed = TypeConverter.StrToInt(collection.Cast() + .Select(static a => + a.Properties["MaxClockSpeed"].Value.ToString()) + .ElementAtOrDefault(ind) ?? + "0"), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + NumberOfCores = TypeConverter.StrToInt(collection.Cast() + .Select(static a => + a.Properties["NumberOfCores"].Value.ToString()) + .ElementAtOrDefault(ind) ?? + "0"), + NumberOfLogicalProcessors = TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["NumberOfLogicalProcessors"].Value.ToString()) + .ElementAtOrDefault(ind) ?? "0") + }; - //Добавляю в список - processorsList.Add(processor); + //Добавляю в список + processorsList.Add(processor); + } + + //Возвращаю список + return processorsList; + } + catch (NullReferenceException) + { + return new(); } - - //Возвращаю список - return processorsList; } /// @@ -122,13 +139,20 @@ public static class OsInfo /// Список информации о количестве оперативной памяти private static ulong GetRAMs () { - //Создаю классы менеджмента - ManagementClass management = new("Win32_ComputerSystem"); - ManagementObjectCollection collection = management.GetInstances(); + try + { + //Создаю классы менеджмента + ManagementClass management = new("Win32_ComputerSystem"); + ManagementObjectCollection collection = management.GetInstances(); - //Получаю результат - return TypeConverter.StrToUInt64(collection.Cast() - .Select(static a => a.Properties["TotalPhysicalMemory"].Value.ToString()).FirstOrDefault() ?? "0"); + //Получаю результат + return TypeConverter.StrToUInt64(collection.Cast() + .Select(static a => a.Properties["TotalPhysicalMemory"].Value.ToString()).FirstOrDefault() ?? "0"); + } + catch (NullReferenceException) + { + return 0; + } } /// @@ -137,56 +161,63 @@ public static class OsInfo /// Список информации о видеоадаптерах private static List GetVideoAdapterInfos () { - //Создаю результирующий список - List videosList = new(); - - //Создаю классы менеджмента - ManagementClass management = new("Win32_VideoController"); - ManagementObjectCollection collection = management.GetInstances(); - - //Получаю число адаптеров - int count = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); - - //Перебираю массив данных - for (int ind = 0; ind < count; ind++) + try { - //Создаю элемент информации об адаптере - OsVideoAdapterInfo adapter = new() + //Создаю результирующий список + List videosList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_VideoController"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число адаптеров + int count = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < count; ind++) { - Caption = collection.Cast() - .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), - Description = collection.Cast() - .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), - DeviceId = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), - AdapterRAM = TypeConverter.StrToInt(collection.Cast() - .Select(static a => a.Properties["AdapterRAM"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), - DriverDate = collection.Cast() - .Select(static a => a.Properties["DriverDate"].Value.ToString()).ElementAtOrDefault(ind), - Name = collection.Cast() - .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), - CurrentResolution = (TypeConverter.StrToInt(collection.Cast() - .Select(static a => a.Properties["CurrentHorizontalResolution"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), - TypeConverter.StrToInt(collection.Cast() - .Select(static a => a.Properties["CurrentVerticalResolution"].Value.ToString()) - .ElementAtOrDefault(ind) ?? "0")), - SystemName = collection.Cast() - .Select(static a => a.Properties["SystemName"].Value.ToString()).ElementAtOrDefault(ind), - DriverVersion = collection.Cast() - .Select(static a => a.Properties["DriverVersion"].Value.ToString()).ElementAtOrDefault(ind), - InstalledDisplayDrivers = collection.Cast() - .Select(static a => a.Properties["InstalledDisplayDrivers"].Value.ToString()).ElementAtOrDefault(ind), - VideoProcessor = collection.Cast() - .Select(static a => a.Properties["VideoProcessor"].Value.ToString()).ElementAtOrDefault(ind) - }; + //Создаю элемент информации об адаптере + OsVideoAdapterInfo adapter = new() + { + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + AdapterRAM = TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["AdapterRAM"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + DriverDate = collection.Cast() + .Select(static a => a.Properties["DriverDate"].Value.ToString()).ElementAtOrDefault(ind), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + CurrentResolution = (TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["CurrentHorizontalResolution"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + TypeConverter.StrToInt(collection.Cast() + .Select(static a => a.Properties["CurrentVerticalResolution"].Value.ToString()) + .ElementAtOrDefault(ind) ?? "0")), + SystemName = collection.Cast() + .Select(static a => a.Properties["SystemName"].Value.ToString()).ElementAtOrDefault(ind), + DriverVersion = collection.Cast() + .Select(static a => a.Properties["DriverVersion"].Value.ToString()).ElementAtOrDefault(ind), + InstalledDisplayDrivers = collection.Cast() + .Select(static a => a.Properties["InstalledDisplayDrivers"].Value.ToString()).ElementAtOrDefault(ind), + VideoProcessor = collection.Cast() + .Select(static a => a.Properties["VideoProcessor"].Value.ToString()).ElementAtOrDefault(ind) + }; - //Добавляю в список - videosList.Add(adapter); + //Добавляю в список + videosList.Add(adapter); + } + + //Возвращаю список + return videosList; + } + catch (NullReferenceException) + { + return new(); } - - //Возвращаю список - return videosList; } /// @@ -195,17 +226,24 @@ public static class OsInfo /// Список информации о дисках private static List GetDriveInfos () { - //Создаю результат - List result = new(); + try + { + //Создаю результат + List result = new(); - //Добавление всех HDD/SSD дисков - result.AddRange(GetHDDs()); + //Добавление всех HDD/SSD дисков + result.AddRange(GetHDDs()); - //Добавление всех CD/DVD/BD дисков - result.AddRange(GetCDRom()); + //Добавление всех CD/DVD/BD дисков + result.AddRange(GetCDRom()); - //Вывожу список - return result; + //Вывожу список + return result; + } + catch (NullReferenceException) + { + return new(); + } } /// @@ -214,44 +252,51 @@ public static class OsInfo /// Информация обо всех HDD/SSD дисках private static List GetHDDs () { - //Создаю результирующий список - List driveList = new(); - - //Создаю классы менеджмента - ManagementClass management = new("Win32_DiskDrive"); - ManagementObjectCollection collection = management.GetInstances(); - - //Получаю число адаптеров - int count = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); - - //Перебираю массив данных - for (int ind = 0; ind < count; ind++) + try { - //Создаю элемент информации об адаптере - OsDriveInfo drive = new() + //Создаю результирующий список + List driveList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_DiskDrive"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число адаптеров + int count = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < count; ind++) { - Type = EDriveType.DtHardDisc, - Caption = collection.Cast() - .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), - Description = collection.Cast() - .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), - DeviceId = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), - Name = collection.Cast() - .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), - TotalSize = TypeConverter.StrToUInt64(collection.Cast() - .Select(static a => a.Properties["Size"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), - Model = collection.Cast() - .Select(static a => a.Properties["Model"].Value.ToString()).ElementAtOrDefault(ind) - }; + //Создаю элемент информации об адаптере + OsDriveInfo drive = new() + { + Type = EDriveType.DtHardDisc, + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + TotalSize = TypeConverter.StrToUInt64(collection.Cast() + .Select(static a => a.Properties["Size"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"), + Model = collection.Cast() + .Select(static a => a.Properties["Model"].Value.ToString()).ElementAtOrDefault(ind) + }; - //Добавляю в список - driveList.Add(drive); + //Добавляю в список + driveList.Add(drive); + } + + //Возвращаю список + return driveList; + } + catch (NullReferenceException) + { + return new(); } - - //Возвращаю список - return driveList; } /// @@ -260,44 +305,51 @@ public static class OsInfo /// Информация обо всех CD/DVD/BD дисках private static List GetCDRom () { - //Создаю результирующий список - List driveList = new(); - - //Создаю классы менеджмента - ManagementClass management = new("Win32_CDROMDrive"); - ManagementObjectCollection collection = management.GetInstances(); - - //Получаю число адаптеров - int count = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); - - //Перебираю массив данных - for (int ind = 0; ind < count; ind++) + try { - //Создаю элемент информации об адаптере - OsDriveInfo drive = new() + //Создаю результирующий список + List driveList = new(); + + //Создаю классы менеджмента + ManagementClass management = new("Win32_CDROMDrive"); + ManagementObjectCollection collection = management.GetInstances(); + + //Получаю число адаптеров + int count = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).Count(); + + //Перебираю массив данных + for (int ind = 0; ind < count; ind++) { - Type = EDriveType.DtCDRom, - Caption = collection.Cast() - .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), - Description = collection.Cast() - .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), - DeviceId = collection.Cast() - .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), - Name = collection.Cast() - .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), - //Ставится 0, чтобы не проверять корректность загрузки и читаемость диска, а также избежать удлинения получения информации - TotalSize = 0, - Model = collection.Cast() - .Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind) - }; + //Создаю элемент информации об адаптере + OsDriveInfo drive = new() + { + Type = EDriveType.DtCDRom, + Caption = collection.Cast() + .Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind), + Description = collection.Cast() + .Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind), + DeviceId = collection.Cast() + .Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind), + Name = collection.Cast() + .Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind), + //Ставится 0, чтобы не проверять корректность загрузки и читаемость диска, а также избежать удлинения получения информации + TotalSize = 0, + Model = collection.Cast() + .Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind) + }; - //Добавляю в список - driveList.Add(drive); + //Добавляю в список + driveList.Add(drive); + } + + //Возвращаю список + return driveList; + } + catch (NullReferenceException) + { + return new(); } - - //Возвращаю список - return driveList; } /// @@ -306,35 +358,45 @@ public static class OsInfo /// Информация о сети интернет private static List GetNet () { - //Создаю результирующий список - List netList = new(); - - //Получаю информацию о всех сетевых интерфейсах - foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) + try { - //Создаю элемент - OsNetInfo netInfo = new() - { - Name = adapter.Name, - Description = adapter.Description, - MacAddress = adapter.OperationalStatus == OperationalStatus.Up ? adapter.GetPhysicalAddress().ToString() : null - }; + //Создаю результирующий список + List netList = new(); - //Получаю IP-адрес - foreach (UnicastIPAddressInformation info in adapter.GetIPProperties().UnicastAddresses.Where(static info => - info.Address.AddressFamily == AddressFamily.InterNetwork && info.IsDnsEligible)) + //Получаю информацию о всех сетевых интерфейсах + foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) { - if (!string.IsNullOrWhiteSpace(netInfo.IPAddress)) - netInfo.IPAddress += ";"; - netInfo.IPAddress += info.Address.ToString(); + //Создаю элемент + OsNetInfo netInfo = new() + { + Name = adapter.Name, + Description = adapter.Description, + MacAddress = adapter.OperationalStatus == OperationalStatus.Up + ? adapter.GetPhysicalAddress().ToString() + : null + }; + + //Получаю IP-адрес + foreach (UnicastIPAddressInformation info in adapter.GetIPProperties().UnicastAddresses.Where( + static info => + info.Address.AddressFamily == AddressFamily.InterNetwork && info.IsDnsEligible)) + { + if (!string.IsNullOrWhiteSpace(netInfo.IPAddress)) + netInfo.IPAddress += ";"; + netInfo.IPAddress += info.Address.ToString(); + } + + //Добавляю адаптер + netList.Add(netInfo); } - //Добавляю адаптер - netList.Add(netInfo); + //Возвращаю список + return netList; + } + catch (NullReferenceException) + { + return new(); } - - //Возвращаю список - return netList; } #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index bdbb49c..9b03e5b 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.204.0 + 2023.212.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From 455e88635aedaf4b0554cf787e9f4b99a5db7919 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 9 Apr 2023 10:56:43 +0300 Subject: [PATCH 28/51] 20230409 --- anbs_cp/Classes/ConsoleParamsParser.cs | 61 ++++++++++++++++++++++++++ anbs_cp/anbs_cp.csproj | 6 +-- 2 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 anbs_cp/Classes/ConsoleParamsParser.cs diff --git a/anbs_cp/Classes/ConsoleParamsParser.cs b/anbs_cp/Classes/ConsoleParamsParser.cs new file mode 100644 index 0000000..e7ff481 --- /dev/null +++ b/anbs_cp/Classes/ConsoleParamsParser.cs @@ -0,0 +1,61 @@ +namespace anbs_cp.Classes; + +/// +/// Обработчик параметров консоли +/// +public sealed class ConsoleParamsParser +{ + /// + /// Массив параметров + /// + private readonly List<(string, string?)> _paramsList; + + /// + /// Конструктор + /// + /// Параметры консоли + public ConsoleParamsParser (string[] consoleParams) + { + //Создаю список параметров + _paramsList = new(); + + //Заполняю его + foreach (string consoleParam in consoleParams) + { + //Индекс знака "=" + int eqPlace = consoleParam.IndexOf('='); + + //Получаю параметр + string param = eqPlace > -1 ? consoleParam[..eqPlace] : consoleParam; + + //Получаю значение параметра + string? value = eqPlace == -1 ? null : consoleParam[(eqPlace + 1)..].Trim(new[] { '"' }); + + //Сохраняю в списке + _paramsList.Add((param, value)); + } + } + + /// + /// Проверяет наличие параметра + /// + /// Параметр + /// Есть ли параметр в списке + public bool HasParam (string param) => + _paramsList.Any(keyValue => keyValue.Item1 == param); + + /// + /// Получает значение параметра + /// + /// + /// + public string? GetValue (string param) => + !HasParam(param) ? null : _paramsList.FirstOrDefault(keyValue => keyValue.Item1 == param).Item2; + + /// + /// Получает список всех параметров + /// + /// Список всех параметров + public List GetParamsList () => + _paramsList.Select(static keyValue => keyValue.Item1).ToList(); +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 9b03e5b..ceeed7b 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.212.0 + 2023.409.0 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -40,9 +40,9 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 5f753c48bf31ee8b8d8c98d66229c4ad7bbc2c5e Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 9 Apr 2023 21:07:52 +0300 Subject: [PATCH 29/51] 20230409-1 --- anbs_cp/Classes/ConsoleParamsParser.cs | 2 +- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/anbs_cp/Classes/ConsoleParamsParser.cs b/anbs_cp/Classes/ConsoleParamsParser.cs index e7ff481..6adf278 100644 --- a/anbs_cp/Classes/ConsoleParamsParser.cs +++ b/anbs_cp/Classes/ConsoleParamsParser.cs @@ -32,7 +32,7 @@ public sealed class ConsoleParamsParser string? value = eqPlace == -1 ? null : consoleParam[(eqPlace + 1)..].Trim(new[] { '"' }); //Сохраняю в списке - _paramsList.Add((param, value)); + _paramsList.Add((param.ToLower(), value)); } } diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index ceeed7b..4e78db6 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.409.0 + 2023.409.1 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From 09119bd2bad122f54c0b6a4cd839eba8f13e3ea5 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 9 Apr 2023 21:12:44 +0300 Subject: [PATCH 30/51] 20230409-2 --- anbs_cp/Classes/ConsoleParamsParser.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/anbs_cp/Classes/ConsoleParamsParser.cs b/anbs_cp/Classes/ConsoleParamsParser.cs index 6adf278..f932b55 100644 --- a/anbs_cp/Classes/ConsoleParamsParser.cs +++ b/anbs_cp/Classes/ConsoleParamsParser.cs @@ -42,7 +42,7 @@ public sealed class ConsoleParamsParser /// Параметр /// Есть ли параметр в списке public bool HasParam (string param) => - _paramsList.Any(keyValue => keyValue.Item1 == param); + _paramsList.Any(keyValue => keyValue.Item1 == param.ToLower()); /// /// Получает значение параметра @@ -50,12 +50,12 @@ public sealed class ConsoleParamsParser /// /// public string? GetValue (string param) => - !HasParam(param) ? null : _paramsList.FirstOrDefault(keyValue => keyValue.Item1 == param).Item2; + !HasParam(param) ? null : _paramsList.FirstOrDefault(keyValue => keyValue.Item1 == param.ToLower()).Item2; /// /// Получает список всех параметров /// /// Список всех параметров public List GetParamsList () => - _paramsList.Select(static keyValue => keyValue.Item1).ToList(); + _paramsList.Select(static keyValue => keyValue.Item1.ToLower()).ToList(); } \ No newline at end of file From ff965f08bd6ef51666161d90e2096d5e01985170 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 9 Apr 2023 21:22:22 +0300 Subject: [PATCH 31/51] 20230409-3 --- anbs_cp/anbs_cp.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 4e78db6..758d1b5 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.409.1 + 2023.409.2 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. From ef329af61a4434caca304e20e9a84b9abce656cc Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 14 May 2023 18:29:41 +0300 Subject: [PATCH 32/51] 20230514 --- anbs_cp/Classes/FileExtensions.cs | 14 +-- anbs_cp/Classes/FileHash.cs | 15 --- anbs_cp/Classes/PasswordOptions.cs | 50 ++++++++++ anbs_cp/Classes/TextFormatter.cs | 111 +++++++++++++++++++++ anbs_cp/Classes/TypeConverter.cs | 94 +++++++---------- anbs_cp/anbs_cp.csproj | 14 ++- anbs_cpfn/Classes/NetFileExtension.cs | 17 ++++ anbs_cpfn/Classes/NetFileHash.cs | 38 +++++++ anbs_cpfn/Classes/NetTypeConverter.cs | 35 +++++++ anbs_cpfn/Extensions/UrlHelperExtension.cs | 110 ++++++++++++++++++++ anbs_cpfn/anbs_cpfn.csproj | 38 +++++++ anbsoftware.componentspack.sln | 11 +- anbsoftware.componentspack.sln.DotSettings | 3 + 13 files changed, 455 insertions(+), 95 deletions(-) create mode 100644 anbs_cp/Classes/PasswordOptions.cs create mode 100644 anbs_cp/Classes/TextFormatter.cs create mode 100644 anbs_cpfn/Classes/NetFileExtension.cs create mode 100644 anbs_cpfn/Classes/NetFileHash.cs create mode 100644 anbs_cpfn/Classes/NetTypeConverter.cs create mode 100644 anbs_cpfn/Extensions/UrlHelperExtension.cs create mode 100644 anbs_cpfn/anbs_cpfn.csproj diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs index 478586f..2988845 100644 --- a/anbs_cp/Classes/FileExtensions.cs +++ b/anbs_cp/Classes/FileExtensions.cs @@ -1,8 +1,4 @@ -using System.Security.Cryptography; - -using Microsoft.AspNetCore.Http; - -namespace anbs_cp.Classes; +namespace anbs_cp.Classes; /// /// Класс -- расширение для класса File @@ -17,14 +13,6 @@ public static class FileExtension public static string MIMEType (string filename) => MimeTypes.GetMimeType(filename); - /// - /// Получает MIME-тип файла - /// - /// Загружаемый файл - /// MIME-тип файла - public static string MIMEType (IFormFile file) => - file.ContentType; - /// /// Размер файла в байтах /// diff --git a/anbs_cp/Classes/FileHash.cs b/anbs_cp/Classes/FileHash.cs index 73ca448..72b09da 100644 --- a/anbs_cp/Classes/FileHash.cs +++ b/anbs_cp/Classes/FileHash.cs @@ -1,8 +1,6 @@ using System.Security.Cryptography; using System.Text; -using Microsoft.AspNetCore.Http; - namespace anbs_cp.Classes; /// @@ -23,19 +21,6 @@ public sealed class FileHash Hash = md5.ComputeHash(stream); } - /// - /// Получение md5-хэша загружаемого файла. - /// Взято с https://stackoverflow.com/a/67081012/16469671 - /// - /// Загружаемый файл - /// Массив хэша - public FileHash (IFormFile file) - { - using MD5 md5 = MD5.Create(); - using StreamReader streamReader = new(file.OpenReadStream()); - Hash = md5.ComputeHash(streamReader.BaseStream); - } - /// /// Простой конструктор /// diff --git a/anbs_cp/Classes/PasswordOptions.cs b/anbs_cp/Classes/PasswordOptions.cs new file mode 100644 index 0000000..519f5de --- /dev/null +++ b/anbs_cp/Classes/PasswordOptions.cs @@ -0,0 +1,50 @@ +namespace anbs_cp.Classes; + +/// +/// Параметры пароля +/// +public sealed class PasswordOptions +{ + /// + /// Конструктор + /// + public PasswordOptions () + { + RequiredLength = 8; + RequireLowercase = true; + RequireUppercase = true; + RequireDigit = true; + RequireNonAlphanumeric = false; + RequiredUniqueChars = 6; + } + + /// + /// Требуемая длина пароля + /// + public byte RequiredLength { get; set; } + + /// + /// Требовать строчные буквы в пароле + /// + public bool RequireLowercase { get; set; } + + /// + /// Требовать прописные буквы в пароле + /// + public bool RequireUppercase { get; set; } + + /// + /// Требовать цифры в пароле + /// + public bool RequireDigit { get; set; } + + /// + /// Требовать символы + /// + public bool RequireNonAlphanumeric { get; set; } + + /// + /// Уникальных символов + /// + public byte RequiredUniqueChars { get; set; } +} \ No newline at end of file diff --git a/anbs_cp/Classes/TextFormatter.cs b/anbs_cp/Classes/TextFormatter.cs new file mode 100644 index 0000000..4d9e1c7 --- /dev/null +++ b/anbs_cp/Classes/TextFormatter.cs @@ -0,0 +1,111 @@ +using System.Net.Mail; + +namespace anbs_cp.Classes; + +/// +/// Форматирование текста +/// +public static class TextFormatter +{ + /// + /// Заменяет %МАРКЕРЫ% на их значения + /// + /// Текст сообщения + /// Словарь замен + /// Отформатированное сообщение + public static string FormatMessage (string message, Dictionary replaceDictionary) => + replaceDictionary.Aggregate(message, + static (current, item) => current.Replace($"%{item.Key}%", item.Value)); + + /// + /// Обрезает строку до указанных в параметре символов + /// + /// Текст, который нужно обрезать + /// Максимальное количество символов в тексте + /// Чем завершать обрезанный текст, если он был обрезан. Внимание расходует ! + /// Обрезанный текст + public static string GetShortText (string text, int maxLength, string endDots = "") => + text.Length < maxLength ? text : $"{text[..(maxLength - endDots.Length)]}{endDots}"; + + /// + /// Генерирует случайный пароль, удовлетворяющий параметрам . + /// Автор метода: Darkseal (https://stackoverflow.com/users/1233379/darkseal) + /// URL: https://stackoverflow.com/a/46229180/16469671 + /// + /// Объект допустимых параметров пароля, содержащий требования к надежности пароля. + /// Случайный пароль + public static string GenerateRandomPassword (PasswordOptions? options) + { + //Проверка options и установка по-умолчанию + options ??= new(); + + //Получаю массив символов + string[] randomChars = { + "ABCDEFGHJKLMNOPQRSTUVWXYZ", // прописные буквы + "abcdefghijkmnopqrstuvwxyz", // строчные буквы + "0123456789", // цифры + "~!@#$%^&*+-/.,{}[]();:|?<>='`" // символы + }; + + //Создаю объект Random + Random rand = new(Environment.TickCount); + + //Массив результатов + List chars = new(); + + //Вставляю прописные буквы + if (options.RequireUppercase) + chars.Insert(rand.Next(0, chars.Count), + randomChars[0][rand.Next(0, randomChars[0].Length)]); + + //Вставляю строчные буквы + if (options.RequireLowercase) + chars.Insert(rand.Next(0, chars.Count), + randomChars[1][rand.Next(0, randomChars[1].Length)]); + + //Вставляю цифры + if (options.RequireDigit) + chars.Insert(rand.Next(0, chars.Count), + randomChars[2][rand.Next(0, randomChars[2].Length)]); + + //Вставляю символы + if (options.RequireNonAlphanumeric) + chars.Insert(rand.Next(0, chars.Count), + randomChars[3][rand.Next(0, randomChars[3].Length)]); + + //Делаю выборку + for (int i = chars.Count; i < options.RequiredLength || chars.Distinct().Count() < options.RequiredUniqueChars; i++) + { + string rcs = randomChars[rand.Next(0, randomChars.Length)]; + chars.Insert(rand.Next(0, chars.Count), + rcs[rand.Next(0, rcs.Length)]); + } + + //Вывожу результат + return new(chars.ToArray()); + } + + /// + /// Проверяет на соответствие критерию электронной почты + /// Взято с: https://stackoverflow.com/a/1374644/16469671 + /// + /// Проверяемая строка + /// Является ли адресом электронной почты + public static bool IsValidEmail (string email) + { + string trimmedEmail = email.Trim(); + + if (trimmedEmail.EndsWith(".", StringComparison.Ordinal)) + return false; + + try + { + MailAddress addr = new(email); + return addr.Address == trimmedEmail; + } + catch + { + return false; + } + } +} \ No newline at end of file diff --git a/anbs_cp/Classes/TypeConverter.cs b/anbs_cp/Classes/TypeConverter.cs index 6139a0f..1760edb 100644 --- a/anbs_cp/Classes/TypeConverter.cs +++ b/anbs_cp/Classes/TypeConverter.cs @@ -1,7 +1,4 @@ -using System.Text.Encodings.Web; -using Microsoft.AspNetCore.Html; - -namespace anbs_cp.Classes; +namespace anbs_cp.Classes; /// /// Конвертер типов на манер Delphi @@ -13,37 +10,37 @@ public static class TypeConverter /// /// Преобразование int в string /// - /// Число + /// Число /// Строка - public static string IntToStr(int AInt) => AInt.ToString(); + public static string IntToStr (int aInt) => aInt.ToString(); /// /// Преобразование uint в string /// - /// Число + /// Число /// Строка - public static string IntToStr(uint AInt) => AInt.ToString(); + public static string IntToStr (uint aInt) => aInt.ToString(); /// /// Преобразование long в string /// - /// Число + /// Число /// Строка - public static string IntToStr(long AInt) => AInt.ToString(); + public static string IntToStr (long aInt) => aInt.ToString(); /// /// Преобразование ulong в string /// - /// Число + /// Число /// Строка - public static string IntToStr(ulong AInt) => AInt.ToString(); + public static string IntToStr (ulong aInt) => aInt.ToString(); /// /// Преобразование byte в string /// - /// Число + /// Число /// Строка - public static string IntToStr(byte AInt) => AInt.ToString(); + public static string IntToStr (byte aInt) => aInt.ToString(); #endregion @@ -52,86 +49,67 @@ public static class TypeConverter /// /// Преобразование строки в число /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) + /// Строка + /// Значение по умолчанию (по умолчанию, 0) /// Число - public static int StrToInt(string AStr, int ADefault = 0) + public static int StrToInt (string aStr, int aDefault = 0) { - if (!int.TryParse(AStr, out int result)) result = ADefault; + if (!int.TryParse(aStr, out int result)) + result = aDefault; return result; } /// /// Преобразование строки в число /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) + /// Строка + /// Значение по умолчанию (по умолчанию, 0) /// Число - public static uint StrToUInt(string AStr, uint ADefault = 0) + public static uint StrToUInt (string aStr, uint aDefault = 0) { - if (!uint.TryParse(AStr, out uint result)) result = ADefault; + if (!uint.TryParse(aStr, out uint result)) + result = aDefault; return result; } /// /// Преобразование строки в число /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) + /// Строка + /// Значение по умолчанию (по умолчанию, 0) /// Число - public static long StrToInt64(string AStr, long ADefault = 0) + public static long StrToInt64 (string aStr, long aDefault = 0) { - if (!long.TryParse(AStr, out long result)) result = ADefault; + if (!long.TryParse(aStr, out long result)) + result = aDefault; return result; } /// /// Преобразование строки в число /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) + /// Строка + /// Значение по умолчанию (по умолчанию, 0) /// Число - public static ulong StrToUInt64(string AStr, ulong ADefault = 0) + public static ulong StrToUInt64 (string aStr, ulong aDefault = 0) { - if (!ulong.TryParse(AStr, out ulong result)) result = ADefault; + if (!ulong.TryParse(aStr, out ulong result)) + result = aDefault; return result; } /// /// Преобразование строки в число /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) + /// Строка + /// Значение по умолчанию (по умолчанию, 0) /// Число - public static byte StrToByte(string AStr, byte ADefault = 0) + public static byte StrToByte (string aStr, byte aDefault = 0) { - if (!byte.TryParse(AStr, out byte result)) result = ADefault; + if (!byte.TryParse(aStr, out byte result)) + result = aDefault; return result; } #endregion - - #region Конвернтация IHtmlContent - /// - /// Преобразует тип в строку . - /// - /// Значение, которое нужно преобразовать. - /// - public static string HtmlContentToString(IHtmlContent content) - { - //Создаём writer - using StringWriter writer = new(); - //Конвертируем IHtmlContent в string - content.WriteTo(writer, HtmlEncoder.Default); - //Возвращаем результат - return writer.ToString(); - } - - /// - /// Преобразует строку в тип . - /// - /// Значение, которое нужно преобразовать. - /// - public static IHtmlContent StringToHtmlContent(string content) => new HtmlContentBuilder().AppendHtml(content); - #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 758d1b5..21ced65 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,11 +2,11 @@ net7.0 - 2023.409.2 - Alexander Babaev - ANB Software Components Pack - Library of some useful functions in C# language. - Alexander Babaev + 2023.0514.2 + Александр Бабаев + Набор компонентов ANB Software + Библиотека полезных методов языка C# + Александр Бабаев anbs_cp anbs_cp enable @@ -38,10 +38,8 @@ - - - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/anbs_cpfn/Classes/NetFileExtension.cs b/anbs_cpfn/Classes/NetFileExtension.cs new file mode 100644 index 0000000..bef0227 --- /dev/null +++ b/anbs_cpfn/Classes/NetFileExtension.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Http; + +namespace anbs_cp.ForNet.Classes; + +/// +/// Класс -- расширение для класса File +/// +public class NetFileExtension +{ + /// + /// Получает MIME-тип файла + /// + /// Загружаемый файл + /// MIME-тип файла + public static string MIMEType (IFormFile file) => + file.ContentType; +} \ No newline at end of file diff --git a/anbs_cpfn/Classes/NetFileHash.cs b/anbs_cpfn/Classes/NetFileHash.cs new file mode 100644 index 0000000..fc2e50c --- /dev/null +++ b/anbs_cpfn/Classes/NetFileHash.cs @@ -0,0 +1,38 @@ +using System.Security.Cryptography; + +using anbs_cp.Classes; + +using Microsoft.AspNetCore.Http; + +namespace anbs_cp.ForNet.Classes; + +public static class NetFileHash +{ + /// + /// Получение md5-хэша загружаемого файла. + /// Взято с https://stackoverflow.com/a/67081012/16469671 + /// + /// Загружаемый файл + /// Массив хэша + public static FileHash GetFileHash (IFormFile file) + { + //Создаю md5 + using MD5 md5 = MD5.Create(); + + //Создаю поток для чтения + using StreamReader streamReader = new(file.OpenReadStream()); + + //Получаю строковый хэш + string hash = BitConverter.ToString(md5.ComputeHash(streamReader.BaseStream)).Replace("-", "") + .ToLowerInvariant(); + + //Создаю результат + FileHash fileHash = new(); + + //Вношу в него данные + fileHash.FromString(hash); + + //Возвращаю результат + return fileHash; + } +} \ No newline at end of file diff --git a/anbs_cpfn/Classes/NetTypeConverter.cs b/anbs_cpfn/Classes/NetTypeConverter.cs new file mode 100644 index 0000000..5aceca8 --- /dev/null +++ b/anbs_cpfn/Classes/NetTypeConverter.cs @@ -0,0 +1,35 @@ +using System.Text.Encodings.Web; + +using Microsoft.AspNetCore.Html; + +namespace anbs_cp.ForNet.Classes; + +/// +/// Расширение конвертера типов на манер Delphi +/// +public static class NetTypeConverter +{ + #region Конвернтация IHtmlContent + /// + /// Преобразует тип в строку . + /// + /// Значение, которое нужно преобразовать. + /// + public static string HtmlContentToString(IHtmlContent content) + { + //Создаём writer + using StringWriter writer = new(); + //Конвертируем IHtmlContent в string + content.WriteTo(writer, HtmlEncoder.Default); + //Возвращаем результат + return writer.ToString(); + } + + /// + /// Преобразует строку в тип . + /// + /// Значение, которое нужно преобразовать. + /// + public static IHtmlContent StringToHtmlContent(string content) => new HtmlContentBuilder().AppendHtml(content); + #endregion +} \ No newline at end of file diff --git a/anbs_cpfn/Extensions/UrlHelperExtension.cs b/anbs_cpfn/Extensions/UrlHelperExtension.cs new file mode 100644 index 0000000..a793f56 --- /dev/null +++ b/anbs_cpfn/Extensions/UrlHelperExtension.cs @@ -0,0 +1,110 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.Primitives; + +namespace anbs_cp.ForNet.Extensions; + +/// +/// Расширение URLHelper +/// +public static class UrlHelperExtension +{ + /// + /// Очищает URL, удаляя ненужные QueryString + /// + /// + /// + /// + /// + /// + /// + /// Ссылка, которую нужно почистить + /// Массив ключей, которые нужно удалить + /// Возвращать только локальную ссылку + /// + public static string ParseURLQuery(this IUrlHelper helper, HttpContext context, string? url, + string[] clearQueryString, bool getLocalURL = true) + { + //Получаю returnURL + url ??= "/"; + + //Если адрес локальный, то преобразую в полный + if (helper.IsLocalUrl(url)) + url = LocalToFullURL(helper, context, url); + + //Создаю uri по адресу + Uri uri = new(url ?? ""); + + //Формат + const UriFormat format = UriFormat.UriEscaped; + + //Формирую Uri-адрес сайта + string baseUri = + uri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port, + format); + + //Формирую локальную ссылку + string localUri = uri.GetComponents(UriComponents.Path, format); + + //Создаю словарь запроса + Dictionary query = QueryHelpers.ParseQuery(uri.Query); + + //Если он содержит параметр для очистки, то удаляю его + foreach (KeyValuePair queryItem in query.Where(queryItem => + clearQueryString.Contains(queryItem.Key))) + query.Remove(queryItem.Key); + + //Создаю список запроса, пригодный для QueryBuilder + List> queryList = query.Select(static queryItem => + new KeyValuePair(queryItem.Key, queryItem.Value.ToString())).ToList(); + + //Запускаю построение новых параметров + QueryBuilder qBuilder = new(queryList); + + //Создаю переменную-результат + string result = ""; + + //Если нужно получить полную ссылку + if (!getLocalURL) + result = baseUri; + + //формирую переменную-результат + result = $"{result}/{localUri}{qBuilder.ToQueryString()}"; + + //Вывожу результат + return result; + } + + /// + /// Получает локальный url-адрес + /// + /// + /// url-адрес + /// Локальный url-адрес + public static string ToLocalURL (this IUrlHelper helper, string url) + { + //Создаю uri из url + Uri uri = new(url); + + //Вывожу результат + return helper.IsLocalUrl(url) ? url : uri.PathAndQuery; + } + + /// + /// Преобразует локальную ссылку в полную + /// + /// + /// + /// + /// + /// + /// + /// Ссылка + /// + /// + /// + public static string? LocalToFullURL (this IUrlHelper helper, HttpContext context, string? url) => + helper.IsLocalUrl(url) ? $"{context.Request.Scheme}://{context.Request.Host}{url}" : url; +} \ No newline at end of file diff --git a/anbs_cpfn/anbs_cpfn.csproj b/anbs_cpfn/anbs_cpfn.csproj new file mode 100644 index 0000000..70928cc --- /dev/null +++ b/anbs_cpfn/anbs_cpfn.csproj @@ -0,0 +1,38 @@ + + + + net7.0 + enable + enable + True + ANBSoftware.ComponentsPackForNet + 2023.05.14.1 + Александр Бабаев + Набор компонентов ANB Software для ASP.NET Core + Библиотека полезных методов языка C# для ASP.NET Core + Александр Бабаев + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + git + MIT + anbs_cp.ForNet + anbs_cp_fn + + + + + + + + + + + + + + + + + + + diff --git a/anbsoftware.componentspack.sln b/anbsoftware.componentspack.sln index adc732b..1443384 100644 --- a/anbsoftware.componentspack.sln +++ b/anbsoftware.componentspack.sln @@ -5,7 +5,12 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cp", "anbs_cp\anbs_cp.csproj", "{442A56CC-1061-4EB5-8B67-3E3D997976D7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "demo", "demo\demo.csproj", "{3BB0778D-3C34-4DD8-A54E-CB476BEF2F7B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "demo", "demo\demo.csproj", "{3BB0778D-3C34-4DD8-A54E-CB476BEF2F7B}" + ProjectSection(ProjectDependencies) = postProject + {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cpfn", "anbs_cpfn\anbs_cpfn.csproj", "{EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}" ProjectSection(ProjectDependencies) = postProject {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} EndProjectSection @@ -23,6 +28,10 @@ Global {3BB0778D-3C34-4DD8-A54E-CB476BEF2F7B}.Debug|Any CPU.ActiveCfg = Release|Any CPU {3BB0778D-3C34-4DD8-A54E-CB476BEF2F7B}.Debug|Any CPU.Build.0 = Release|Any CPU {3BB0778D-3C34-4DD8-A54E-CB476BEF2F7B}.Release|Any CPU.ActiveCfg = Debug.CNF|Any CPU + {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 08f8a10..8425d97 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -4,7 +4,10 @@ HDD RA RAM + True + True True + True True True True From 042a2257bf908280028889bb25cbb645cc79c10a Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 2 Jun 2023 10:42:15 +0300 Subject: [PATCH 33/51] 20230602 --- anbs_cp/Classes/FileExtensions.cs | 4 +- anbs_cp/Structs/KeyValue.cs | 51 ++++++++++++++++++++++++++ anbs_cp/Structs/TwoDimSize.cs | 61 +++++++++++++++++++++++++++++++ anbs_cp/anbs_cp.csproj | 10 ++--- 4 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 anbs_cp/Structs/KeyValue.cs create mode 100644 anbs_cp/Structs/TwoDimSize.cs diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs index 2988845..6dee83e 100644 --- a/anbs_cp/Classes/FileExtensions.cs +++ b/anbs_cp/Classes/FileExtensions.cs @@ -1,4 +1,6 @@ -namespace anbs_cp.Classes; +using MimeKit; + +namespace anbs_cp.Classes; /// /// Класс -- расширение для класса File diff --git a/anbs_cp/Structs/KeyValue.cs b/anbs_cp/Structs/KeyValue.cs new file mode 100644 index 0000000..ab42d49 --- /dev/null +++ b/anbs_cp/Structs/KeyValue.cs @@ -0,0 +1,51 @@ +namespace anbs_cp.Structs; + +/// +/// Пара ключ-значение +/// +/// Тип ключа +/// Тип значения +public struct KeyValue +{ + #region Конструкторы + /// + /// Конструктор по умолчанию + /// + public KeyValue () + { + Key = default; + Value = default; + } + + /// + /// Конструктор со значениями + /// + /// Ключ + /// Значение + public KeyValue (TK key, TV value) + { + Key = key; + Value = value; + } + #endregion + + #region Свойства + /// + /// Ключ + /// + public TK? Key { get; set; } + + /// + /// Значение + /// + public TV? Value { get; set; } + #endregion + + #region Методы + /// + /// Получает ключ-значение по умолчанию + /// + /// Ключ-значение по умолчанию + public static KeyValue GetDefault() => new(); + #endregion +} \ No newline at end of file diff --git a/anbs_cp/Structs/TwoDimSize.cs b/anbs_cp/Structs/TwoDimSize.cs new file mode 100644 index 0000000..1e8db7d --- /dev/null +++ b/anbs_cp/Structs/TwoDimSize.cs @@ -0,0 +1,61 @@ +namespace anbs_cp.Structs; + +/// +/// Двумерный размер +/// +public struct TwoDimSize +{ + #region Приватные поля + /// + /// Длина (приватное) + /// + private int _pWidth; + + /// + /// Высота (приватное) + /// + private int _pHeight; + #endregion + + #region Конструкторы + /// + /// Конструктор по умолчанию + /// + public TwoDimSize () + { + Width = 0; + Height = 0; + } + + /// + /// Конструктор + /// + /// Длина + /// Высота + public TwoDimSize (int width, int height) + { + Width = width; + Height = height; + } + #endregion + + #region Свойства + /// + /// Длина + /// + public int Width + { + readonly get => _pWidth; + set => _pWidth = value < 0 ? 0 : value; + } + + /// + /// Высота + /// + public int Height + { + readonly get => _pHeight; + set => _pHeight = value < 0 ? 0 : value; + } + #endregion +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 21ced65..9037109 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.0514.2 + 2023.0602 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# @@ -38,13 +38,9 @@ - + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + From 42530c234d695eac9a1c58d2e5eef663be5d1bcd Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 11 Aug 2023 20:52:35 +0300 Subject: [PATCH 34/51] 20230811 --- anbs_cp/Classes/TypeConverter.cs | 194 +++++++++++++++++++------------ anbs_cp/anbs_cp.csproj | 10 +- 2 files changed, 129 insertions(+), 75 deletions(-) diff --git a/anbs_cp/Classes/TypeConverter.cs b/anbs_cp/Classes/TypeConverter.cs index 1760edb..63ef01d 100644 --- a/anbs_cp/Classes/TypeConverter.cs +++ b/anbs_cp/Classes/TypeConverter.cs @@ -1,115 +1,165 @@ -namespace anbs_cp.Classes; +using System.Globalization; + +using Newtonsoft.Json; + +namespace anbs_cp.Classes; /// -/// Конвертер типов на манер Delphi +/// Конвертер типов на манер Delphi /// public static class TypeConverter { #region Конвертация числа в строку /// - /// Преобразование int в string + /// Преобразование в /// - /// Число - /// Строка - public static string IntToStr (int aInt) => aInt.ToString(); + /// Число + /// Значение в + public static string IntToStr (int value) => value.ToString(); /// - /// Преобразование uint в string + /// Преобразование в /// - /// Число - /// Строка - public static string IntToStr (uint aInt) => aInt.ToString(); + /// Число + /// Значение в + public static string IntToStr (uint value) => value.ToString(); /// - /// Преобразование long в string + /// Преобразование в /// - /// Число - /// Строка - public static string IntToStr (long aInt) => aInt.ToString(); + /// Число + /// Значение в + public static string IntToStr (long value) => value.ToString(); /// - /// Преобразование ulong в string + /// Преобразование в /// - /// Число - /// Строка - public static string IntToStr (ulong aInt) => aInt.ToString(); + /// Число + /// Значение в + public static string IntToStr (ulong value) => value.ToString(); /// - /// Преобразование byte в string + /// Преобразование в /// - /// Число - /// Строка - public static string IntToStr (byte aInt) => aInt.ToString(); + /// Число + /// Значение в + public static string IntToStr (byte value) => value.ToString(); + + /// + /// Преобразование в + /// + /// Число + /// Значение в + public static string DecimalToStr (decimal value) => value.ToString(CultureInfo.InvariantCulture); + + /// + /// Преобразование в + /// + /// Число + /// Значение в + public static string DoubleToStr (double value) => value.ToString(CultureInfo.InvariantCulture); + + /// + /// Преобразование в + /// + /// Значение правда/ложь + /// Значение в + public static string BoolToStr (bool value) => value.ToString(); + + /// + /// Преобразование в + /// + /// Тип + /// Значение типа + /// Значение в + public static string TypeToStr (T value) => JsonConvert.SerializeObject(value); #endregion #region Конвертация строки в число /// - /// Преобразование строки в число + /// Преобразование в /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static int StrToInt (string aStr, int aDefault = 0) - { - if (!int.TryParse(aStr, out int result)) - result = aDefault; - return result; - } + /// Строка + /// Значение по умолчанию + /// Значение в + public static int StrToInt (string value, int defaultValue = 0) => + int.TryParse(value, out int result) ? result : defaultValue; /// - /// Преобразование строки в число + /// Преобразование в /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static uint StrToUInt (string aStr, uint aDefault = 0) - { - if (!uint.TryParse(aStr, out uint result)) - result = aDefault; - return result; - } + /// Строка + /// Значение по умолчанию + /// Значение в + public static uint StrToUInt (string value, uint defaultValue = 0) => + uint.TryParse(value, out uint result) ? result : defaultValue; /// - /// Преобразование строки в число + /// Преобразование в /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static long StrToInt64 (string aStr, long aDefault = 0) - { - if (!long.TryParse(aStr, out long result)) - result = aDefault; - return result; - } + /// Строка + /// Значение по умолчанию + /// Значение в + public static long StrToInt64 (string value, long defaultValue = 0) => + long.TryParse(value, out long result) ? result : defaultValue; /// - /// Преобразование строки в число + /// Преобразование в /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static ulong StrToUInt64 (string aStr, ulong aDefault = 0) - { - if (!ulong.TryParse(aStr, out ulong result)) - result = aDefault; - return result; - } + /// Строка + /// Значение по умолчанию + /// Значение в + public static ulong StrToUInt64 (string value, ulong defaultValue = 0) => + ulong.TryParse(value, out ulong result) ? result : defaultValue; /// - /// Преобразование строки в число + /// Преобразование в /// - /// Строка - /// Значение по умолчанию (по умолчанию, 0) - /// Число - public static byte StrToByte (string aStr, byte aDefault = 0) - { - if (!byte.TryParse(aStr, out byte result)) - result = aDefault; - return result; - } + /// Строка + /// Значение по умолчанию + /// Значение в + public static byte StrToByte (string value, byte defaultValue = byte.MinValue) => + byte.TryParse(value, out byte result) ? result : defaultValue; + + /// + /// Преобразование в + /// + /// Строка + /// Значение по умолчанию () + /// Значение в + public static decimal StrToDecimal (string value, decimal defaultValue = decimal.Zero) => + decimal.TryParse(value, out decimal result) ? result : defaultValue; + + /// + /// Преобразование в + /// + /// Строка + /// Значение по умолчанию + /// Значение в + public static double StrToDouble (string value, double defaultValue = 0) => + double.TryParse(value, out double result) ? result : defaultValue; + + /// + /// Преобразование в + /// + /// Строка + /// Значение по умолчанию + /// Значение в + public static bool StrToBool (string value, bool defaultValue = false) => + bool.TryParse(value, out bool result) ? result : defaultValue; + + /// + /// Преобразование в тип + /// + /// Тип + /// Строка + /// Значение по умолчанию + /// Значение в + public static T StrToType(string value, T defaultValue) => + JsonConvert.DeserializeObject(value) ?? defaultValue; #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 9037109..b1d3421 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.0602 + 2023.811.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# @@ -38,9 +38,13 @@ - + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + From 4c697863fa796e44d519146d996fb8fb123209c3 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 11 Aug 2023 21:19:41 +0300 Subject: [PATCH 35/51] 20230811-1 --- anbs_cp/Classes/FileExtensions.cs | 4 +-- anbs_cp/anbs_cp.csproj | 4 +-- .../Classes}/OsDriveInfo.cs | 10 ++++---- {anbs_cp => anbs_cposinfo}/Classes/OsInfo.cs | 8 +++--- .../Classes}/OsNetInfo.cs | 4 +-- .../Classes}/OsProcessorInfo.cs | 8 +++--- .../Classes}/OsVideoAdapterInfo.cs | 8 +++--- .../Classes}/OsWindowsInfo.cs | 16 ++++++------ .../Enums/EDriveType.cs | 2 +- .../Interfaces}/IOsBasicInfo.cs | 2 +- .../Interfaces}/IOsDriveInfo.cs | 6 ++--- .../Interfaces}/IOsNetInfo.cs | 2 +- .../Interfaces}/IOsProcessorInfo.cs | 4 +-- .../Interfaces}/IOsVideoAdapterInfo.cs | 4 +-- .../Interfaces}/IOsWindowsInfo.cs | 2 +- anbs_cposinfo/anbs_cposinfo.csproj | 25 +++++++++++++++++++ anbsoftware.componentspack.sln | 8 +++++- demo/OsInfoFrm.cs | 2 +- demo/demo.csproj | 1 + 19 files changed, 75 insertions(+), 45 deletions(-) rename {anbs_cp/Classes/OsInfos => anbs_cposinfo/Classes}/OsDriveInfo.cs (86%) rename {anbs_cp => anbs_cposinfo}/Classes/OsInfo.cs (99%) rename {anbs_cp/Classes/OsInfos => anbs_cposinfo/Classes}/OsNetInfo.cs (92%) rename {anbs_cp/Classes/OsInfos => anbs_cposinfo/Classes}/OsProcessorInfo.cs (89%) rename {anbs_cp/Classes/OsInfos => anbs_cposinfo/Classes}/OsVideoAdapterInfo.cs (91%) rename {anbs_cp/Classes/OsInfos => anbs_cposinfo/Classes}/OsWindowsInfo.cs (71%) rename {anbs_cp => anbs_cposinfo}/Enums/EDriveType.cs (87%) rename {anbs_cp/Interfaces/OsInfos => anbs_cposinfo/Interfaces}/IOsBasicInfo.cs (93%) rename {anbs_cp/Interfaces/OsInfos => anbs_cposinfo/Interfaces}/IOsDriveInfo.cs (77%) rename {anbs_cp/Interfaces/OsInfos => anbs_cposinfo/Interfaces}/IOsNetInfo.cs (89%) rename {anbs_cp/Interfaces/OsInfos => anbs_cposinfo/Interfaces}/IOsProcessorInfo.cs (87%) rename {anbs_cp/Interfaces/OsInfos => anbs_cposinfo/Interfaces}/IOsVideoAdapterInfo.cs (91%) rename {anbs_cp/Interfaces/OsInfos => anbs_cposinfo/Interfaces}/IOsWindowsInfo.cs (93%) create mode 100644 anbs_cposinfo/anbs_cposinfo.csproj diff --git a/anbs_cp/Classes/FileExtensions.cs b/anbs_cp/Classes/FileExtensions.cs index 6dee83e..2988845 100644 --- a/anbs_cp/Classes/FileExtensions.cs +++ b/anbs_cp/Classes/FileExtensions.cs @@ -1,6 +1,4 @@ -using MimeKit; - -namespace anbs_cp.Classes; +namespace anbs_cp.Classes; /// /// Класс -- расширение для класса File diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index b1d3421..f9514d6 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -38,12 +38,12 @@ - - + all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/anbs_cp/Classes/OsInfos/OsDriveInfo.cs b/anbs_cposinfo/Classes/OsDriveInfo.cs similarity index 86% rename from anbs_cp/Classes/OsInfos/OsDriveInfo.cs rename to anbs_cposinfo/Classes/OsDriveInfo.cs index b64ef67..8ec8ce0 100644 --- a/anbs_cp/Classes/OsInfos/OsDriveInfo.cs +++ b/anbs_cposinfo/Classes/OsDriveInfo.cs @@ -1,17 +1,17 @@ -using anbs_cp.Enums; -using anbs_cp.Interfaces.OsInfos; +using anbs_cp.OsInfo.Enums; +using anbs_cp.OsInfo.Interfaces; -namespace anbs_cp.Classes.OsInfos; +namespace anbs_cp.OsInfo.Classes; /// /// Информация о дисках /// -public class OsDriveInfo : IOsDriveInfo +public sealed class OsDriveInfo: IOsDriveInfo { /// /// Конструктор /// - public OsDriveInfo() + public OsDriveInfo () { Type = EDriveType.DtHardDisc; Caption = null; diff --git a/anbs_cp/Classes/OsInfo.cs b/anbs_cposinfo/Classes/OsInfo.cs similarity index 99% rename from anbs_cp/Classes/OsInfo.cs rename to anbs_cposinfo/Classes/OsInfo.cs index ad059bc..7b6da2d 100644 --- a/anbs_cp/Classes/OsInfo.cs +++ b/anbs_cposinfo/Classes/OsInfo.cs @@ -2,11 +2,11 @@ using System.Net.NetworkInformation; using System.Net.Sockets; -using anbs_cp.Classes.OsInfos; -using anbs_cp.Enums; -using anbs_cp.Interfaces.OsInfos; +using anbs_cp.Classes; +using anbs_cp.OsInfo.Enums; +using anbs_cp.OsInfo.Interfaces; -namespace anbs_cp.Classes; +namespace anbs_cp.OsInfo.Classes; /// /// Информация о системе diff --git a/anbs_cp/Classes/OsInfos/OsNetInfo.cs b/anbs_cposinfo/Classes/OsNetInfo.cs similarity index 92% rename from anbs_cp/Classes/OsInfos/OsNetInfo.cs rename to anbs_cposinfo/Classes/OsNetInfo.cs index 5e0eb5f..e5b416b 100644 --- a/anbs_cp/Classes/OsInfos/OsNetInfo.cs +++ b/anbs_cposinfo/Classes/OsNetInfo.cs @@ -1,6 +1,6 @@ -using anbs_cp.Interfaces.OsInfos; +using anbs_cp.OsInfo.Interfaces; -namespace anbs_cp.Classes.OsInfos; +namespace anbs_cp.OsInfo.Classes; /// /// Информация об интернет-соединении diff --git a/anbs_cp/Classes/OsInfos/OsProcessorInfo.cs b/anbs_cposinfo/Classes/OsProcessorInfo.cs similarity index 89% rename from anbs_cp/Classes/OsInfos/OsProcessorInfo.cs rename to anbs_cposinfo/Classes/OsProcessorInfo.cs index b99e6af..df3bba8 100644 --- a/anbs_cp/Classes/OsInfos/OsProcessorInfo.cs +++ b/anbs_cposinfo/Classes/OsProcessorInfo.cs @@ -1,16 +1,16 @@ -using anbs_cp.Interfaces.OsInfos; +using anbs_cp.OsInfo.Interfaces; -namespace anbs_cp.Classes.OsInfos; +namespace anbs_cp.OsInfo.Classes; /// /// Класс информации о процессоре /// -public sealed class OsProcessorInfo : IOsProcessorInfo +public sealed class OsProcessorInfo: IOsProcessorInfo { /// /// Конструктор /// - public OsProcessorInfo() + public OsProcessorInfo () { Caption = null; Description = null; diff --git a/anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs b/anbs_cposinfo/Classes/OsVideoAdapterInfo.cs similarity index 91% rename from anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs rename to anbs_cposinfo/Classes/OsVideoAdapterInfo.cs index 59ede17..2b46a7a 100644 --- a/anbs_cp/Classes/OsInfos/OsVideoAdapterInfo.cs +++ b/anbs_cposinfo/Classes/OsVideoAdapterInfo.cs @@ -1,16 +1,16 @@ -using anbs_cp.Interfaces.OsInfos; +using anbs_cp.OsInfo.Interfaces; -namespace anbs_cp.Classes.OsInfos; +namespace anbs_cp.OsInfo.Classes; /// /// Информация о видеокарте /// -internal sealed class OsVideoAdapterInfo : IOsVideoAdapterInfo +internal sealed class OsVideoAdapterInfo: IOsVideoAdapterInfo { /// /// Конструктор /// - public OsVideoAdapterInfo() + public OsVideoAdapterInfo () { AdapterRAM = 0; Caption = null; diff --git a/anbs_cp/Classes/OsInfos/OsWindowsInfo.cs b/anbs_cposinfo/Classes/OsWindowsInfo.cs similarity index 71% rename from anbs_cp/Classes/OsInfos/OsWindowsInfo.cs rename to anbs_cposinfo/Classes/OsWindowsInfo.cs index e16e1aa..3218361 100644 --- a/anbs_cp/Classes/OsInfos/OsWindowsInfo.cs +++ b/anbs_cposinfo/Classes/OsWindowsInfo.cs @@ -1,16 +1,16 @@ -using anbs_cp.Interfaces.OsInfos; +using anbs_cp.OsInfo.Interfaces; -namespace anbs_cp.Classes.OsInfos; +namespace anbs_cp.OsInfo.Classes; /// /// Информация о Windows /// -public sealed class OsWindowsInfo : IOsWindowsInfo +public sealed class OsWindowsInfo: IOsWindowsInfo { /// /// Конструктор /// - public OsWindowsInfo() + public OsWindowsInfo () { Version = null; Is64 = true; @@ -42,21 +42,21 @@ public sealed class OsWindowsInfo : IOsWindowsInfo /// /// Заголовок /// - public string? Caption { get => Version; set => _= value; } + public string? Caption { get => Version; set => _ = value; } /// /// Описание /// - public string? Description { get => Version; set => _= value; } + public string? Description { get => Version; set => _ = value; } /// /// Идентификатор /// - public string? DeviceId { get => Version; set => _= value; } + public string? DeviceId { get => Version; set => _ = value; } /// /// Имя /// - public string? Name { get => Version; set => _= value; } + public string? Name { get => Version; set => _ = value; } #endregion } \ No newline at end of file diff --git a/anbs_cp/Enums/EDriveType.cs b/anbs_cposinfo/Enums/EDriveType.cs similarity index 87% rename from anbs_cp/Enums/EDriveType.cs rename to anbs_cposinfo/Enums/EDriveType.cs index 7b8c049..c8af779 100644 --- a/anbs_cp/Enums/EDriveType.cs +++ b/anbs_cposinfo/Enums/EDriveType.cs @@ -1,4 +1,4 @@ -namespace anbs_cp.Enums; +namespace anbs_cp.OsInfo.Enums; /// /// Тип носителя diff --git a/anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs b/anbs_cposinfo/Interfaces/IOsBasicInfo.cs similarity index 93% rename from anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs rename to anbs_cposinfo/Interfaces/IOsBasicInfo.cs index 986dffd..2d40df6 100644 --- a/anbs_cp/Interfaces/OsInfos/IOsBasicInfo.cs +++ b/anbs_cposinfo/Interfaces/IOsBasicInfo.cs @@ -1,4 +1,4 @@ -namespace anbs_cp.Interfaces.OsInfos; +namespace anbs_cp.OsInfo.Interfaces; /// /// Базовые параметры устройства diff --git a/anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs b/anbs_cposinfo/Interfaces/IOsDriveInfo.cs similarity index 77% rename from anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs rename to anbs_cposinfo/Interfaces/IOsDriveInfo.cs index 522dba6..04cfdd1 100644 --- a/anbs_cp/Interfaces/OsInfos/IOsDriveInfo.cs +++ b/anbs_cposinfo/Interfaces/IOsDriveInfo.cs @@ -1,11 +1,11 @@ -using anbs_cp.Enums; +using anbs_cp.OsInfo.Enums; -namespace anbs_cp.Interfaces.OsInfos; +namespace anbs_cp.OsInfo.Interfaces; /// /// Информация о дисках /// -public interface IOsDriveInfo : IOsBasicInfo +public interface IOsDriveInfo: IOsBasicInfo { /// /// Тип диска diff --git a/anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs b/anbs_cposinfo/Interfaces/IOsNetInfo.cs similarity index 89% rename from anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs rename to anbs_cposinfo/Interfaces/IOsNetInfo.cs index 6efac09..5e54e62 100644 --- a/anbs_cp/Interfaces/OsInfos/IOsNetInfo.cs +++ b/anbs_cposinfo/Interfaces/IOsNetInfo.cs @@ -1,4 +1,4 @@ -namespace anbs_cp.Interfaces.OsInfos; +namespace anbs_cp.OsInfo.Interfaces; /// /// Информация об интернет-соединении diff --git a/anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs b/anbs_cposinfo/Interfaces/IOsProcessorInfo.cs similarity index 87% rename from anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs rename to anbs_cposinfo/Interfaces/IOsProcessorInfo.cs index 87ddc7e..56b8179 100644 --- a/anbs_cp/Interfaces/OsInfos/IOsProcessorInfo.cs +++ b/anbs_cposinfo/Interfaces/IOsProcessorInfo.cs @@ -1,9 +1,9 @@ -namespace anbs_cp.Interfaces.OsInfos; +namespace anbs_cp.OsInfo.Interfaces; /// /// Информация о процессоре /// -public interface IOsProcessorInfo : IOsBasicInfo +public interface IOsProcessorInfo: IOsBasicInfo { /// /// Заголовок diff --git a/anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs b/anbs_cposinfo/Interfaces/IOsVideoAdapterInfo.cs similarity index 91% rename from anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs rename to anbs_cposinfo/Interfaces/IOsVideoAdapterInfo.cs index 26fced1..9b4c6a2 100644 --- a/anbs_cp/Interfaces/OsInfos/IOsVideoAdapterInfo.cs +++ b/anbs_cposinfo/Interfaces/IOsVideoAdapterInfo.cs @@ -1,9 +1,9 @@ -namespace anbs_cp.Interfaces.OsInfos; +namespace anbs_cp.OsInfo.Interfaces; /// /// Информация о видеокарте /// -public interface IOsVideoAdapterInfo : IOsBasicInfo +public interface IOsVideoAdapterInfo: IOsBasicInfo { /// /// Память diff --git a/anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs b/anbs_cposinfo/Interfaces/IOsWindowsInfo.cs similarity index 93% rename from anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs rename to anbs_cposinfo/Interfaces/IOsWindowsInfo.cs index 3e3fae4..7459f82 100644 --- a/anbs_cp/Interfaces/OsInfos/IOsWindowsInfo.cs +++ b/anbs_cposinfo/Interfaces/IOsWindowsInfo.cs @@ -1,4 +1,4 @@ -namespace anbs_cp.Interfaces.OsInfos; +namespace anbs_cp.OsInfo.Interfaces; /// /// Информация о Windows diff --git a/anbs_cposinfo/anbs_cposinfo.csproj b/anbs_cposinfo/anbs_cposinfo.csproj new file mode 100644 index 0000000..ea64a25 --- /dev/null +++ b/anbs_cposinfo/anbs_cposinfo.csproj @@ -0,0 +1,25 @@ + + + + net7.0 + enable + enable + anbs_cp.OsInfo + True + ANBSoftware.ComponentsPackOsInfo + 2023.8.11 + Александр Бабаев + Набор компонентов ANB Software для получения информации о Windows + Библиотека полезных методов языка C# для получения информации об Windows + Александр Бабаев + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + git + + + + + + + + diff --git a/anbsoftware.componentspack.sln b/anbsoftware.componentspack.sln index 1443384..e2e10fa 100644 --- a/anbsoftware.componentspack.sln +++ b/anbsoftware.componentspack.sln @@ -10,11 +10,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "demo", "demo\demo.csproj", {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cpfn", "anbs_cpfn\anbs_cpfn.csproj", "{EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpfn", "anbs_cpfn\anbs_cpfn.csproj", "{EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}" ProjectSection(ProjectDependencies) = postProject {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,6 +34,10 @@ Global {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}.Release|Any CPU.Build.0 = Release|Any CPU + {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/demo/OsInfoFrm.cs b/demo/OsInfoFrm.cs index df8694b..f92bea5 100644 --- a/demo/OsInfoFrm.cs +++ b/demo/OsInfoFrm.cs @@ -1,4 +1,4 @@ -using anbs_cp.Classes; +using anbs_cp.OsInfo.Classes; using Newtonsoft.Json; diff --git a/demo/demo.csproj b/demo/demo.csproj index d1ba3bc..05b81c5 100644 --- a/demo/demo.csproj +++ b/demo/demo.csproj @@ -23,6 +23,7 @@ + From e6b2c3f0a150bfa1cc2344f0975a9d62e5a8b164 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 13 Aug 2023 11:13:05 +0300 Subject: [PATCH 36/51] 20230813 --- anbs_cp/Classes/TextFormatter.cs | 23 ++++++++++++++++++++++ anbs_cp/Classes/TypeConverter.cs | 4 ++-- anbs_cp/anbs_cp.csproj | 2 +- anbsoftware.componentspack.sln.DotSettings | 2 ++ demo/demo.csproj | 4 ---- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/anbs_cp/Classes/TextFormatter.cs b/anbs_cp/Classes/TextFormatter.cs index 4d9e1c7..f7eeaa7 100644 --- a/anbs_cp/Classes/TextFormatter.cs +++ b/anbs_cp/Classes/TextFormatter.cs @@ -1,4 +1,5 @@ using System.Net.Mail; +using System.Text.RegularExpressions; namespace anbs_cp.Classes; @@ -108,4 +109,26 @@ public static class TextFormatter return false; } } + + /// + /// Проверяет текст на совпадение регулярному выражению по шаблону с опциями (см. ) + /// + /// Текст на проверку + /// Шаблон + /// Параметры проверки в формате (можно игнорировать, по умолчанию: ) + /// Есть ли совпадения в тексте + public static bool IsMatchRegExp (string text, string pattern, RegexOptions? options = null) + { + // Задаю настройки проверки регулярных выражений + RegexOptions regexOptions = options ?? RegexOptions.None; + + // Создаю класс для проверки выражения + Regex regex = new Regex(pattern, regexOptions); + + // Получаю совпадения + MatchCollection matches = regex.Matches(text); + + // Возвращаю результат + return matches.Count > 0; + } } \ No newline at end of file diff --git a/anbs_cp/Classes/TypeConverter.cs b/anbs_cp/Classes/TypeConverter.cs index 63ef01d..06c88d3 100644 --- a/anbs_cp/Classes/TypeConverter.cs +++ b/anbs_cp/Classes/TypeConverter.cs @@ -68,7 +68,7 @@ public static class TypeConverter public static string BoolToStr (bool value) => value.ToString(); /// - /// Преобразование в + /// Преобразование любого типа в (сериализация) /// /// Тип /// Значение типа @@ -152,7 +152,7 @@ public static class TypeConverter bool.TryParse(value, out bool result) ? result : defaultValue; /// - /// Преобразование в тип + /// Преобразование в тип (десериализация) /// /// Тип /// Строка diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index f9514d6..83bb7c7 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.811.0 + 2023.813.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 8425d97..977eb0e 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -15,9 +15,11 @@ True True True + True True True True + True True True True diff --git a/demo/demo.csproj b/demo/demo.csproj index 05b81c5..08dcf93 100644 --- a/demo/demo.csproj +++ b/demo/demo.csproj @@ -18,10 +18,6 @@ True - - - - From 7fad80bae16eaa04bc21cc0f927772e1e34ae2f4 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 13 Aug 2023 13:32:52 +0300 Subject: [PATCH 37/51] 20230813-1 --- anbs_cp/Classes/TextFormatter.cs | 12 +++--------- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/anbs_cp/Classes/TextFormatter.cs b/anbs_cp/Classes/TextFormatter.cs index f7eeaa7..470fa0e 100644 --- a/anbs_cp/Classes/TextFormatter.cs +++ b/anbs_cp/Classes/TextFormatter.cs @@ -115,20 +115,14 @@ public static class TextFormatter /// /// Текст на проверку /// Шаблон - /// Параметры проверки в формате (можно игнорировать, по умолчанию: ) + /// Параметры проверки в формате (можно игнорировать, по умолчанию: ) /// Есть ли совпадения в тексте public static bool IsMatchRegExp (string text, string pattern, RegexOptions? options = null) { // Задаю настройки проверки регулярных выражений - RegexOptions regexOptions = options ?? RegexOptions.None; - - // Создаю класс для проверки выражения - Regex regex = new Regex(pattern, regexOptions); - - // Получаю совпадения - MatchCollection matches = regex.Matches(text); + RegexOptions regexOptions = options ?? RegexOptions.IgnoreCase; // Возвращаю результат - return matches.Count > 0; + return Regex.IsMatch(text, pattern, regexOptions); } } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 83bb7c7..8210ecd 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.813.0 + 2023.813.1 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# From 4617d02649702e5c2da3bdf4465a08db2a2bafdf Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 18 Aug 2023 18:22:16 +0300 Subject: [PATCH 38/51] 20230818 --- anbs_cpdb/Classes/MySqlEngine.cs | 122 ++++++++++++++++++++++++++++++ anbs_cpdb/Interfaces/IDbEngine.cs | 72 ++++++++++++++++++ anbs_cpdb/anbs_cpdb.csproj | 27 +++++++ anbsoftware.componentspack.sln | 6 ++ 4 files changed, 227 insertions(+) create mode 100644 anbs_cpdb/Classes/MySqlEngine.cs create mode 100644 anbs_cpdb/Interfaces/IDbEngine.cs create mode 100644 anbs_cpdb/anbs_cpdb.csproj diff --git a/anbs_cpdb/Classes/MySqlEngine.cs b/anbs_cpdb/Classes/MySqlEngine.cs new file mode 100644 index 0000000..8fe0d24 --- /dev/null +++ b/anbs_cpdb/Classes/MySqlEngine.cs @@ -0,0 +1,122 @@ +using anbs_cp.Database.Interfaces; +using anbs_cp.Structs; + +using Dapper; + +using MySqlConnector; + +namespace anbs_cp.Database.Classes; + +public class MySqlEngine: IDbEngine +{ + /// + /// Конструктор + /// + /// Строка подключения базы данных + public MySqlEngine (string connectionString) => ConnectionString = connectionString; + + /// + /// Строка подключения базы данных + /// + public string ConnectionString { get; set; } + + #region Небезопасные методы + /// + /// Выполняем команду + /// + /// Запрос + /// Данные запроса + /// Успешно ли (есть ли хотя бы одна затронутая строки) выполнена команда + public async Task ExecuteAsync (string sql, object model) + { + // Подключаемся к БД + await using MySqlConnection connection = new(ConnectionString); + + // Открываем соединение + await connection.OpenAsync(); + + // Выполняем команду и выводим результат + return await connection.ExecuteAsync(sql, model) > 0; + } + + /// + /// Запрос на получение одной строки + /// + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает тип или значение по умолчанию + public async Task QueryRowAsync (string sql, object model) + { + // Подключаемся к БД + await using MySqlConnection connection = new(ConnectionString); + + // Открываем соединение + await connection.OpenAsync(); + + // Выполняем запрос и выводим результат + return await connection.QueryFirstOrDefaultAsync(sql, model); + } + + /// + /// Запрос + /// + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + public async Task> QueryAsync (string sql, object model) + { + // Подключаемся к БД + await using MySqlConnection? connection = new(ConnectionString); + + // Открываем соединение + await connection.OpenAsync(); + + // Выполняем запрос и выводим результат + return await connection.QueryAsync(sql, model); + } + + #endregion + + #region Получение + public async Task> SelectAsync (string table, string[] columns, List> where, string? orderBy = null) + { + string sql = $@"SELECT + {(columns.Any() ? string.Join(", ", columns) : "*")} + FROM {table} "; + + List whereCondition = new(); + + List paramsValues = new(); + + if (where.Any()) + { + whereCondition.AddRange(where.Select(static whereItem => $"{whereItem.Key}=@{whereItem.Key}")); + paramsValues.AddRange(where.Select(static whereItem => $"@{whereItem.Key}={whereItem.Value}")); + } + + if (whereCondition.Any()) + sql += $" WHERE {string.Join(", ", whereCondition.ToArray())}"; + + if (orderBy != null) + sql += $" ORDER BY {orderBy}"; + + return await QueryAsync(sql, paramsValues.ToArray()); + } + + public async Task SelectRowAsync (string table, List columns, KeyValue where, string? orderBy = null) => throw new NotImplementedException(); + #endregion + + public async Task CountAsync (string table) => throw new NotImplementedException(); + + public async Task InsertAsync (string table, T entity, KeyValue primaryIndex) => throw new NotImplementedException(); + + public async Task InsertUpdateAsync (string table, T entity) => throw new NotImplementedException(); + + public async Task UpdateAsync (string table, T entity, KeyValue where) => throw new NotImplementedException(); + + public async Task DeleteAsync (string table, KeyValue where) => throw new NotImplementedException(); + + public async Task DeleteRowAsync (string table, KeyValue where) => throw new NotImplementedException(); +}} \ No newline at end of file diff --git a/anbs_cpdb/Interfaces/IDbEngine.cs b/anbs_cpdb/Interfaces/IDbEngine.cs new file mode 100644 index 0000000..332713f --- /dev/null +++ b/anbs_cpdb/Interfaces/IDbEngine.cs @@ -0,0 +1,72 @@ +using anbs_cp.Structs; + +namespace anbs_cp.Database.Interfaces; + +/// +/// Интерфейс для работы с базой данных +/// +public interface IDbEngine +{ + /// + /// Строка подключения + /// + string ConnectionString { get; set; } + + #region Небезопасные методы + + Task ExecuteAsync (string sql, object model); + + /// + /// Запрос на получение одной строки + /// + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает тип или значение по умолчанию + Task QueryRowAsync (string sql, object model); + + /// + /// Запрос + /// + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + Task> QueryAsync (string sql, object model); + + #endregion + + #region Получение + Task> SelectAsync (string table, string[] columns, List> where, string? orderBy = null); + + Task SelectRowAsync (string table, List columns, KeyValue where, string? orderBy = null); + #endregion + + #region Вычисление числа элементов в таблице + + Task CountAsync (string table); + + #endregion + + #region Добавление строки в таблицу + + Task InsertAsync (string table, T entity, KeyValue primaryIndex); + + Task InsertUpdateAsync (string table, T entity); + + #endregion + + #region Обновление строки в таблице + + Task UpdateAsync (string table, T entity, KeyValue where); + + #endregion + + #region Удаление строк + + Task DeleteAsync (string table, KeyValue where); + + Task DeleteRowAsync (string table, KeyValue where); + + #endregion +} \ No newline at end of file diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj new file mode 100644 index 0000000..fd807b8 --- /dev/null +++ b/anbs_cpdb/anbs_cpdb.csproj @@ -0,0 +1,27 @@ + + + + net7.0 + enable + enable + anbs_cp_db + anbs_cp.Database + True + ANBSoftware.ComponentsPack.Database + 2023.08.18 + Александр Бабаев + Набор компонентов ANB Software для работы с БД + Библиотека полезных методов языка C# для работы с базами данных + Александр Бабаев + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack + git + + + + + + + + + diff --git a/anbsoftware.componentspack.sln b/anbsoftware.componentspack.sln index e2e10fa..1435a4a 100644 --- a/anbsoftware.componentspack.sln +++ b/anbsoftware.componentspack.sln @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpfn", "anbs_cpfn\anbs EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,6 +40,10 @@ Global {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Debug|Any CPU.Build.0 = Debug|Any CPU {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Release|Any CPU.ActiveCfg = Release|Any CPU {80E1FEA9-EEDA-4411-8EBA-11991432E98E}.Release|Any CPU.Build.0 = Release|Any CPU + {3796862F-F181-4A27-92D8-8BF13C4FD711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3796862F-F181-4A27-92D8-8BF13C4FD711}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3796862F-F181-4A27-92D8-8BF13C4FD711}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3796862F-F181-4A27-92D8-8BF13C4FD711}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 2fdb100ee02a26e25716227c322d578761deb62d Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 18 Aug 2023 23:05:27 +0300 Subject: [PATCH 39/51] 20230818-1 --- anbs_cpdb/Classes/MySqlEngine.cs | 74 +++++++++++++++++++++++++++---- anbs_cpdb/Interfaces/IDbEngine.cs | 31 +++++++++++-- 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/anbs_cpdb/Classes/MySqlEngine.cs b/anbs_cpdb/Classes/MySqlEngine.cs index 8fe0d24..a5ef494 100644 --- a/anbs_cpdb/Classes/MySqlEngine.cs +++ b/anbs_cpdb/Classes/MySqlEngine.cs @@ -68,7 +68,7 @@ public class MySqlEngine: IDbEngine public async Task> QueryAsync (string sql, object model) { // Подключаемся к БД - await using MySqlConnection? connection = new(ConnectionString); + await using MySqlConnection connection = new(ConnectionString); // Открываем соединение await connection.OpenAsync(); @@ -80,35 +80,91 @@ public class MySqlEngine: IDbEngine #endregion #region Получение - public async Task> SelectAsync (string table, string[] columns, List> where, string? orderBy = null) - { - string sql = $@"SELECT - {(columns.Any() ? string.Join(", ", columns) : "*")} - FROM {table} "; + /// + /// Выборка данных из таблицы + /// + /// Тип данных + /// Имя таблицы + /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) + /// Массив значений столбцов, которые должны попасть в выборку + /// Сортировка + /// Сколько максимально элементов должно быть в выборке (0 -- без ограничения) + /// Массив типа + public async Task> SelectAsync(string table, string[] columns, + List> where, string? orderBy, int limit = 0) + { + // Формирую запрос + string sql = $""" + SELECT + {(columns.Any() ? string.Join(", ", columns) : "*")} + FROM {table} + """; + + // Создаю массив where параметров List whereCondition = new(); + // Создаю массив значений List paramsValues = new(); + // Если заданы параметры where if (where.Any()) { + // - то формирую массив where из where-запроса whereCondition.AddRange(where.Select(static whereItem => $"{whereItem.Key}=@{whereItem.Key}")); + // - и значения параметров paramsValues.AddRange(where.Select(static whereItem => $"@{whereItem.Key}={whereItem.Value}")); } + // Если массив where параметров не пуст if (whereCondition.Any()) + // - то добавляю к запросу sql += $" WHERE {string.Join(", ", whereCondition.ToArray())}"; + // Если добавлена сортировка if (orderBy != null) + // - то добавляю сортировку к запросу sql += $" ORDER BY {orderBy}"; + // Если установлено запрашиваемое число элементов + if (limit > 0) + // - то вводим ограничение + sql += $" LIMIT {limit}"; + + // Осуществляю запрос и возвращаю результат return await QueryAsync(sql, paramsValues.ToArray()); } - public async Task SelectRowAsync (string table, List columns, KeyValue where, string? orderBy = null) => throw new NotImplementedException(); + /// + /// Выборка строки из таблицы + /// + /// Тип данных + /// Имя таблицы + /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) + /// Массив значений столбцов, которые должны попасть в выборку + /// Сортировка + /// Тип или null + public async Task SelectRowAsync(string table, string[] columns, List> where, + string? orderBy = null) => (await SelectAsync(table, columns, where, orderBy, 1)).FirstOrDefault(); + #endregion - public async Task CountAsync (string table) => throw new NotImplementedException(); + #region Вычисление числа элементов в таблице +/// +/// Вычисляет число строк в таблице +/// +/// Таблица +/// Число строк в таблице + public async Task CountAsync(string table) + { + // Задаю запрос + string sql = $"SELECT COUNT(*) FROM {table}"; + + // Выполняю запрос + return (await QueryAsync(sql, new())).FirstOrDefault(); + } + + #endregion public async Task InsertAsync (string table, T entity, KeyValue primaryIndex) => throw new NotImplementedException(); @@ -119,4 +175,4 @@ public class MySqlEngine: IDbEngine public async Task DeleteAsync (string table, KeyValue where) => throw new NotImplementedException(); public async Task DeleteRowAsync (string table, KeyValue where) => throw new NotImplementedException(); -}} \ No newline at end of file +} \ No newline at end of file diff --git a/anbs_cpdb/Interfaces/IDbEngine.cs b/anbs_cpdb/Interfaces/IDbEngine.cs index 332713f..0150450 100644 --- a/anbs_cpdb/Interfaces/IDbEngine.cs +++ b/anbs_cpdb/Interfaces/IDbEngine.cs @@ -37,15 +37,38 @@ public interface IDbEngine #endregion #region Получение - Task> SelectAsync (string table, string[] columns, List> where, string? orderBy = null); - Task SelectRowAsync (string table, List columns, KeyValue where, string? orderBy = null); + /// + /// Выборка данных из таблицы + /// + /// Тип данных + /// Имя таблицы + /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) + /// Массив значений столбцов, которые должны попасть в выборку + /// Сортировка + /// Сколько максимально элементов должно быть в выборке (0 -- без ограничения) + /// Массив типа + Task> SelectAsync (string table, string[] columns, List> where, string? orderBy, int limit = 0); + + /// + /// Выборка строки из таблицы + /// + /// Тип данных + /// Имя таблицы + /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) + /// Массив значений столбцов, которые должны попасть в выборку + /// Сортировка + /// Тип или null + Task SelectRowAsync (string table, string[] columns, List> where, string? orderBy = null); #endregion #region Вычисление числа элементов в таблице - + /// + /// Вычисляет число строк в таблице + /// + /// Таблица + /// Число строк в таблице Task CountAsync (string table); - #endregion #region Добавление строки в таблицу From 9b37f0477ef384b1b17b99a245193cb5f14e3612 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 19 Aug 2023 14:33:14 +0300 Subject: [PATCH 40/51] 20230819 --- anbs_cpdb/Classes/MySqlEngine.cs | 385 ++++++++++++++++++++++-------- anbs_cpdb/Interfaces/IDbEngine.cs | 214 +++++++++++++---- anbs_cpdb/anbs_cpdb.csproj | 3 +- 3 files changed, 456 insertions(+), 146 deletions(-) diff --git a/anbs_cpdb/Classes/MySqlEngine.cs b/anbs_cpdb/Classes/MySqlEngine.cs index a5ef494..20dee85 100644 --- a/anbs_cpdb/Classes/MySqlEngine.cs +++ b/anbs_cpdb/Classes/MySqlEngine.cs @@ -20,14 +20,14 @@ public class MySqlEngine: IDbEngine /// public string ConnectionString { get; set; } - #region Небезопасные методы + #region Базовые операции /// /// Выполняем команду /// /// Запрос - /// Данные запроса - /// Успешно ли (есть ли хотя бы одна затронутая строки) выполнена команда - public async Task ExecuteAsync (string sql, object model) + /// Данные запроса + /// Количество затронутых строк + public async Task ExecuteAsync (string sql, object values) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -36,17 +36,25 @@ public class MySqlEngine: IDbEngine await connection.OpenAsync(); // Выполняем команду и выводим результат - return await connection.ExecuteAsync(sql, model) > 0; + return await connection.ExecuteAsync(sql, values); } /// - /// Запрос на получение одной строки + /// Выполняем команду + /// + /// Запрос + /// Данные запроса + /// Количество затронутых строк + public int Execute (string sql, object values) => ExecuteAsync(sql, values).GetAwaiter().GetResult(); + + /// + /// Запрос /// /// Тип передаваемого значения /// Запрос - /// Данные запроса - /// Возвращает тип или значение по умолчанию - public async Task QueryRowAsync (string sql, object model) + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + public async Task> QueryAsync (string sql, object values) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -55,7 +63,7 @@ public class MySqlEngine: IDbEngine await connection.OpenAsync(); // Выполняем запрос и выводим результат - return await connection.QueryFirstOrDefaultAsync(sql, model); + return await connection.QueryAsync(sql, values); } /// @@ -63,9 +71,18 @@ public class MySqlEngine: IDbEngine /// /// Тип передаваемого значения /// Запрос - /// Данные запроса + /// Данные запроса /// Возвращает массив типа или значение по умолчанию - public async Task> QueryAsync (string sql, object model) + public IEnumerable Query (string sql, object values) => QueryAsync(sql, values).GetAwaiter().GetResult(); + + /// + /// Запрос строки + /// + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + public async Task QueryRowAsync (string sql, object values) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -74,105 +91,275 @@ public class MySqlEngine: IDbEngine await connection.OpenAsync(); // Выполняем запрос и выводим результат - return await connection.QueryAsync(sql, model); + return await connection.QuerySingleOrDefaultAsync(sql, values); } + /// + /// Запрос строки + /// + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + public T? QueryRow (string sql, object values) => QueryRowAsync(sql, values).GetAwaiter().GetResult(); + #endregion - #region Получение + + #region Получение данных + /// + /// Получает массив данных (SELECT * FROM...) + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Массив результата запроса + public async Task> GetResultsAsync (string sql, object values) => await QueryAsync(sql, values); /// - /// Выборка данных из таблицы + /// Получает массив данных (SELECT * FROM...) /// - /// Тип данных - /// Имя таблицы - /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) - /// Массив значений столбцов, которые должны попасть в выборку - /// Сортировка - /// Сколько максимально элементов должно быть в выборке (0 -- без ограничения) - /// Массив типа - public async Task> SelectAsync(string table, string[] columns, - List> where, string? orderBy, int limit = 0) + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Массив результата запроса + public IEnumerable GetResults (string sql, object values) => GetResultsAsync(sql, values).GetAwaiter().GetResult(); + + /// + /// Получает строку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Строки данных или null + public async Task GetRowAsync (string sql, object values) { - // Формирую запрос + // Подключаемся к БД + await using MySqlConnection connection = new(ConnectionString); + + // Открываем соединение + await connection.OpenAsync(); + + // Выполняем запрос и выводим результат + return await connection.QuerySingleOrDefaultAsync(sql, values); + } + + /// + /// Получает строку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Строки данных или null + public T? GetRow (string sql, object values) => GetRowAsync(sql, values).GetAwaiter().GetResult(); + + /// + /// Получает колонку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Колонка данных или null + public async Task> GetColAsync (string sql, object values) + where T : IComparable, IConvertible, IEquatable => await QueryAsync(sql, values); + + /// + /// Получает колонку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Колонка данных или null + public IEnumerable GetCol (string sql, object values) where T : IComparable, IConvertible, IEquatable => + GetColAsync(sql, values).GetAwaiter().GetResult(); + + /// + /// Получение значение единичного поля + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Поле или null + public async Task GetVarAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable + { + // Подключаемся к БД + await using MySqlConnection connection = new(ConnectionString); + + // Открываем соединение + await connection.OpenAsync(); + + // Выполняем запрос и выводим результат + return await connection.QuerySingleOrDefaultAsync(sql, values); + } + + /// + /// Получение значение единичного поля + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Поле или null + public T? GetVar (string sql, object values) where T : IComparable, IConvertible, IEquatable => + GetVarAsync(sql, values).GetAwaiter().GetResult(); + + #endregion + + #region CRUD данные + + /// + /// Вставляет данные в таблицу + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Результат выполнения + public async Task InsertAsync (T data, string tableName) where T : class + { + // Получение список имён свойств в data + List propertyNamesList = (from dataProperty in data.GetType().GetProperties() select dataProperty.Name).ToList(); + + // Получаем список имён в data, обрамленные @ + List propertyValuesList = propertyNamesList.Select(static propertyName => $"@{propertyName}").ToList(); + + //Получаем строку имён свойств + string propertyNames = string.Join(", ", propertyNamesList.ToArray()); + + // Получаем строку имён свойств, обрамленных @ + string propertyValues = string.Join(", ", propertyValuesList.ToArray()); + + // Создаю соединение + await using MySqlConnection connection = new(ConnectionString); + + // Создаю запрос string sql = $""" - SELECT - {(columns.Any() ? string.Join(", ", columns) : "*")} - FROM {table} - """; - - // Создаю массив where параметров - List whereCondition = new(); - - // Создаю массив значений - List paramsValues = new(); - - // Если заданы параметры where - if (where.Any()) - { - // - то формирую массив where из where-запроса - whereCondition.AddRange(where.Select(static whereItem => $"{whereItem.Key}=@{whereItem.Key}")); - // - и значения параметров - paramsValues.AddRange(where.Select(static whereItem => $"@{whereItem.Key}={whereItem.Value}")); - } - - // Если массив where параметров не пуст - if (whereCondition.Any()) - // - то добавляю к запросу - sql += $" WHERE {string.Join(", ", whereCondition.ToArray())}"; - - // Если добавлена сортировка - if (orderBy != null) - // - то добавляю сортировку к запросу - sql += $" ORDER BY {orderBy}"; - - // Если установлено запрашиваемое число элементов - if (limit > 0) - // - то вводим ограничение - sql += $" LIMIT {limit}"; - - // Осуществляю запрос и возвращаю результат - return await QueryAsync(sql, paramsValues.ToArray()); - } - - /// - /// Выборка строки из таблицы - /// - /// Тип данных - /// Имя таблицы - /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) - /// Массив значений столбцов, которые должны попасть в выборку - /// Сортировка - /// Тип или null - public async Task SelectRowAsync(string table, string[] columns, List> where, - string? orderBy = null) => (await SelectAsync(table, columns, where, orderBy, 1)).FirstOrDefault(); - - #endregion - - #region Вычисление числа элементов в таблице -/// -/// Вычисляет число строк в таблице -/// -/// Таблица -/// Число строк в таблице - public async Task CountAsync(string table) - { - // Задаю запрос - string sql = $"SELECT COUNT(*) FROM {table}"; + INSERT + INTO {tableName} ({propertyNames}) + VALUES ({propertyValues}) + """; // Выполняю запрос - return (await QueryAsync(sql, new())).FirstOrDefault(); + return await connection.ExecuteAsync(sql, data) > 0; } + /// + /// Вставляет данные в таблицу + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Результат выполнения + public bool Insert (T data, string tableName) where T : class => InsertAsync(data, tableName).GetAwaiter().GetResult(); + + /// + /// Обновляет строку в таблице + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data + /// Результат выполнения + public async Task UpdateAsync (T data, string tableName, string whereConditionColumn) where T : class + { + // Получение список имён свойств в data + List propertyNamesList = (from dataProperty in data.GetType().GetProperties() + where dataProperty.Name != whereConditionColumn + select dataProperty.Name).ToList(); + + // Получаем список имён в data, обрамленные @ + List propertyKeyValuesList = propertyNamesList.Select(static propertyName => $"{propertyName}=@{propertyName}").ToList(); + + // Получаем строку имён свойств, обрамленных @ + string properties = string.Join(", ", propertyKeyValuesList.ToArray()); + + // Создаю соединение + await using MySqlConnection connection = new(ConnectionString); + + // Создаю запрос + string sql = $""" + UPDATE + {tableName} + SET + ({properties}) + WHERE + {whereConditionColumn}=@{whereConditionColumn} + """; + + // Выполняю запрос + return await connection.ExecuteAsync(sql, data) > 0; + } + + /// + /// Обновляет строку в таблице + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data + /// Результат выполнения + public bool Update (T data, string tableName, string whereConditionColumn) where T : class => + UpdateAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult(); + + /// + /// Удаляет строки + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + public async Task DeleteAsync (string tableName, KeyValue where) + { + // Создаю соединение + await using MySqlConnection connection = new(ConnectionString); + + // Создаю запрос + string sql = $""" + DELETE FROM + {tableName} + WHERE + {where.Key}=@{where.Key} + """; + + // Выполняю запрос + return await connection.ExecuteAsync(sql, new { where.Value }) > 0; + } + + /// + /// Удаляет строки + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + public bool Delete (string tableName, KeyValue where) => DeleteAsync(tableName, where).GetAwaiter().GetResult(); + + /// + /// Удаляет строку + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + public async Task DeleteRowAsync (string tableName, KeyValue where) + { + // Создаю соединение + await using MySqlConnection connection = new(ConnectionString); + + // Создаю запрос + string sql = $""" + DELETE FROM + {tableName} + WHERE + {where.Key}=@{where.Key} + LIMIT 1 + """; + + // Выполняю запрос + return await connection.ExecuteAsync(sql, new { where.Value }) > 0; + } + + /// + /// Удаляет строку + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + public bool DeleteRow (string tableName, KeyValue where) => DeleteRowAsync(tableName, where).GetAwaiter().GetResult(); #endregion - - public async Task InsertAsync (string table, T entity, KeyValue primaryIndex) => throw new NotImplementedException(); - - public async Task InsertUpdateAsync (string table, T entity) => throw new NotImplementedException(); - - public async Task UpdateAsync (string table, T entity, KeyValue where) => throw new NotImplementedException(); - - public async Task DeleteAsync (string table, KeyValue where) => throw new NotImplementedException(); - - public async Task DeleteRowAsync (string table, KeyValue where) => throw new NotImplementedException(); } \ No newline at end of file diff --git a/anbs_cpdb/Interfaces/IDbEngine.cs b/anbs_cpdb/Interfaces/IDbEngine.cs index 0150450..672eed1 100644 --- a/anbs_cpdb/Interfaces/IDbEngine.cs +++ b/anbs_cpdb/Interfaces/IDbEngine.cs @@ -12,84 +12,206 @@ public interface IDbEngine /// string ConnectionString { get; set; } - #region Небезопасные методы - - Task ExecuteAsync (string sql, object model); + #region Базовые операции /// - /// Запрос на получение одной строки + /// Выполняем команду /// - /// Тип передаваемого значения /// Запрос - /// Данные запроса - /// Возвращает тип или значение по умолчанию - Task QueryRowAsync (string sql, object model); + /// Данные запроса + /// Количество затронутых строк + Task ExecuteAsync (string sql, object values); + + /// + /// Выполняем команду + /// + /// Запрос + /// Данные запроса + /// Количество затронутых строк + int Execute (string sql, object values); /// /// Запрос /// /// Тип передаваемого значения /// Запрос - /// Данные запроса + /// Данные запроса /// Возвращает массив типа или значение по умолчанию - Task> QueryAsync (string sql, object model); - - #endregion - - #region Получение + Task> QueryAsync (string sql, object values); /// - /// Выборка данных из таблицы + /// Запрос /// - /// Тип данных - /// Имя таблицы - /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) - /// Массив значений столбцов, которые должны попасть в выборку - /// Сортировка - /// Сколько максимально элементов должно быть в выборке (0 -- без ограничения) - /// Массив типа - Task> SelectAsync (string table, string[] columns, List> where, string? orderBy, int limit = 0); + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + IEnumerable Query (string sql, object values); /// - /// Выборка строки из таблицы + /// Запрос строки /// - /// Тип данных - /// Имя таблицы - /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все) - /// Массив значений столбцов, которые должны попасть в выборку - /// Сортировка - /// Тип или null - Task SelectRowAsync (string table, string[] columns, List> where, string? orderBy = null); - #endregion + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + Task QueryRowAsync (string sql, object values); - #region Вычисление числа элементов в таблице /// - /// Вычисляет число строк в таблице + /// Запрос строки /// - /// Таблица - /// Число строк в таблице - Task CountAsync (string table); + /// Тип передаваемого значения + /// Запрос + /// Данные запроса + /// Возвращает массив типа или значение по умолчанию + T? QueryRow (string sql, object values); #endregion - #region Добавление строки в таблицу + #region Получение данных - Task InsertAsync (string table, T entity, KeyValue primaryIndex); + /// + /// Получает массив данных (SELECT * FROM...) + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Массив результата запроса + Task> GetResultsAsync (string sql, object values); - Task InsertUpdateAsync (string table, T entity); + /// + /// Получает массив данных (SELECT * FROM...) + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Массив результата запроса + IEnumerable GetResults (string sql, object values); + + /// + /// Получает строку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Строки данных или null + Task GetRowAsync (string sql, object values); + + /// + /// Получает строку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Строки данных или null + T? GetRow (string sql, object values); + + /// + /// Получает колонку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Колонка данных или null + Task> GetColAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable; + + /// + /// Получает колонку в массиве данных + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Колонка данных или null + IEnumerable GetCol (string sql, object values) where T : IComparable, IConvertible, IEquatable; + + /// + /// Получение значение единичного поля + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Поле или null + Task GetVarAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable; + + /// + /// Получение значение единичного поля + /// + /// Тип получаемых данных + /// SQL-запрос + /// Данные запроса + /// Поле или null + T? GetVar (string sql, object values) where T : IComparable, IConvertible, IEquatable; #endregion - #region Обновление строки в таблице + #region CRUD данные + /// + /// Вставляет данные в таблицу + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Результат выполнения + Task InsertAsync (T data, string tableName) where T : class; - Task UpdateAsync (string table, T entity, KeyValue where); + /// + /// Вставляет данные в таблицу + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Результат выполнения + bool Insert (T data, string tableName) where T : class; - #endregion + /// + /// Обновляет строку в таблице + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data + /// Результат выполнения + Task UpdateAsync (T data, string tableName, string whereConditionColumn) where T : class; - #region Удаление строк + /// + /// Обновляет строку в таблице + /// + /// Класс данных + /// Данные + /// Имя таблицы + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data + /// Результат выполнения + bool Update (T data, string tableName, string whereConditionColumn) where T : class; - Task DeleteAsync (string table, KeyValue where); + /// + /// Удаляет строки + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + Task DeleteAsync (string tableName, KeyValue where); - Task DeleteRowAsync (string table, KeyValue where); + /// + /// Удаляет строки + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + bool Delete (string tableName, KeyValue where); + /// + /// Удаляет строку + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + Task DeleteRowAsync (string tableName, KeyValue where); + + /// + /// Удаляет строку + /// + /// Имя таблицы + /// Условие + /// Результат выполнения + bool DeleteRow (string tableName, KeyValue where); #endregion } \ No newline at end of file diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj index fd807b8..a96949b 100644 --- a/anbs_cpdb/anbs_cpdb.csproj +++ b/anbs_cpdb/anbs_cpdb.csproj @@ -8,7 +8,7 @@ anbs_cp.Database True ANBSoftware.ComponentsPack.Database - 2023.08.18 + 2023.08.19 Александр Бабаев Набор компонентов ANB Software для работы с БД Библиотека полезных методов языка C# для работы с базами данных @@ -22,6 +22,7 @@ + From cb8ffde7c0f9f6fa6a070ebdae1d3fa72de1672a Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 19 Aug 2023 18:12:03 +0300 Subject: [PATCH 41/51] 20230819-1 --- anbs_cpdb/Classes/MySqlEngine.cs | 36 +++++++++++++++------------- anbs_cpdb/Interfaces/IDbEngine.cs | 40 ++++++++++++++++--------------- anbs_cpdb/anbs_cpdb.csproj | 4 +--- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/anbs_cpdb/Classes/MySqlEngine.cs b/anbs_cpdb/Classes/MySqlEngine.cs index 20dee85..8f328ca 100644 --- a/anbs_cpdb/Classes/MySqlEngine.cs +++ b/anbs_cpdb/Classes/MySqlEngine.cs @@ -1,5 +1,4 @@ using anbs_cp.Database.Interfaces; -using anbs_cp.Structs; using Dapper; @@ -276,10 +275,9 @@ public class MySqlEngine: IDbEngine // Создаю запрос string sql = $""" - UPDATE - {tableName} + UPDATE {tableName} SET - ({properties}) + {properties} WHERE {whereConditionColumn}=@{whereConditionColumn} """; @@ -302,10 +300,11 @@ public class MySqlEngine: IDbEngine /// /// Удаляет строки /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - public async Task DeleteAsync (string tableName, KeyValue where) + public async Task DeleteAsync (T data, string tableName, string whereConditionColumn) where T : class { // Создаю соединение await using MySqlConnection connection = new(ConnectionString); @@ -315,28 +314,31 @@ public class MySqlEngine: IDbEngine DELETE FROM {tableName} WHERE - {where.Key}=@{where.Key} + {whereConditionColumn}=@{whereConditionColumn} """; // Выполняю запрос - return await connection.ExecuteAsync(sql, new { where.Value }) > 0; + return await connection.ExecuteAsync(sql, data) > 0; } /// /// Удаляет строки /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - public bool Delete (string tableName, KeyValue where) => DeleteAsync(tableName, where).GetAwaiter().GetResult(); + public bool Delete (T data, string tableName, string whereConditionColumn) where T : class => + DeleteAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult(); /// /// Удаляет строку /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - public async Task DeleteRowAsync (string tableName, KeyValue where) + public async Task DeleteRowAsync (T data, string tableName, string whereConditionColumn) where T : class { // Создаю соединение await using MySqlConnection connection = new(ConnectionString); @@ -346,20 +348,22 @@ public class MySqlEngine: IDbEngine DELETE FROM {tableName} WHERE - {where.Key}=@{where.Key} + {whereConditionColumn}=@{whereConditionColumn} LIMIT 1 """; // Выполняю запрос - return await connection.ExecuteAsync(sql, new { where.Value }) > 0; + return await connection.ExecuteAsync(sql, data) > 0; } /// /// Удаляет строку /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - public bool DeleteRow (string tableName, KeyValue where) => DeleteRowAsync(tableName, where).GetAwaiter().GetResult(); + public bool DeleteRow(T data, string tableName, string whereConditionColumn) where T : class => + DeleteRowAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult(); #endregion } \ No newline at end of file diff --git a/anbs_cpdb/Interfaces/IDbEngine.cs b/anbs_cpdb/Interfaces/IDbEngine.cs index 672eed1..8499723 100644 --- a/anbs_cpdb/Interfaces/IDbEngine.cs +++ b/anbs_cpdb/Interfaces/IDbEngine.cs @@ -1,6 +1,4 @@ -using anbs_cp.Structs; - -namespace anbs_cp.Database.Interfaces; +namespace anbs_cp.Database.Interfaces; /// /// Интерфейс для работы с базой данных @@ -112,7 +110,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Колонка данных или null - Task> GetColAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable; + Task> GetColAsync (string sql, object values) where T: IComparable, IConvertible, IEquatable; /// /// Получает колонку в массиве данных @@ -121,7 +119,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Колонка данных или null - IEnumerable GetCol (string sql, object values) where T : IComparable, IConvertible, IEquatable; + IEnumerable GetCol (string sql, object values) where T: IComparable, IConvertible, IEquatable; /// /// Получение значение единичного поля @@ -130,7 +128,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Поле или null - Task GetVarAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable; + Task GetVarAsync (string sql, object values) where T: IComparable, IConvertible, IEquatable; /// /// Получение значение единичного поля @@ -139,7 +137,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Поле или null - T? GetVar (string sql, object values) where T : IComparable, IConvertible, IEquatable; + T? GetVar (string sql, object values) where T: IComparable, IConvertible, IEquatable; #endregion @@ -151,7 +149,7 @@ public interface IDbEngine /// Данные /// Имя таблицы /// Результат выполнения - Task InsertAsync (T data, string tableName) where T : class; + Task InsertAsync (T data, string tableName) where T: class; /// /// Вставляет данные в таблицу @@ -160,7 +158,7 @@ public interface IDbEngine /// Данные /// Имя таблицы /// Результат выполнения - bool Insert (T data, string tableName) where T : class; + bool Insert (T data, string tableName) where T: class; /// /// Обновляет строку в таблице @@ -170,7 +168,7 @@ public interface IDbEngine /// Имя таблицы /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - Task UpdateAsync (T data, string tableName, string whereConditionColumn) where T : class; + Task UpdateAsync (T data, string tableName, string whereConditionColumn) where T: class; /// /// Обновляет строку в таблице @@ -180,38 +178,42 @@ public interface IDbEngine /// Имя таблицы /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - bool Update (T data, string tableName, string whereConditionColumn) where T : class; + bool Update (T data, string tableName, string whereConditionColumn) where T: class; /// /// Удаляет строки /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - Task DeleteAsync (string tableName, KeyValue where); + Task DeleteAsync (T data, string tableName, string whereConditionColumn) where T: class; /// /// Удаляет строки /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - bool Delete (string tableName, KeyValue where); + bool Delete (T data, string tableName, string whereConditionColumn) where T: class; /// /// Удаляет строку /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - Task DeleteRowAsync (string tableName, KeyValue where); + Task DeleteRowAsync (T data, string tableName, string whereConditionColumn) where T: class; /// /// Удаляет строку /// + /// Данные /// Имя таблицы - /// Условие + /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - bool DeleteRow (string tableName, KeyValue where); + bool DeleteRow (T data, string tableName, string whereConditionColumn) where T: class; #endregion } \ No newline at end of file diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj index a96949b..730b781 100644 --- a/anbs_cpdb/anbs_cpdb.csproj +++ b/anbs_cpdb/anbs_cpdb.csproj @@ -8,7 +8,7 @@ anbs_cp.Database True ANBSoftware.ComponentsPack.Database - 2023.08.19 + 2023.08.19.4 Александр Бабаев Набор компонентов ANB Software для работы с БД Библиотека полезных методов языка C# для работы с базами данных @@ -19,10 +19,8 @@ - - From b09af0c79f3043e28331098eda9577465cc8c1bf Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 27 Aug 2023 09:44:19 +0300 Subject: [PATCH 42/51] 20230827 --- anbs_cp/Structs/KeyValueList.cs | 145 ++++++++++++++++++++++++++++++ anbs_cp/anbs_cp.csproj | 2 +- anbs_cpdb/Classes/MySqlEngine.cs | 30 +++---- anbs_cpdb/Interfaces/IDbEngine.cs | 32 +++---- anbs_cpdb/anbs_cpdb.csproj | 2 +- 5 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 anbs_cp/Structs/KeyValueList.cs diff --git a/anbs_cp/Structs/KeyValueList.cs b/anbs_cp/Structs/KeyValueList.cs new file mode 100644 index 0000000..6531759 --- /dev/null +++ b/anbs_cp/Structs/KeyValueList.cs @@ -0,0 +1,145 @@ +namespace anbs_cp.Structs; + +/// +/// Список из пара ключ-значение +/// +/// Тип ключа +/// Тип значения +public struct KeyValueList +{ + /// + /// Хранение значений + /// + private readonly List> _list; + + #region Конструкторы + /// + /// Конструктор по умолчанию + /// + public KeyValueList () => _list = new(); + #endregion + + #region Свойства + /// + /// Список ключей из списка + /// + public IEnumerable Keys => GetKeys(); + #endregion + + #region Методы + + /// + /// Получает список ключей + /// + /// Список ключей + private IEnumerable GetKeys () => from keyValue in _list where keyValue.Key is not null select keyValue.Key; + + /// + /// Добавляет в список параметр + /// + /// Параметр + public void Add (KeyValue keyValue) => _list.Add(keyValue); + + /// + /// Добавляет в список параметр + /// + /// Ключ параметра + /// Значение + public void Add (TK key, TV value) => _list.Add(new(key, value)); + + /// + /// Изменяет значение + /// + /// Новое значение + public void ChangeValue (KeyValue keyValue) + { + // Если такой ключ не существует + if (!Contains(keyValue.Key!)) + { + // - тогда добавляю новое значение + Add(keyValue); + + // - прерываю + return; + } + + // Существующее значение + KeyValue existValue = GetItem(keyValue.Key!) ?? new(); + + // Удаляем существующее + _list.Remove(existValue); + + // Добавляем новое + _list.Add(keyValue); + } + + /// + /// Изменяет значение + /// + /// Ключ + /// Новое значение + public void ChangeValue (TK key, TV newValue) => ChangeValue(new(key, newValue)); + + /// + /// Получает элемент по ключу + /// + /// Ключ + /// Элемент + public KeyValue? GetItem (TK key) + { + // Ищем элемент в списке + foreach (KeyValue keyValueItem in _list.Where(keyValueItem => keyValueItem.Key!.Equals(key))) + // - возвращаем его при нахождении + return keyValueItem; + + // Элемент не найден -- вывожу null + return null; + } + + /// + /// Получает значение + /// + /// Ключ + /// Значение + public TV? GetValue (TK key) + { + // Если такой ключ не существует + if (!Contains(key)) + // Тогда возвращаю значение по умолчанию + return default; + + // Получаю элемент + KeyValue keyValue = GetItem(key) ?? new(); + + // Вывожу значение + return keyValue.Value; + } + + /// + /// Удаляет элемент из списка + /// + /// Элемент + public void Remove (KeyValue keyValue) => _list.Remove(keyValue); + + /// + /// Удаляет элемент из списка + /// + /// Ключ элемента + public void Remove (TK key) => Remove(GetItem(key) ?? new()); + + /// + /// Проверяет, содержится ли элемент в списке + /// + /// Элемент + /// Результат проверки + public bool Contains (KeyValue keyValue) => _list.Contains(keyValue); + + /// + /// Проверяет, содержится ли элемент в списке + /// + /// Ключ элемента + /// Результат проверки + public bool Contains (TK key) => Keys.Any(keyParam => keyParam!.Equals(key)); + + #endregion +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 8210ecd..2fb692f 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.813.1 + 2023.827.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# diff --git a/anbs_cpdb/Classes/MySqlEngine.cs b/anbs_cpdb/Classes/MySqlEngine.cs index 8f328ca..e280601 100644 --- a/anbs_cpdb/Classes/MySqlEngine.cs +++ b/anbs_cpdb/Classes/MySqlEngine.cs @@ -26,7 +26,7 @@ public class MySqlEngine: IDbEngine /// Запрос /// Данные запроса /// Количество затронутых строк - public async Task ExecuteAsync (string sql, object values) + public async Task ExecuteAsync (string sql, object? values = null) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -44,7 +44,7 @@ public class MySqlEngine: IDbEngine /// Запрос /// Данные запроса /// Количество затронутых строк - public int Execute (string sql, object values) => ExecuteAsync(sql, values).GetAwaiter().GetResult(); + public int Execute (string sql, object? values = null) => ExecuteAsync(sql, values).GetAwaiter().GetResult(); /// /// Запрос @@ -53,7 +53,7 @@ public class MySqlEngine: IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - public async Task> QueryAsync (string sql, object values) + public async Task> QueryAsync (string sql, object? values = null) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -72,7 +72,7 @@ public class MySqlEngine: IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - public IEnumerable Query (string sql, object values) => QueryAsync(sql, values).GetAwaiter().GetResult(); + public IEnumerable Query (string sql, object? values = null) => QueryAsync(sql, values).GetAwaiter().GetResult(); /// /// Запрос строки @@ -81,7 +81,7 @@ public class MySqlEngine: IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - public async Task QueryRowAsync (string sql, object values) + public async Task QueryRowAsync (string sql, object? values = null) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -100,7 +100,7 @@ public class MySqlEngine: IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - public T? QueryRow (string sql, object values) => QueryRowAsync(sql, values).GetAwaiter().GetResult(); + public T? QueryRow (string sql, object? values = null) => QueryRowAsync(sql, values).GetAwaiter().GetResult(); #endregion @@ -113,7 +113,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Массив результата запроса - public async Task> GetResultsAsync (string sql, object values) => await QueryAsync(sql, values); + public async Task> GetResultsAsync (string sql, object? values = null) => await QueryAsync(sql, values); /// /// Получает массив данных (SELECT * FROM...) @@ -122,7 +122,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Массив результата запроса - public IEnumerable GetResults (string sql, object values) => GetResultsAsync(sql, values).GetAwaiter().GetResult(); + public IEnumerable GetResults (string sql, object? values = null) => GetResultsAsync(sql, values).GetAwaiter().GetResult(); /// /// Получает строку в массиве данных @@ -131,7 +131,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Строки данных или null - public async Task GetRowAsync (string sql, object values) + public async Task GetRowAsync (string sql, object? values = null) { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -150,7 +150,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Строки данных или null - public T? GetRow (string sql, object values) => GetRowAsync(sql, values).GetAwaiter().GetResult(); + public T? GetRow (string sql, object? values = null) => GetRowAsync(sql, values).GetAwaiter().GetResult(); /// /// Получает колонку в массиве данных @@ -159,7 +159,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Колонка данных или null - public async Task> GetColAsync (string sql, object values) + public async Task> GetColAsync (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable => await QueryAsync(sql, values); /// @@ -169,7 +169,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Колонка данных или null - public IEnumerable GetCol (string sql, object values) where T : IComparable, IConvertible, IEquatable => + public IEnumerable GetCol (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable => GetColAsync(sql, values).GetAwaiter().GetResult(); /// @@ -179,7 +179,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Поле или null - public async Task GetVarAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable + public async Task GetVarAsync (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable { // Подключаемся к БД await using MySqlConnection connection = new(ConnectionString); @@ -198,7 +198,7 @@ public class MySqlEngine: IDbEngine /// SQL-запрос /// Данные запроса /// Поле или null - public T? GetVar (string sql, object values) where T : IComparable, IConvertible, IEquatable => + public T? GetVar (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable => GetVarAsync(sql, values).GetAwaiter().GetResult(); #endregion @@ -363,7 +363,7 @@ public class MySqlEngine: IDbEngine /// Имя таблицы /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data /// Результат выполнения - public bool DeleteRow(T data, string tableName, string whereConditionColumn) where T : class => + public bool DeleteRow (T data, string tableName, string whereConditionColumn) where T : class => DeleteRowAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult(); #endregion } \ No newline at end of file diff --git a/anbs_cpdb/Interfaces/IDbEngine.cs b/anbs_cpdb/Interfaces/IDbEngine.cs index 8499723..b4f5943 100644 --- a/anbs_cpdb/Interfaces/IDbEngine.cs +++ b/anbs_cpdb/Interfaces/IDbEngine.cs @@ -1,4 +1,6 @@ -namespace anbs_cp.Database.Interfaces; +using System.Transactions; + +namespace anbs_cp.Database.Interfaces; /// /// Интерфейс для работы с базой данных @@ -18,7 +20,7 @@ public interface IDbEngine /// Запрос /// Данные запроса /// Количество затронутых строк - Task ExecuteAsync (string sql, object values); + Task ExecuteAsync (string sql, object? values = null); /// /// Выполняем команду @@ -26,7 +28,7 @@ public interface IDbEngine /// Запрос /// Данные запроса /// Количество затронутых строк - int Execute (string sql, object values); + int Execute (string sql, object? values = null); /// /// Запрос @@ -35,7 +37,7 @@ public interface IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - Task> QueryAsync (string sql, object values); + Task> QueryAsync (string sql, object? values = null); /// /// Запрос @@ -44,7 +46,7 @@ public interface IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - IEnumerable Query (string sql, object values); + IEnumerable Query (string sql, object? values = null); /// /// Запрос строки @@ -53,7 +55,7 @@ public interface IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - Task QueryRowAsync (string sql, object values); + Task QueryRowAsync (string sql, object? values = null); /// /// Запрос строки @@ -62,7 +64,7 @@ public interface IDbEngine /// Запрос /// Данные запроса /// Возвращает массив типа или значение по умолчанию - T? QueryRow (string sql, object values); + T? QueryRow (string sql, object? values = null); #endregion #region Получение данных @@ -74,7 +76,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Массив результата запроса - Task> GetResultsAsync (string sql, object values); + Task> GetResultsAsync (string sql, object? values = null); /// /// Получает массив данных (SELECT * FROM...) @@ -83,7 +85,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Массив результата запроса - IEnumerable GetResults (string sql, object values); + IEnumerable GetResults (string sql, object? values = null); /// /// Получает строку в массиве данных @@ -92,7 +94,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Строки данных или null - Task GetRowAsync (string sql, object values); + Task GetRowAsync (string sql, object? values = null); /// /// Получает строку в массиве данных @@ -101,7 +103,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Строки данных или null - T? GetRow (string sql, object values); + T? GetRow (string sql, object? values = null); /// /// Получает колонку в массиве данных @@ -110,7 +112,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Колонка данных или null - Task> GetColAsync (string sql, object values) where T: IComparable, IConvertible, IEquatable; + Task> GetColAsync (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable; /// /// Получает колонку в массиве данных @@ -119,7 +121,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Колонка данных или null - IEnumerable GetCol (string sql, object values) where T: IComparable, IConvertible, IEquatable; + IEnumerable GetCol (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable; /// /// Получение значение единичного поля @@ -128,7 +130,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Поле или null - Task GetVarAsync (string sql, object values) where T: IComparable, IConvertible, IEquatable; + Task GetVarAsync (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable; /// /// Получение значение единичного поля @@ -137,7 +139,7 @@ public interface IDbEngine /// SQL-запрос /// Данные запроса /// Поле или null - T? GetVar (string sql, object values) where T: IComparable, IConvertible, IEquatable; + T? GetVar (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable; #endregion diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj index 730b781..6987504 100644 --- a/anbs_cpdb/anbs_cpdb.csproj +++ b/anbs_cpdb/anbs_cpdb.csproj @@ -8,7 +8,7 @@ anbs_cp.Database True ANBSoftware.ComponentsPack.Database - 2023.08.19.4 + 2023.08.27.0 Александр Бабаев Набор компонентов ANB Software для работы с БД Библиотека полезных методов языка C# для работы с базами данных From 2106429d0a5495aa46a14ef8de3d740628386d3e Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 4 Sep 2023 22:04:04 +0300 Subject: [PATCH 43/51] 20230904 --- anbs_cp/Classes/Encrypt/StringEncrypt.cs | 113 +++++++++++++++++---- anbs_cp/Interfaces/IEncryptKey.cs | 12 --- anbs_cp/anbs_cp.csproj | 2 +- anbsoftware.componentspack.sln.DotSettings | 5 +- 4 files changed, 96 insertions(+), 36 deletions(-) delete mode 100644 anbs_cp/Interfaces/IEncryptKey.cs diff --git a/anbs_cp/Classes/Encrypt/StringEncrypt.cs b/anbs_cp/Classes/Encrypt/StringEncrypt.cs index 71f11f2..46a90cd 100644 --- a/anbs_cp/Classes/Encrypt/StringEncrypt.cs +++ b/anbs_cp/Classes/Encrypt/StringEncrypt.cs @@ -1,6 +1,5 @@ -using System.Text; - -using gfoidl.Base64; +using System.Security.Cryptography; +using System.Text; namespace anbs_cp.Classes.Encrypt; @@ -10,42 +9,112 @@ namespace anbs_cp.Classes.Encrypt; public static class StringEncrypt { /// - /// Метод для шифрования строки + /// Получение ключа из строки /// - /// Строка, которая должна быть зашифрована - /// Этот статический метод возвращает зашифрованную строку - public static string Encrypt (string text) + /// Ключ-строка + /// Хэш-ключ + /// Ключ + private static byte[] KeyFromString (string s, byte[] salt) { - byte[] byteText = Encoding.UTF8.GetBytes(text); - return Base64.Url.Encode(byteText); + // Создаю хэшер + using Rfc2898DeriveBytes hasher = new(s, salt, 1000, HashAlgorithmName.SHA256); + + // Получаю ключ + return hasher.GetBytes(32); } /// - /// Метод для шифрования массива строк + /// Метод для шифрования строки /// - /// Массив строк - /// Этот статический метод возвращает зашифрованную строку из массива - public static string EncryptBytes (byte[] bytes) => Base64.Url.Encode(bytes); + /// Строка, которая должна быть зашифрована + /// Ключ + /// Этот статический метод возвращает зашифрованную строку + public static string Encrypt (string text, string key) + { + // Создаю криптограф + using Aes aes = Aes.Create(); + + // Получаю ключ + aes.Key = KeyFromString(key, aes.IV); + + // Открываю поток + using MemoryStream ms = new(); + + // Пишу данные в поток + ms.Write(aes.IV); + + // Создаю шифрованный поток + using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) + // Пишу данные в него + cs.Write(Encoding.UTF8.GetBytes(text)); + + // Возвращаю зашифрованный текст + return Convert.ToBase64String(ms.ToArray()); + } /// /// Метод для дешифрования строки /// /// Строка, которая должна быть дешифрована + /// Ключ /// Этот статический метод возвращает дешифрованную строку - public static string Decrypt (string text) + public static string Decrypt (string text, string key) { - string guidBase64Url = text.Replace('+', '-').Replace('/', '_').TrimEnd('='); - return Encoding.UTF8.GetString(Base64.Url.Decode(guidBase64Url)); + // Открываю поток в памяти + using MemoryStream ms = new(Convert.FromBase64String(text)); + + // Задаю ключ + byte[] iv = new byte[16]; + + // Читаю его + _ = ms.Read(iv); + + // Создаю криптограф + using Aes aes = Aes.Create(); + + // Получаю ключ + aes.Key = KeyFromString(key, iv); + + // присваиваю ключ + aes.IV = iv; + + // Создаю поток дешифратора + using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); + + // Задаю поток итогового текста + using MemoryStream output = new(); + + // Копирую данные в выходной поток + cs.CopyTo(output); + + // Вывожу расшифрованный текст + return Encoding.UTF8.GetString(output.ToArray()); } /// - /// Метод для дешифрования в массив byte + /// Декодирует зашифрованную строку в HTML-пригодный формат /// - /// Строка, которая должна быть дешифрована - /// Этот статический метод возвращает дешифрованный массива byte[] - public static byte[] DecryptBytes (string text) + /// Зашифрованная строка + /// Этот статический метод возвращает дешифрованную строку + public static string Base64UrlEncode(string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_'); + + /// + /// Раскодирует из декодированной строки в HTML-пригодный формат + /// + /// Декодированная строка + /// Этот статический метод возвращает шифрованную строку + public static string Base64UrlDecode(string text) { - string guidBase64Url = text.Replace('+', '-').Replace('/', '_').TrimEnd('='); - return Base64.Url.Decode(guidBase64Url); + string result = text.Replace('_', '/').Replace('-', '+'); + switch (result.Length % 4) + { + case 2: + result += "=="; + break; + case 3: + result += "="; + break; + } + return result; } } \ No newline at end of file diff --git a/anbs_cp/Interfaces/IEncryptKey.cs b/anbs_cp/Interfaces/IEncryptKey.cs deleted file mode 100644 index fedd43a..0000000 --- a/anbs_cp/Interfaces/IEncryptKey.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace anbs_cp.Interfaces; - -/// -/// Интерфейс ключа -/// -public interface IEncryptKey -{ - /// - /// Ключ - /// - public byte[] Key { get; set; } -} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 2fb692f..95cc409 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.827.0 + 2023.902.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 977eb0e..25bcf0b 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -17,10 +17,13 @@ True True True + True True + True True True True True True - True \ No newline at end of file + True + True \ No newline at end of file From 6966acaeb391c68153c949acb87c508896b6522f Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 8 Sep 2023 07:44:36 +0300 Subject: [PATCH 44/51] 20230908 --- anbs_cp/Classes/Encrypt/PasswordEncrypt.cs | 56 +++++++++ anbs_cp/Classes/Encrypt/StringEncrypt.cs | 95 +-------------- anbs_cp/Classes/Encrypt/StringEncryptor.cs | 127 +++++++++++++++++++++ anbs_cp/Interfaces/IEncryptor.cs | 37 ++++++ anbs_cp/anbs_cp.csproj | 3 +- anbsoftware.componentspack.sln.DotSettings | 1 + 6 files changed, 229 insertions(+), 90 deletions(-) create mode 100644 anbs_cp/Classes/Encrypt/PasswordEncrypt.cs create mode 100644 anbs_cp/Classes/Encrypt/StringEncryptor.cs create mode 100644 anbs_cp/Interfaces/IEncryptor.cs diff --git a/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs b/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs new file mode 100644 index 0000000..7270784 --- /dev/null +++ b/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs @@ -0,0 +1,56 @@ +using System.Text; + +using anbs_cp.Interfaces; + +using Microsoft.AspNetCore.Cryptography.KeyDerivation; + +namespace anbs_cp.Classes.Encrypt; + +/// +/// Класс шифрования пароля +/// +public sealed class PasswordEncrypt: IEncryptor +{ + /// + /// Шифрование пароля + /// + /// Пароль + /// Хэш-код пароля + /// Зашифрованный пароль + public string Encrypt (string password, string salt) + { + // Получаю byte-массив из хэш-кода пароля + byte[] saltBytes = Encoding.UTF8.GetBytes(salt); + + // Шифрую пароль + byte[] encryptedPassword = KeyDerivation.Pbkdf2(password, saltBytes, KeyDerivationPrf.HMACSHA512, 5000, 64); + + // Возвращаю зашифрованный пароль + return Convert.ToBase64String(encryptedPassword); + } + + /// + /// Этот метод не требует реализации в этом классе! + /// + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// Этот метод не требует реализации в этом классе! + public string Decrypt (string encryptedValue, string salt) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!"); + + /// + /// Этот метод не требует реализации в этом классе! + /// + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// Этот метод не требует реализации в этом классе! + public string Base64UrlEncode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!"); + + /// + /// Этот метод не требует реализации в этом классе! + /// + /// НЕ РАБОТАЕТ + /// НЕ РАБОТАЕТ + /// Этот метод не требует реализации в этом классе! + public string Base64UrlDecode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!"); +} \ No newline at end of file diff --git a/anbs_cp/Classes/Encrypt/StringEncrypt.cs b/anbs_cp/Classes/Encrypt/StringEncrypt.cs index 46a90cd..1a96540 100644 --- a/anbs_cp/Classes/Encrypt/StringEncrypt.cs +++ b/anbs_cp/Classes/Encrypt/StringEncrypt.cs @@ -1,56 +1,17 @@ -using System.Security.Cryptography; -using System.Text; - -namespace anbs_cp.Classes.Encrypt; +namespace anbs_cp.Classes.Encrypt; /// -/// Класс для шифровки строк +/// Статическая обертка для класса шифровки строк StringEncryptor /// public static class StringEncrypt { - /// - /// Получение ключа из строки - /// - /// Ключ-строка - /// Хэш-ключ - /// Ключ - private static byte[] KeyFromString (string s, byte[] salt) - { - // Создаю хэшер - using Rfc2898DeriveBytes hasher = new(s, salt, 1000, HashAlgorithmName.SHA256); - - // Получаю ключ - return hasher.GetBytes(32); - } - /// /// Метод для шифрования строки /// /// Строка, которая должна быть зашифрована /// Ключ /// Этот статический метод возвращает зашифрованную строку - public static string Encrypt (string text, string key) - { - // Создаю криптограф - using Aes aes = Aes.Create(); - - // Получаю ключ - aes.Key = KeyFromString(key, aes.IV); - - // Открываю поток - using MemoryStream ms = new(); - - // Пишу данные в поток - ms.Write(aes.IV); - - // Создаю шифрованный поток - using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) - // Пишу данные в него - cs.Write(Encoding.UTF8.GetBytes(text)); - - // Возвращаю зашифрованный текст - return Convert.ToBase64String(ms.ToArray()); - } + public static string Encrypt (string text, string key) => new StringEncryptor().Encrypt(text, key); /// /// Метод для дешифрования строки @@ -58,63 +19,19 @@ public static class StringEncrypt /// Строка, которая должна быть дешифрована /// Ключ /// Этот статический метод возвращает дешифрованную строку - public static string Decrypt (string text, string key) - { - // Открываю поток в памяти - using MemoryStream ms = new(Convert.FromBase64String(text)); - - // Задаю ключ - byte[] iv = new byte[16]; - - // Читаю его - _ = ms.Read(iv); - - // Создаю криптограф - using Aes aes = Aes.Create(); - - // Получаю ключ - aes.Key = KeyFromString(key, iv); - - // присваиваю ключ - aes.IV = iv; - - // Создаю поток дешифратора - using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); - - // Задаю поток итогового текста - using MemoryStream output = new(); - - // Копирую данные в выходной поток - cs.CopyTo(output); - - // Вывожу расшифрованный текст - return Encoding.UTF8.GetString(output.ToArray()); - } + public static string Decrypt (string text, string key) => new StringEncryptor().Decrypt(text, key); /// /// Декодирует зашифрованную строку в HTML-пригодный формат /// /// Зашифрованная строка /// Этот статический метод возвращает дешифрованную строку - public static string Base64UrlEncode(string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_'); + public static string Base64UrlEncode (string text) => new StringEncryptor().Base64UrlEncode(text); /// /// Раскодирует из декодированной строки в HTML-пригодный формат /// /// Декодированная строка /// Этот статический метод возвращает шифрованную строку - public static string Base64UrlDecode(string text) - { - string result = text.Replace('_', '/').Replace('-', '+'); - switch (result.Length % 4) - { - case 2: - result += "=="; - break; - case 3: - result += "="; - break; - } - return result; - } + public static string Base64UrlDecode (string text) => new StringEncryptor().Base64UrlDecode(text); } \ No newline at end of file diff --git a/anbs_cp/Classes/Encrypt/StringEncryptor.cs b/anbs_cp/Classes/Encrypt/StringEncryptor.cs new file mode 100644 index 0000000..4f6cce8 --- /dev/null +++ b/anbs_cp/Classes/Encrypt/StringEncryptor.cs @@ -0,0 +1,127 @@ +using System.Security.Cryptography; +using System.Text; + +using anbs_cp.Interfaces; + +namespace anbs_cp.Classes.Encrypt; + +/// +/// Класс для шифровки строк +/// +public sealed class StringEncryptor: IEncryptor +{ + /// + /// Получение ключа из строки + /// + /// Ключ-строка + /// Хэш-ключ + /// Ключ + private static byte[] KeyFromString (string s, byte[] salt) + { + // Создаю хэшер + using Rfc2898DeriveBytes hasher = new(s, salt, 1000, HashAlgorithmName.SHA256); + + // Получаю ключ + return hasher.GetBytes(32); + } + + /// + /// Метод для шифрования строки + /// + /// Строка, которая должна быть зашифрована + /// Ключ + /// Этот метод возвращает зашифрованную строку + public string Encrypt (string value, string salt) + { + // Создаю криптограф + using Aes aes = Aes.Create(); + + // Получаю ключ + aes.Key = KeyFromString(salt, aes.IV); + + // Открываю поток + using MemoryStream ms = new(); + + // Пишу данные в поток + ms.Write(aes.IV); + + // Создаю шифрованный поток + using (CryptoStream cs = new(ms, aes.CreateEncryptor(), CryptoStreamMode.Write, true)) + // Пишу данные в него + cs.Write(Encoding.UTF8.GetBytes(value)); + + // Возвращаю зашифрованный текст + return Convert.ToBase64String(ms.ToArray()); + } + + /// + /// Метод для дешифрования строки + /// + /// Строка, которая должна быть дешифрована + /// Ключ + /// Этот метод возвращает дешифрованную строку + public string Decrypt (string encryptedValue, string salt) + { + // Открываю поток в памяти + using MemoryStream ms = new(Convert.FromBase64String(encryptedValue)); + + // Задаю ключ + byte[] iv = new byte[16]; + + // Читаю его + _ = ms.Read(iv); + + // Создаю криптограф + using Aes aes = Aes.Create(); + + // Получаю ключ + aes.Key = KeyFromString(salt, iv); + + // присваиваю ключ + aes.IV = iv; + + // Создаю поток дешифратора + using CryptoStream cs = new(ms, aes.CreateDecryptor(), CryptoStreamMode.Read, true); + + // Задаю поток итогового текста + using MemoryStream output = new(); + + // Копирую данные в выходной поток + cs.CopyTo(output); + + // Вывожу расшифрованный текст + return Encoding.UTF8.GetString(output.ToArray()); + } + + /// + /// Декодирует зашифрованную строку в HTML-пригодный формат + /// + /// Зашифрованная строка + /// Этот метод возвращает дешифрованную строку + public string Base64UrlEncode (string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_'); + + /// + /// Раскодирует из декодированной строки в HTML-пригодный формат + /// + /// Декодированная строка + /// Этот метод возвращает шифрованную строку + public string Base64UrlDecode (string text) + { + // Первоначальная замена + string result = text.Replace('_', '/').Replace('-', '+'); + + // Заменяю значения + switch (result.Length % 4) + { + case 2: + result += "=="; + break; + case 3: + result += "="; + break; + } + + // Возвращаю результат + return result; + } +} \ No newline at end of file diff --git a/anbs_cp/Interfaces/IEncryptor.cs b/anbs_cp/Interfaces/IEncryptor.cs new file mode 100644 index 0000000..4fb84ea --- /dev/null +++ b/anbs_cp/Interfaces/IEncryptor.cs @@ -0,0 +1,37 @@ +namespace anbs_cp.Interfaces; + +/// +/// Интерфейс шифрования +/// +public interface IEncryptor +{ + /// + /// Метод для шифрования строки + /// + /// Строка, которая должна быть зашифрована + /// Ключ шифрования + /// Этот метод возвращает зашифрованную строку + string Encrypt (string value, string salt); + + /// + /// Метод для дешифрования строки + /// + /// Строка, которая должна быть дешифрована + /// Ключ шифрования + /// Этот метод возвращает дешифрованную строку + string Decrypt (string encryptedValue, string salt); + + /// + /// Декодирует зашифрованную строку в HTML-пригодный формат + /// + /// Зашифрованная строка + /// Этот метод возвращает дешифрованную строку + string Base64UrlEncode (string text); + + /// + /// Раскодирует из декодированной строки в HTML-пригодный формат + /// + /// Декодированная строка + /// Этот метод возвращает шифрованную строку + string Base64UrlDecode (string text); +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 95cc409..17e5ea1 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.902.0 + 2023.908.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# @@ -38,6 +38,7 @@ + all diff --git a/anbsoftware.componentspack.sln.DotSettings b/anbsoftware.componentspack.sln.DotSettings index 25bcf0b..94e58b5 100644 --- a/anbsoftware.componentspack.sln.DotSettings +++ b/anbsoftware.componentspack.sln.DotSettings @@ -8,6 +8,7 @@ True True True + True True True True From 5041dd07fba79f9504c7f24e30aab1c4b36360a9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 8 Sep 2023 21:50:54 +0300 Subject: [PATCH 45/51] 20230908-1 --- anbs_cp/anbs_cp.csproj | 6 +----- .../Encrypt => anbs_cpfn/Classes}/PasswordEncrypt.cs | 2 +- anbs_cpfn/anbs_cpfn.csproj | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) rename {anbs_cp/Classes/Encrypt => anbs_cpfn/Classes}/PasswordEncrypt.cs (98%) diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 17e5ea1..e931af5 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.908.0 + 2023.908.1 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# @@ -37,15 +37,11 @@ - - - all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs b/anbs_cpfn/Classes/PasswordEncrypt.cs similarity index 98% rename from anbs_cp/Classes/Encrypt/PasswordEncrypt.cs rename to anbs_cpfn/Classes/PasswordEncrypt.cs index 7270784..a338eb2 100644 --- a/anbs_cp/Classes/Encrypt/PasswordEncrypt.cs +++ b/anbs_cpfn/Classes/PasswordEncrypt.cs @@ -4,7 +4,7 @@ using anbs_cp.Interfaces; using Microsoft.AspNetCore.Cryptography.KeyDerivation; -namespace anbs_cp.Classes.Encrypt; +namespace anbs_cp.ForNet.Classes; /// /// Класс шифрования пароля diff --git a/anbs_cpfn/anbs_cpfn.csproj b/anbs_cpfn/anbs_cpfn.csproj index 70928cc..ba4151e 100644 --- a/anbs_cpfn/anbs_cpfn.csproj +++ b/anbs_cpfn/anbs_cpfn.csproj @@ -6,7 +6,7 @@ enable True ANBSoftware.ComponentsPackForNet - 2023.05.14.1 + 2023.09.08.0 Александр Бабаев Набор компонентов ANB Software для ASP.NET Core Библиотека полезных методов языка C# для ASP.NET Core @@ -20,8 +20,8 @@ + - From c3d71a6a63a3aa661d76078cc33c431fcc01bcf7 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 15 Oct 2023 10:20:30 +0300 Subject: [PATCH 46/51] 20231015 --- anbs_cp/{Structs => Classes}/KeyValueList.cs | 22 ++++++++++++++++++-- anbs_cp/anbs_cp.csproj | 2 +- anbs_cpdb/anbs_cpdb.csproj | 2 +- anbs_cpfn/anbs_cpfn.csproj | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) rename anbs_cp/{Structs => Classes}/KeyValueList.cs (87%) diff --git a/anbs_cp/Structs/KeyValueList.cs b/anbs_cp/Classes/KeyValueList.cs similarity index 87% rename from anbs_cp/Structs/KeyValueList.cs rename to anbs_cp/Classes/KeyValueList.cs index 6531759..f9e0810 100644 --- a/anbs_cp/Structs/KeyValueList.cs +++ b/anbs_cp/Classes/KeyValueList.cs @@ -1,11 +1,15 @@ -namespace anbs_cp.Structs; +using System.Collections; + +using anbs_cp.Structs; + +namespace anbs_cp.Classes; /// /// Список из пара ключ-значение /// /// Тип ключа /// Тип значения -public struct KeyValueList +public class KeyValueList: IEnumerable> { /// /// Хранение значений @@ -142,4 +146,18 @@ public struct KeyValueList public bool Contains (TK key) => Keys.Any(keyParam => keyParam!.Equals(key)); #endregion + + #region Реализация интерфейса IEnumerable> + /// + /// Получаю + /// + /// + public IEnumerator> GetEnumerator () => _list.GetEnumerator(); + + /// + /// Получаю + /// + /// + IEnumerator IEnumerable.GetEnumerator () => GetEnumerator(); + #endregion } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index e931af5..8a96959 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.908.1 + 2023.1015.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj index 6987504..785a68c 100644 --- a/anbs_cpdb/anbs_cpdb.csproj +++ b/anbs_cpdb/anbs_cpdb.csproj @@ -19,7 +19,7 @@ - + diff --git a/anbs_cpfn/anbs_cpfn.csproj b/anbs_cpfn/anbs_cpfn.csproj index ba4151e..4c8faa1 100644 --- a/anbs_cpfn/anbs_cpfn.csproj +++ b/anbs_cpfn/anbs_cpfn.csproj @@ -20,7 +20,7 @@ - + From d8bc16b6461730ee44c0a4602e9fc4f8227f3849 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 1 Nov 2023 12:43:47 +0300 Subject: [PATCH 47/51] 2023111 --- anbs_cp/Classes/ActionState.cs | 13 +++++++++++-- anbs_cp/Classes/ActionStateSimply.cs | 9 +++++++++ anbs_cp/anbs_cp.csproj | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 anbs_cp/Classes/ActionStateSimply.cs diff --git a/anbs_cp/Classes/ActionState.cs b/anbs_cp/Classes/ActionState.cs index 0a72407..034feee 100644 --- a/anbs_cp/Classes/ActionState.cs +++ b/anbs_cp/Classes/ActionState.cs @@ -5,19 +5,23 @@ namespace anbs_cp.Classes; /// /// Состояние действия /// +/// Обновлено 2023.11.1 +/// * Добавлен возвращаемый результат +/// /// Обновлено 2023.01.121.1: /// * Заменены интерфейсы IAction* на соответствующие классы /// -public sealed class ActionState +public class ActionState { /// /// Конструктор /// - public ActionState () + protected ActionState () { Info = new(); Warnings = new(); Errors = new(); + Value = default; } /// @@ -35,6 +39,11 @@ public sealed class ActionState /// public List Errors { get; } + /// + /// Значение + /// + public T? Value { get; set; } + #region Методы #region Очистка diff --git a/anbs_cp/Classes/ActionStateSimply.cs b/anbs_cp/Classes/ActionStateSimply.cs new file mode 100644 index 0000000..8c73d9d --- /dev/null +++ b/anbs_cp/Classes/ActionStateSimply.cs @@ -0,0 +1,9 @@ +namespace anbs_cp.Classes; + +/// +/// Состояние действия +/// +/// Обновлено 2023.11.1 +/// * Добавлен класс ActionState без возвращаемого значения +/// +public sealed class ActionState: ActionState { } \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 8a96959..c1ad123 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.1015.0 + 2023.1101.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# From b3f35fafe6a80f8cff88b9ba19545089a7f5f49d Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 1 Nov 2023 12:57:43 +0300 Subject: [PATCH 48/51] 2023111-1 --- anbs_cp/Classes/ActionState.cs | 16 ++++++++++++++-- anbs_cp/anbs_cp.csproj | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/anbs_cp/Classes/ActionState.cs b/anbs_cp/Classes/ActionState.cs index 034feee..1bba81d 100644 --- a/anbs_cp/Classes/ActionState.cs +++ b/anbs_cp/Classes/ActionState.cs @@ -14,9 +14,9 @@ namespace anbs_cp.Classes; public class ActionState { /// - /// Конструктор + /// Конструктор по умолчанию /// - protected ActionState () + public ActionState () { Info = new(); Warnings = new(); @@ -24,6 +24,18 @@ public class ActionState Value = default; } + /// + /// Конструктор с указанием начального значения + /// + /// Начальное значение + public ActionState (T defaultValue) + { + Info = new(); + Warnings = new(); + Errors = new(); + Value = defaultValue; + } + /// /// Список информации /// diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index c1ad123..843b5b4 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net7.0 - 2023.1101.0 + 2023.1101.1 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# From 1c8ed4088341e118cb2f37388085a0459c0fa508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=91=D0=B0=D0=B1=D0=B0=D0=B5=D0=B2?= Date: Wed, 15 Nov 2023 07:11:17 +0300 Subject: [PATCH 49/51] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 55a1358..a8aeaba 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,16 @@ -# anbsoftware_componentspack -some classes that extend the capabilities of the C # language - -# Welcome to ANB Software Components Pack! - -You are on the component set «ANB» page. Thanks for your interest in the project - -# License - -MIIT +# Что такое ANB Software Components Pack? +ANB Software Components Pack - набор полезных классов C#, которые расширяют возможности языка. Они могут использоваться в приложенях для ОС Widows и серверов на базе этой ОС. + +# Лицензия +MIIT + +# anbsoftware_componentspack +some classes that extend the capabilities of the C # language + +# Welcome to ANB Software Components Pack! + +You are on the component set «ANB» page. Thanks for your interest in the project + +# License + +MIIT \ No newline at end of file From 6dae1b482876aab034bdf4dfb50994379bb317e0 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Nov 2023 07:23:14 +0300 Subject: [PATCH 50/51] 20231114 --- anbs_cp/Classes/TimestampValidator.cs | 10 +++++----- anbs_cp/anbs_cp.csproj | 4 ++-- anbs_cp/anbs_cp.csproj.DotSettings | 2 +- anbs_cpdb/anbs_cpdb.csproj | 8 ++++---- anbs_cpdb/anbs_cpdb.csproj.DotSettings | 2 ++ anbs_cpfn/anbs_cpfn.csproj | 8 ++++---- anbs_cpfn/anbs_cpfn.csproj.DotSettings | 2 ++ anbs_cposinfo/anbs_cposinfo.csproj | 11 +++++++---- anbs_cposinfo/anbs_cposinfo.csproj.DotSettings | 2 ++ anbsoftware.componentspack.sln | 7 +++++-- demo/demo.csproj | 2 +- demo/demo.csproj.DotSettings | 2 +- 12 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 anbs_cpdb/anbs_cpdb.csproj.DotSettings create mode 100644 anbs_cpfn/anbs_cpfn.csproj.DotSettings create mode 100644 anbs_cposinfo/anbs_cposinfo.csproj.DotSettings diff --git a/anbs_cp/Classes/TimestampValidator.cs b/anbs_cp/Classes/TimestampValidator.cs index 910c325..c85266a 100644 --- a/anbs_cp/Classes/TimestampValidator.cs +++ b/anbs_cp/Classes/TimestampValidator.cs @@ -71,13 +71,13 @@ public static class TimestampValidator /// Проверка временного интервала (в час) /// /// Временной интервал - /// Проверяемый временной интервал - /// Временная дельта в часах + /// Проверяемый временной интервал + /// Временная дельта в часах /// - /// Попал ли в промежуток + + /// Попал ли в промежуток + /// - public static bool ValidateFromHour(long timestamp, long checkedstamp, ulong deltahr) => - Validate(timestamp, checkedstamp, checked(deltahr * 3600000UL)); + public static bool ValidateFromHour(long timestamp, long checkedStamp, ulong deltaHour) => + Validate(timestamp, checkedStamp, checked(deltaHour * 3600000UL)); /// /// Проверка попадания текущего времени в заданный интервал (в час) diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index 843b5b4..a6a5e8f 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -1,8 +1,8 @@  - net7.0 - 2023.1101.1 + net8.0 + 2023.1114.0 Александр Бабаев Набор компонентов ANB Software Библиотека полезных методов языка C# diff --git a/anbs_cp/anbs_cp.csproj.DotSettings b/anbs_cp/anbs_cp.csproj.DotSettings index 16c7a3d..632c268 100644 --- a/anbs_cp/anbs_cp.csproj.DotSettings +++ b/anbs_cp/anbs_cp.csproj.DotSettings @@ -1,2 +1,2 @@  - CSharp110 \ No newline at end of file + CSharp120 \ No newline at end of file diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj index 785a68c..0624317 100644 --- a/anbs_cpdb/anbs_cpdb.csproj +++ b/anbs_cpdb/anbs_cpdb.csproj @@ -1,14 +1,14 @@ - net7.0 + net8.0 enable enable anbs_cp_db anbs_cp.Database True ANBSoftware.ComponentsPack.Database - 2023.08.27.0 + 2023.11.14.0 Александр Бабаев Набор компонентов ANB Software для работы с БД Библиотека полезных методов языка C# для работы с базами данных @@ -19,8 +19,8 @@ - - + + diff --git a/anbs_cpdb/anbs_cpdb.csproj.DotSettings b/anbs_cpdb/anbs_cpdb.csproj.DotSettings new file mode 100644 index 0000000..632c268 --- /dev/null +++ b/anbs_cpdb/anbs_cpdb.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp120 \ No newline at end of file diff --git a/anbs_cpfn/anbs_cpfn.csproj b/anbs_cpfn/anbs_cpfn.csproj index 4c8faa1..dda3682 100644 --- a/anbs_cpfn/anbs_cpfn.csproj +++ b/anbs_cpfn/anbs_cpfn.csproj @@ -1,12 +1,12 @@ - net7.0 + net8.0 enable enable True ANBSoftware.ComponentsPackForNet - 2023.09.08.0 + 2023.11.14.0 Александр Бабаев Набор компонентов ANB Software для ASP.NET Core Библиотека полезных методов языка C# для ASP.NET Core @@ -20,11 +20,11 @@ - + - + diff --git a/anbs_cpfn/anbs_cpfn.csproj.DotSettings b/anbs_cpfn/anbs_cpfn.csproj.DotSettings new file mode 100644 index 0000000..632c268 --- /dev/null +++ b/anbs_cpfn/anbs_cpfn.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp120 \ No newline at end of file diff --git a/anbs_cposinfo/anbs_cposinfo.csproj b/anbs_cposinfo/anbs_cposinfo.csproj index ea64a25..45b2409 100644 --- a/anbs_cposinfo/anbs_cposinfo.csproj +++ b/anbs_cposinfo/anbs_cposinfo.csproj @@ -1,13 +1,13 @@ - net7.0 + net8.0 enable enable anbs_cp.OsInfo True ANBSoftware.ComponentsPackOsInfo - 2023.8.11 + 2023.11.14 Александр Бабаев Набор компонентов ANB Software для получения информации о Windows Библиотека полезных методов языка C# для получения информации об Windows @@ -18,8 +18,11 @@ - - + + + + + diff --git a/anbs_cposinfo/anbs_cposinfo.csproj.DotSettings b/anbs_cposinfo/anbs_cposinfo.csproj.DotSettings new file mode 100644 index 0000000..632c268 --- /dev/null +++ b/anbs_cposinfo/anbs_cposinfo.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp120 \ No newline at end of file diff --git a/anbsoftware.componentspack.sln b/anbsoftware.componentspack.sln index 1435a4a..bf66211 100644 --- a/anbsoftware.componentspack.sln +++ b/anbsoftware.componentspack.sln @@ -15,9 +15,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpfn", "anbs_cpfn\anbs {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}" + ProjectSection(ProjectDependencies) = postProject + {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/demo/demo.csproj b/demo/demo.csproj index 08dcf93..d547f4c 100644 --- a/demo/demo.csproj +++ b/demo/demo.csproj @@ -2,7 +2,7 @@ WinExe - net7.0-windows + net8.0-windows7.0 enable true enable diff --git a/demo/demo.csproj.DotSettings b/demo/demo.csproj.DotSettings index 4887f94..632c268 100644 --- a/demo/demo.csproj.DotSettings +++ b/demo/demo.csproj.DotSettings @@ -1,2 +1,2 @@  - CSharp100 \ No newline at end of file + CSharp120 \ No newline at end of file From 8e5d01bffa8e4264db7bc467c5f8a04add628bbd Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Nov 2023 07:28:25 +0300 Subject: [PATCH 51/51] 20231114-1 --- anbsoftware.componentspack.sln | 6 ------ 1 file changed, 6 deletions(-) diff --git a/anbsoftware.componentspack.sln b/anbsoftware.componentspack.sln index bf66211..0760bba 100644 --- a/anbsoftware.componentspack.sln +++ b/anbsoftware.componentspack.sln @@ -11,14 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "demo", "demo\demo.csproj", EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpfn", "anbs_cpfn\anbs_cpfn.csproj", "{EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}" - ProjectSection(ProjectDependencies) = postProject - {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}" - ProjectSection(ProjectDependencies) = postProject - {442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7} - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}" EndProject