20231114-2

This commit is contained in:
Alexander 2023-11-15 10:49:10 +03:00
commit 3b7c7bc522
86 changed files with 5277 additions and 450 deletions

View File

@ -1,7 +1,12 @@
# Что такое ANB Software Components Pack?
ANB Software Components Pack - набор полезных классов C#, которые расширяют возможности языка.
Они могут использоваться в приложенях для ОС Widows и серверов на базе этой ОС.
ANB Software Components Pack - набор полезных классов C#, которые расширяют возможности языка. Они могут использоваться в приложенях для ОС Widows и серверов на базе этой ОС.
# Лицензия
MIIT
# anbsoftware_componentspack
some classes that extend the capabilities of the C # language
# Лицензия
MIIT
MIIT

View File

@ -0,0 +1,63 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс ошибки
/// </summary>
public sealed class ActionError: IActionError
{
/// <summary>
/// Критичность ошибки:
/// при некритичных ошибках продолжение выполнения операции возможно,
/// а при критичных -- нет
/// </summary>
public bool IsCritical { get; init; }
/// <summary>
/// Объект ошибки
/// </summary>
public object Object { get; set; }
/// <summary>
/// Сообщение об ошибке
/// </summary>
public string Message { get; set; }
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionError ()
{
IsCritical = true;
Object = "Not Implemented";
Message = "Not Implemented";
}
/// <summary>
/// Конструктор с 2 параметрами
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="isCritical">Критичность ошибки</param>
public ActionError (string message, bool isCritical = true)
{
IsCritical = isCritical;
Object = "";
Message = message;
}
/// <summary>
/// Конструктор с 3 параметрами
/// </summary>
/// <param name="eObject">Объект ошибки</param>
/// <param name="message">Сообщение</param>
/// <param name="isCritical">Критичность ошибки</param>
public ActionError (object eObject, string message, bool isCritical = true)
{
IsCritical = isCritical;
Object = eObject;
Message = message;
}
#endregion
}

View File

@ -0,0 +1,49 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс предупреждения
/// </summary>
public sealed class ActionInfo: IActionInfo
{
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionInfo ()
{
IsStatusInfo = false;
Object = string.Empty;
Message = string.Empty;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="eObject">Объект</param>
/// <param name="message">Сообщение</param>
/// <param name="isStatus">Является статусной информацией?</param>
public ActionInfo (string eObject, string message, bool isStatus = false)
{
IsStatusInfo = isStatus;
Object = eObject;
Message = message;
}
#endregion
#region Реализация интерфейса
/// <summary>
/// Объект
/// </summary>
public object Object { get; set; }
/// <summary>
/// Сообщение
/// </summary>
public string Message { get; set; }
/// <summary>
/// Статусная информация (например, начало работы)
/// </summary>
public bool IsStatusInfo { get; init; }
#endregion
}

View File

@ -0,0 +1,337 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Состояние действия
///
/// Обновлено 2023.11.1
/// * Добавлен возвращаемый результат
///
/// Обновлено 2023.01.121.1:
/// * Заменены интерфейсы IAction* на соответствующие классы
/// </summary>
public class ActionState<T>
{
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionState ()
{
Info = new();
Warnings = new();
Errors = new();
Value = default;
}
/// <summary>
/// Конструктор с указанием начального значения <see cref="Value"/>
/// </summary>
/// <param name="defaultValue">Начальное значение <see cref="Value"/></param>
public ActionState (T defaultValue)
{
Info = new();
Warnings = new();
Errors = new();
Value = defaultValue;
}
/// <summary>
/// Список информации
/// </summary>
public List<ActionInfo> Info { get; }
/// <summary>
/// Список предупреждений
/// </summary>
public List<ActionWarning> Warnings { get; }
/// <summary>
/// Список ошибок
/// </summary>
public List<ActionError> Errors { get; }
/// <summary>
/// Значение
/// </summary>
public T? Value { get; set; }
#region Методы
#region Очистка
/// <summary>
/// Очищает список ошибок
/// </summary>
public void ClearErrors ()
{
Errors.Clear();
Errors.TrimExcess();
}
/// <summary>
/// Очищает список предупреждений
/// </summary>
public void ClearWarnings ()
{
Warnings.Clear();
Warnings.TrimExcess();
}
/// <summary>
/// Очищает список информации
/// </summary>
public void ClearInfo ()
{
Info.Clear();
Info.TrimExcess();
}
/// <summary>
/// Очищает все списки
/// </summary>
public void Clear ()
{
ClearInfo();
ClearWarnings();
ClearErrors();
}
#endregion
#region Добавление ошибки
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="error">Ошибка</param>
// ReSharper disable once MemberCanBeMadeStatic.Global
// ReSharper disable once FunctionRecursiveOnAllPaths
public void AddError (ActionError error) => Errors.Add(error);
/// <summary>
/// Добавляет ошибки в список
/// </summary>
/// <param name="errors">Список ошибок</param>
public void AddErrors(IEnumerable<ActionError> errors) => Errors.AddRange(errors);
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="critical">Является ли ошибка критической</param>
public void AddError (bool critical = true)
{
//Создаю ошибку
ActionError error = new("", critical);
//Добавляю ошибку
AddError(error);
}
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="message">Сообщение об ошибке</param>
/// <param name="critical">Является ли ошибка критической</param>
public void AddError (string message, bool critical = true)
{
//Создаю ошибку
ActionError error = new(message, critical);
//Добавляю ошибку
AddError(error);
}
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="errorObject">Объект ошибки</param>
/// <param name="message">Сообщение об ошибке</param>
/// /// <param name="critical">Является ли ошибка критической</param>
public void AddError (string errorObject, string message, bool critical = true)
{
//Создаю ошибку
ActionError error = new(errorObject, message, critical);
//Добавляю ошибку
AddError(error);
}
#endregion
#region Добавление предупреждения
/// <summary>
/// Добавление предупреждения
/// </summary>
/// <param name="warning">Предупреждение</param>
public void AddWarning (ActionWarning warning) => Warnings.Add(warning);
/// <summary>
/// Добавление предупреждений
/// </summary>
/// <param name="warnings">Список предупреждений</param>
public void AddWarnings(IEnumerable<ActionWarning> warnings) => Warnings.AddRange(warnings);
/// <summary>
/// Добавление предупреждение
/// </summary>
/// <param name="message">Текст предупреждения</param>
/// <param name="warningObject">Объект предупреждения</param>
public void AddWarning (string message, string warningObject = "")
{
//Создаю предупреждение
ActionWarning warning = new(warningObject, message);
//Добавляю предупреждение
AddWarning(warning);
}
#endregion
#region Добавление информации
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="info">Информация</param>
public void AddInfo (ActionInfo info) => Info.Add(info);
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="infos">Список информации</param>
public void AddInfos (IEnumerable<ActionInfo> infos) => Info.AddRange(infos);
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="message">Текст информации</param>
/// <param name="infoObject">Объект информации</param>
public void AddInfo (string message, string infoObject = "")
{
//Создаю информацию
ActionInfo info = new(infoObject, message);
//Добавляю информацию
AddInfo(info);
}
#endregion
#region Печать
/// <summary>
/// Печать списка ошибок
/// </summary>
/// <param name="formatList">Формат списка</param>
/// <param name="formatItem">Формат элемента списка</param>
/// <returns>Список ошибок в текстовой форме</returns>
public string PrintErrorList (string formatList, string formatItem)
{
string elements =
#pragma warning disable CS8625
Errors.Aggregate<IActionError, string>(null, (current, error) => current + error.PrintMessage(formatItem));
#pragma warning restore CS8625
return string.Format(formatList, elements);
}
/// <summary>
/// Печать списка предупреждений
/// </summary>
/// <param name="formatList">Формат списка</param>
/// <param name="formatItem">Формат элемента списка</param>
/// <returns>Список предупреждений в текстовой форме</returns>
public string PrintWarningList (string formatList, string formatItem)
{
string elements =
#pragma warning disable CS8625
Warnings.Aggregate<IActionWarning, string>(null,
#pragma warning restore CS8625
(current, warning) => current + warning.PrintMessage(formatItem));
return string.Format(formatList, elements);
}
/// <summary>
/// Печать списка информации
/// </summary>
/// <param name="formatList">Формат списка</param>
/// <param name="formatItem">Формат элемента списка</param>
/// <returns>Список информации в текстовой форме</returns>
public string PrintInfoList (string formatList, string formatItem)
{
string elements =
#pragma warning disable CS8625
Info.Aggregate<IActionInfo, string>(null, (current, info) => current + info.PrintMessage(formatItem));
#pragma warning restore CS8625
return string.Format(formatList, elements);
}
#endregion
#region Проверка на наличие
/// <summary>
/// Проверяет, есть ли ошибки
/// </summary>
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
/// <returns>Наличие ошибок</returns>
public bool HasErrors (bool ignoreNonCritical = false) =>
ignoreNonCritical ? Errors.Any(static error => error.IsCritical) : Errors.Any();
/// <summary>
/// Проверяет, есть ли предупреждения
/// </summary>
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
/// <returns>Наличие предупреждений</returns>
public bool HasWarnings (bool ignoreInformWarning = false) => ignoreInformWarning
? Warnings.Any(static warning => !warning.IsInformWarning)
: Warnings.Any();
/// <summary>
/// Проверяет, есть ли сообщения
/// </summary>
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
/// <returns>Наличие сообщений</returns>
public bool HasInfo (bool ignoreStatus) => ignoreStatus ? Info.Any(static info => !info.IsStatusInfo) : Info.Any();
/// <summary>
/// Успешно ли завершилось
/// </summary>
public bool IsSuccess (bool ignoreNonCriticalErrors = false) =>
!HasErrors(ignoreNonCriticalErrors) && !HasWarnings(true);
#endregion
#region Количество сообщений
/// <summary>
/// Количество ошибок
/// </summary>
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
/// <returns>Количество ошибок</returns>
public int ErrorsCount (bool ignoreNonCritical = false) =>
ignoreNonCritical ? Errors.Count(static error => error.IsCritical) : Errors.Count;
/// <summary>
/// Количество предупреждений
/// </summary>
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
/// <returns>Количество предупреждений</returns>
public int WarningsCount (bool ignoreInformWarning = false) => ignoreInformWarning
? Warnings.Count(static warning => !warning.IsInformWarning)
: Warnings.Count;
/// <summary>
/// Количество информационных сообщений
/// </summary>
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
/// <returns>Количество информационных сообщений</returns>
public int InfoCount (bool ignoreStatus) => ignoreStatus ? Info.Count(static info => !info.IsStatusInfo) : Info.Count;
#endregion
#region Добавление другого состояния
/// <summary>
/// Добавляет другое состояние (например, результат другого действия, который возвращает <see cref="ActionState"/>).
/// </summary>
/// <param name="state">Запись состояния</param>
public void AddState(ActionState state)
{
AddErrors(state.Errors);
AddWarnings(state.Warnings);
AddInfos(state.Info);
}
#endregion
#endregion
}

View File

@ -0,0 +1,9 @@
namespace anbs_cp.Classes;
/// <summary>
/// Состояние действия
///
/// Обновлено 2023.11.1
/// * Добавлен класс ActionState без возвращаемого значения
/// </summary>
public sealed class ActionState: ActionState<string> { }

View File

@ -0,0 +1,49 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс предупреждения
/// </summary>
public sealed class ActionWarning: IActionWarning
{
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionWarning ()
{
IsInformWarning = false;
Object = string.Empty;
Message = string.Empty;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="eObject">Объект</param>
/// <param name="message">Сообщение</param>
/// <param name="isInform">Является ли информирующим предупреждением</param>
public ActionWarning (string eObject, string message, bool isInform = false)
{
IsInformWarning = isInform;
Object = eObject;
Message = message;
}
#endregion
#region Реализация интерфейса
/// <summary>
/// Объект
/// </summary>
public object Object { get; set; }
/// <summary>
/// Сообщение
/// </summary>
public string Message { get; set; }
/// <summary>
/// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию.
/// </summary>
public bool IsInformWarning { get; init; }
#endregion
}

View File

@ -0,0 +1,61 @@
namespace anbs_cp.Classes;
/// <summary>
/// Обработчик параметров консоли
/// </summary>
public sealed class ConsoleParamsParser
{
/// <summary>
/// Массив параметров
/// </summary>
private readonly List<(string, string?)> _paramsList;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="consoleParams">Параметры консоли</param>
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.ToLower(), value));
}
}
/// <summary>
/// Проверяет наличие параметра
/// </summary>
/// <param name="param">Параметр</param>
/// <returns>Есть ли параметр в списке</returns>
public bool HasParam (string param) =>
_paramsList.Any(keyValue => keyValue.Item1 == param.ToLower());
/// <summary>
/// Получает значение параметра
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public string? GetValue (string param) =>
!HasParam(param) ? null : _paramsList.FirstOrDefault(keyValue => keyValue.Item1 == param.ToLower()).Item2;
/// <summary>
/// Получает список всех параметров
/// </summary>
/// <returns>Список всех параметров</returns>
public List<string> GetParamsList () =>
_paramsList.Select(static keyValue => keyValue.Item1.ToLower()).ToList();
}

View File

@ -0,0 +1,21 @@
namespace anbs_cp.Classes;
/// <summary>
/// Конвертер количества элементов
/// </summary>
public sealed class CountConverter : ValueConverter
{
/// <summary>
/// Имена размеров файлов по умолчанию
/// </summary>
public static readonly string[] DefaultNames = {"", "тыс.", "млн."};
/// <summary>
/// Конструктор класса
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="decimalPlace">Знаков после запятой (0, 1, 2)</param>
public CountConverter (string[] valueNames, byte decimalPlace = 0) : base(valueNames, 1000, decimalPlace)
{
}
}

View File

@ -0,0 +1,50 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Форматирует число элементов в понятную строку
/// </summary>
public sealed class CountFormatter : IValueFormatter
{
#region ойства класса
/// <summary>
/// Имена чисел (тысяч, миллионов, миллиардов и т.п.)
/// </summary>
public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." };
/// <summary>
/// Знаков после запятой
/// </summary>
public byte DecimalPlaces { get; set; } = 1;
/// <summary>
/// Делители чисел
/// </summary>
public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 };
#endregion
#region Реализация интерфейса
/// <summary>
/// Реализация интерфейса
/// </summary>
public string[] ValueNames
{
get => CountNames;
set => CountNames = value;
}
/// <summary>
/// Реализация интерфейса
/// </summary>
public long[] MaxSizes
{
get => Delimeters;
set => Delimeters = value;
}
#endregion
}

View File

@ -0,0 +1,37 @@
namespace anbs_cp.Classes.Encrypt;
/// <summary>
/// Статическая обертка для класса шифровки строк StringEncryptor
/// </summary>
public static class StringEncrypt
{
/// <summary>
/// Метод для шифрования строки <paramref name="text"/>
/// </summary>
/// <param name="text">Строка, которая должна быть зашифрована</param>
/// <param name="key">Ключ</param>
/// <returns>Этот статический метод возвращает зашифрованную строку <paramref name="text"/></returns>
public static string Encrypt (string text, string key) => new StringEncryptor().Encrypt(text, key);
/// <summary>
/// Метод для дешифрования строки <paramref name="text"/>
/// </summary>
/// <param name="text">Строка, которая должна быть дешифрована</param>
/// <param name="key">Ключ</param>
/// <returns>Этот статический метод возвращает дешифрованную строку <paramref name="text"/></returns>
public static string Decrypt (string text, string key) => new StringEncryptor().Decrypt(text, key);
/// <summary>
/// Декодирует зашифрованную строку в HTML-пригодный формат
/// </summary>
/// <param name="text">Зашифрованная строка</param>
/// <returns>Этот статический метод возвращает дешифрованную строку <paramref name="text"/></returns>
public static string Base64UrlEncode (string text) => new StringEncryptor().Base64UrlEncode(text);
/// <summary>
/// Раскодирует из декодированной строки в HTML-пригодный формат
/// </summary>
/// <param name="text">Декодированная строка</param>
/// <returns>Этот статический метод возвращает шифрованную строку <paramref name="text"/></returns>
public static string Base64UrlDecode (string text) => new StringEncryptor().Base64UrlDecode(text);
}

View File

@ -0,0 +1,127 @@
using System.Security.Cryptography;
using System.Text;
using anbs_cp.Interfaces;
namespace anbs_cp.Classes.Encrypt;
/// <summary>
/// Класс для шифровки строк
/// </summary>
public sealed class StringEncryptor: IEncryptor
{
/// <summary>
/// Получение ключа из строки
/// </summary>
/// <param name="s">Ключ-строка</param>
/// <param name="salt">Хэш-ключ</param>
/// <returns>Ключ</returns>
private static byte[] KeyFromString (string s, byte[] salt)
{
// Создаю хэшер
using Rfc2898DeriveBytes hasher = new(s, salt, 1000, HashAlgorithmName.SHA256);
// Получаю ключ
return hasher.GetBytes(32);
}
/// <summary>
/// Метод для шифрования строки <paramref name="value"/>
/// </summary>
/// <param name="value">Строка, которая должна быть зашифрована</param>
/// <param name="salt">Ключ</param>
/// <returns>Этот метод возвращает зашифрованную строку <paramref name="value"/></returns>
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());
}
/// <summary>
/// Метод для дешифрования строки <paramref name="encryptedValue"/>
/// </summary>
/// <param name="encryptedValue">Строка, которая должна быть дешифрована</param>
/// <param name="salt">Ключ</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="encryptedValue"/></returns>
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());
}
/// <summary>
/// Декодирует зашифрованную строку в HTML-пригодный формат
/// </summary>
/// <param name="text">Зашифрованная строка</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="text"/></returns>
public string Base64UrlEncode (string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_');
/// <summary>
/// Раскодирует из декодированной строки в HTML-пригодный формат
/// </summary>
/// <param name="text">Декодированная строка</param>
/// <returns>Этот метод возвращает шифрованную строку <paramref name="text"/></returns>
public string Base64UrlDecode (string text)
{
// Первоначальная замена
string result = text.Replace('_', '/').Replace('-', '+');
// Заменяю значения
switch (result.Length % 4)
{
case 2:
result += "==";
break;
case 3:
result += "=";
break;
}
// Возвращаю результат
return result;
}
}

View File

@ -0,0 +1,37 @@
namespace anbs_cp.Classes.Exceptions;
/// <summary>
/// Класс-исключение для переименования папок/файлов
/// </summary>
public sealed class RenameException : Exception
{
/// <summary>
/// Имя файла/папки
/// </summary>
public string FileName { get; }
/// <summary>
/// Описание ошибки
/// </summary>
public string? ErrorMessage { get; }
/// <summary>
/// Конструктор
/// </summary>
/// <param name="fileName">Имя файла/папки</param>
/// <param name="errorMessage">Описание ошибки</param>
public RenameException(string fileName, string? errorMessage) : base(GetMessage(fileName, errorMessage ?? string.Empty))
{
FileName = fileName;
ErrorMessage = errorMessage;
}
/// <summary>
/// Получение текстового представление ошибки
/// </summary>
/// <param name="fileName">Имя файла/папки</param>
/// <param name="errorMessage">Описание ошибки</param>
/// <returns>Текстовое представление ошибки</returns>
private static string GetMessage(string fileName, string errorMessage) =>
$"При переименовании файла/папки {fileName} возникла следующая ошибка: {errorMessage}";
}

View File

@ -0,0 +1,27 @@
namespace anbs_cp.Classes;
/// <summary>
/// Класс -- расширение для класса File
/// </summary>
public static class FileExtension
{
/// <summary>
/// Получает MIME-тип файла
/// </summary>
/// <param name="filename">Имя файла</param>
/// <returns>MIME-тип файла</returns>
public static string MIMEType (string filename) =>
MimeTypes.GetMimeType(filename);
/// <summary>
/// Размер файла в байтах
/// </summary>
/// <param name="fileName">Полное имя и путь к файлу</param>
/// <returns>Размер файла в байтах</returns>
public static long FileSize(string fileName)
{
FileInfo fileInfo = new (fileName);
return fileInfo.Length;
}
}

View File

@ -0,0 +1,52 @@
using System.Security.Cryptography;
using System.Text;
namespace anbs_cp.Classes;
/// <summary>
/// Класс для работы с хэшем файла
/// </summary>
public sealed class FileHash
{
/// <summary>
/// Получение md5-хэша файла.
/// Взято с https://stackoverflow.com/a/24031467/16469671
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <returns>Массив хэша</returns>
public FileHash (string fileName)
{
using MD5 md5 = MD5.Create();
using FileStream stream = File.OpenRead(fileName);
Hash = md5.ComputeHash(stream);
}
/// <summary>
/// Простой конструктор
/// </summary>
public FileHash ()
{
Hash = new byte[] { };
}
/// <summary>
/// Хэш файла
/// </summary>
public byte[] Hash { get; private set; }
/// <summary>
/// Вывод в строку
/// </summary>
/// <returns>Строка хэша файла</returns>
public override string ToString () => BitConverter.ToString(Hash).Replace("-", "").ToLowerInvariant();
/// <summary>
/// Конвертирует строку в хэш
/// </summary>
/// <param name="value">Строка</param>
public void FromString (string value)
{
UTF8Encoding utf8 = new();
Hash = utf8.GetBytes(value);
}
}

View File

@ -0,0 +1,21 @@
namespace anbs_cp.Classes;
/// <summary>
/// Конвертер размеров файлов
/// </summary>
public sealed class FileSizeConverter : ValueConverter
{
/// <summary>
/// Имена размеров файлов по умолчанию
/// </summary>
public static readonly string[] DefaultNames = {"байт", "Кб", "Мб", "Гб", "Тб"};
/// <summary>
/// Конструктор класса
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="decimalPlace">Знаков после запятой (0, 1, 2)</param>
public FileSizeConverter (string[] valueNames, byte decimalPlace = 2) : base(valueNames, 1024, decimalPlace)
{
}
}

View File

@ -0,0 +1,71 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Форматирует размер файла/папки в понятную строку
/// </summary>
public class FileSizeFormatter : IValueFormatter
{
#region ойства класса
/// <summary>
/// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт)
/// </summary>
public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" };
/// <summary>
/// Знаков после запятой
/// </summary>
public byte DecimalPlaces { get; set; } = 2;
/// <summary>
/// Максимально байт (далее идут Кбайты)
/// </summary>
public long ByteMax { get; set; } = 1024;
/// <summary>
/// Максимально Кбайт (далее идут Мбайты)
/// </summary>
public long KByteMax { get; set; } = 1048576;
/// <summary>
/// Максимально Мбайт (далее идут Гбайты)
/// </summary>
public long MByteMax { get; set; } = 1073741824;
/// <summary>
/// Максимально Гбайт (далее идут Тбайты)
/// </summary>
public long GByteMax { get; set; } = 1099511627776;
#endregion
#region Реализация интерфейса
/// <summary>
/// Реализация интерфейса
/// </summary>
public string[] ValueNames
{
get => SizeNames;
set => SizeNames = value;
}
/// <summary>
/// Реализация интерфейса
/// </summary>
public long[] MaxSizes
{
get => new[] { ByteMax, KByteMax, MByteMax, GByteMax };
set
{
ByteMax = value[0];
KByteMax = value[1];
MByteMax = value[2];
GByteMax = value[3];
}
}
#endregion
}

View File

@ -0,0 +1,163 @@
using System.Collections;
using anbs_cp.Structs;
namespace anbs_cp.Classes;
/// <summary>
/// Список из пара ключ-значение
/// </summary>
/// <typeparam name="TK">Тип ключа</typeparam>
/// <typeparam name="TV">Тип значения</typeparam>
public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>
{
/// <summary>
/// Хранение значений
/// </summary>
private readonly List<KeyValue<TK, TV>> _list;
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public KeyValueList () => _list = new();
#endregion
#region Свойства
/// <summary>
/// Список ключей из списка
/// </summary>
public IEnumerable<TK> Keys => GetKeys();
#endregion
#region Методы
/// <summary>
/// Получает список ключей
/// </summary>
/// <returns>Список ключей</returns>
private IEnumerable<TK> GetKeys () => from keyValue in _list where keyValue.Key is not null select keyValue.Key;
/// <summary>
/// Добавляет в список параметр
/// </summary>
/// <param name="keyValue">Параметр</param>
public void Add (KeyValue<TK, TV> keyValue) => _list.Add(keyValue);
/// <summary>
/// Добавляет в список параметр
/// </summary>
/// <param name="key">Ключ параметра</param>
/// <param name="value">Значение</param>
public void Add (TK key, TV value) => _list.Add(new(key, value));
/// <summary>
/// Изменяет значение
/// </summary>
/// <param name="keyValue">Новое значение</param>
public void ChangeValue (KeyValue<TK, TV> keyValue)
{
// Если такой ключ не существует
if (!Contains(keyValue.Key!))
{
// - тогда добавляю новое значение
Add(keyValue);
// - прерываю
return;
}
// Существующее значение
KeyValue<TK, TV> existValue = GetItem(keyValue.Key!) ?? new();
// Удаляем существующее
_list.Remove(existValue);
// Добавляем новое
_list.Add(keyValue);
}
/// <summary>
/// Изменяет значение
/// </summary>
/// <param name="key">Ключ</param>
/// <param name="newValue">Новое значение</param>
public void ChangeValue (TK key, TV newValue) => ChangeValue(new(key, newValue));
/// <summary>
/// Получает элемент по ключу
/// </summary>
/// <param name="key">Ключ</param>
/// <returns>Элемент <see cref="KeyValue{TK,TV}"/></returns>
public KeyValue<TK, TV>? GetItem (TK key)
{
// Ищем элемент в списке
foreach (KeyValue<TK, TV> keyValueItem in _list.Where(keyValueItem => keyValueItem.Key!.Equals(key)))
// - возвращаем его при нахождении
return keyValueItem;
// Элемент не найден -- вывожу null
return null;
}
/// <summary>
/// Получает значение
/// </summary>
/// <param name="key">Ключ</param>
/// <returns>Значение</returns>
public TV? GetValue (TK key)
{
// Если такой ключ не существует
if (!Contains(key))
// Тогда возвращаю значение по умолчанию
return default;
// Получаю элемент
KeyValue<TK, TV> keyValue = GetItem(key) ?? new();
// Вывожу значение
return keyValue.Value;
}
/// <summary>
/// Удаляет элемент из списка
/// </summary>
/// <param name="keyValue">Элемент</param>
public void Remove (KeyValue<TK, TV> keyValue) => _list.Remove(keyValue);
/// <summary>
/// Удаляет элемент из списка
/// </summary>
/// <param name="key">Ключ элемента</param>
public void Remove (TK key) => Remove(GetItem(key) ?? new());
/// <summary>
/// Проверяет, содержится ли элемент в списке
/// </summary>
/// <param name="keyValue">Элемент</param>
/// <returns>Результат проверки</returns>
public bool Contains (KeyValue<TK, TV> keyValue) => _list.Contains(keyValue);
/// <summary>
/// Проверяет, содержится ли элемент в списке
/// </summary>
/// <param name="key">Ключ элемента</param>
/// <returns>Результат проверки</returns>
public bool Contains (TK key) => Keys.Any(keyParam => keyParam!.Equals(key));
#endregion
#region Реализация интерфейса IEnumerable<KeyValue<TK, TV>>
/// <summary>
/// Получаю <see cref="IEnumerator"/>
/// </summary>
/// <returns><see cref="IEnumerator"/></returns>
public IEnumerator<KeyValue<TK, TV>> GetEnumerator () => _list.GetEnumerator();
/// <summary>
/// Получаю <see cref="IEnumerator"/>
/// </summary>
/// <returns><see cref="IEnumerator"/></returns>
IEnumerator IEnumerable.GetEnumerator () => GetEnumerator();
#endregion
}

View File

@ -0,0 +1,147 @@
using anbs_cp.Classes.Exceptions;
using anbs_cp.Enums;
namespace anbs_cp.Classes;
/// <summary>
/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#.
/// </summary>
public static class LikeDelphi
{
/// <summary>
/// Аналог функции IncludeTrailingBackslash
/// </summary>
/// <param name="path">Путь, к которому нужно добавить slash</param>
/// <returns>Путь со slash в конце</returns>
public static string IncludeTrailingBackslash (string path)
{
//По умолчанию сохраняем путь
string result = path;
//Если последний символ не "\", то добавим "\" в конце
if (path[^1] != '\\')
result = $@"{path}\";
//Вернём результат
return result;
}
/// <summary>
/// Парсер строки в множество строк
/// </summary>
/// <param name="str">Строка, которую нужно разбить</param>
/// <param name="delimiter">Символ-делитель строки</param>
/// <returns>Массив строк</returns>
public static List<string> ParseString (string str, char delimiter) => str.Split(delimiter).ToList();
/// <summary>
/// Переименовываю файл
/// </summary>
/// <param name="oldName">Старое имя файла (с полным путём)</param>
/// <param name="newName">Новое имя файла (с полным путём)</param>
/// <param name="ifExist">Что делать, если существует</param>
/// <exception cref="RenameException">Если <paramref name="ifExist" /> имеет значение <value>RaiseException</value>, то генерируется ошибка переименования файла</exception>
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);
}
/// <summary>
/// Удаление папки
/// </summary>
/// <param name="dir">Папка</param>
public static void RemoveDir (string dir) => Directory.Delete(dir, true);
/// <summary>
/// Проверяет папку на пустоту
/// Оригинальный ответ от OwenGlendower (https://www.cyberforum.ru/windows-forms/thread1995240.html)
/// </summary>
/// <param name="dir">Проверяемая папка</param>
/// <returns>Пуста (<value>true</value>) или не пуста (<value>false</value>) папка <see cref="dir"/></returns>
public static bool IsDirEmpty (string dir) => !Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories).Any();
/// <summary>
/// Переименовывает папку
/// </summary>
/// <param name="oldName">Старое имя папки (с полным путём)</param>
/// <param name="newName">Новое имя папки (с полным путём)</param>
/// <param name="ifExist">Что делать, если существует</param>
/// <exception cref="RenameException">Если <paramref name="ifExist" /> имеет значение <value>RaiseException</value>, то генерируется ошибка переименования папки</exception>
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);
}
}

View File

@ -0,0 +1,50 @@
namespace anbs_cp.Classes;
/// <summary>
/// Параметры пароля
/// </summary>
public sealed class PasswordOptions
{
/// <summary>
/// Конструктор
/// </summary>
public PasswordOptions ()
{
RequiredLength = 8;
RequireLowercase = true;
RequireUppercase = true;
RequireDigit = true;
RequireNonAlphanumeric = false;
RequiredUniqueChars = 6;
}
/// <summary>
/// Требуемая длина пароля
/// </summary>
public byte RequiredLength { get; set; }
/// <summary>
/// Требовать строчные буквы в пароле
/// </summary>
public bool RequireLowercase { get; set; }
/// <summary>
/// Требовать прописные буквы в пароле
/// </summary>
public bool RequireUppercase { get; set; }
/// <summary>
/// Требовать цифры в пароле
/// </summary>
public bool RequireDigit { get; set; }
/// <summary>
/// Требовать символы
/// </summary>
public bool RequireNonAlphanumeric { get; set; }
/// <summary>
/// Уникальных символов
/// </summary>
public byte RequiredUniqueChars { get; set; }
}

View File

@ -0,0 +1,133 @@
using System.Reflection;
namespace anbs_cp.Classes;
/// <summary>
/// Класс перевода одинаковых свойств из класса TF в класс T.
/// Оригинальные автор(-ы): keenthinker и Avtandil Kavrelishvili.
/// Улучшения: А. Н. Бабаев
/// URL: https://stackoverflow.com/questions/20410234/how-to-automatically-map-the-values-between-instances-of-two-different-classes-i
/// </summary>
public static class SimpleMapper
{
/// <summary>
/// Перевод одинаковых свойств из класса F в класс TT.
/// </summary>
/// <param name="from">Экземпляр класса F</param>
/// <param name="to">Ссылка на экземпляр класса T</param>
/// <param name="mode">Тип сопоставления</param>
/// <param name="list">Список параметров для сопоставления</param>
/// <typeparam name="TF">Класс-родитель</typeparam>
/// <typeparam name="T">Класс-приемник</typeparam>
public static void MapEx<TF, T>(TF from, ref T to, MapMode mode, List<string> list)
{
//Копирую поля
Type typeOfA = typeof(TF);
Type typeOfB = typeof(T);
foreach (FieldInfo fieldOfA in typeOfA.GetFields())
{
//Проверяем выполнение условия и прерываем, если не выполняется
if (!CheckCondition<TF>(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<TF>(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));
}
}
/// <summary>
/// Перевод одинаковых свойств из класса F в класс TT (режим "сопоставление всех параметров").
/// </summary>
/// <param name="from">Параметр класса F</param>
/// <typeparam name="TF">Класс-родитель</typeparam>
/// <typeparam name="T">Класс-приемник</typeparam>
/// <returns>Элемент класса T</returns>
public static T Map<TF, T>(TF from)
{
//Создаю элемент
// ReSharper disable once NullableWarningSuppressionIsUsed
T result = (T)Activator.CreateInstance(typeof(T))!;
//Сопоставляю по принципу "сопоставление всех параметров"
MapEx(from, ref result, MapMode.MapFull, new());
//Вывожу в результат
return result;
}
/// <summary>
/// Проверка выполнения условия
/// </summary>
/// <param name="itemName">Имя элемента</param>
/// <param name="itemValue">Значение элемента</param>
/// <param name="mode">Режим проверки</param>
/// <param name="list">Список игнорирования/добавления</param>
/// <returns></returns>
private static bool CheckCondition<T>(string itemName, object? itemValue, MapMode mode, ICollection<string> 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 => !Equals(itemValue, default(T)),
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null)
};
//Возвращаем результат
return result;
}
/// <summary>
/// Перечисление типов сопоставления
/// </summary>
public enum MapMode
{
/// <summary>
/// Сопоставление всех параметров
/// </summary>
MapFull = 0,
/// <summary>
/// Сопоставление не пустых параметров
/// </summary>
MapNotNull = 1,
/// <summary>
/// Сопоставление по списку
/// </summary>
MapByList = 2,
/// <summary>
/// Сопоставление исключая список
/// </summary>
MapIgnoreList = 3,
/// <summary>
/// Сопоставление параметров, которые не равны значению по умолчанию
/// </summary>
MapNotDefault = 4,
/// <summary>
/// Сопоставление не пустых параметров, которые не равны значению по умолчанию (NotNull и NotDefault одновременно)
/// </summary>
MapNotNullOrDefault = 5,
}
}

View File

@ -0,0 +1,128 @@
using System.Net.Mail;
using System.Text.RegularExpressions;
namespace anbs_cp.Classes;
/// <summary>
/// Форматирование текста
/// </summary>
public static class TextFormatter
{
/// <summary>
/// Заменяет %МАРКЕРЫ% на их значения
/// </summary>
/// <param name="message">Текст сообщения</param>
/// <param name="replaceDictionary">Словарь замен</param>
/// <returns>Отформатированное сообщение</returns>
public static string FormatMessage (string message, Dictionary<string, string> replaceDictionary) =>
replaceDictionary.Aggregate(message,
static (current, item) => current.Replace($"%{item.Key}%", item.Value));
/// <summary>
/// Обрезает строку до указанных в параметре <paramref name="maxLength"/> символов
/// </summary>
/// <param name="text">Текст, который нужно обрезать</param>
/// <param name="maxLength">Максимальное количество символов в тексте</param>
/// <param name="endDots">Чем завершать обрезанный текст, если он был обрезан. Внимание расходует <see cref="maxLength"/>!</param>
/// <returns>Обрезанный текст</returns>
public static string GetShortText (string text, int maxLength, string endDots = "") =>
text.Length < maxLength ? text : $"{text[..(maxLength - endDots.Length)]}{endDots}";
/// <summary>
/// Генерирует случайный пароль, удовлетворяющий параметрам <see cref="PasswordOptions"/> <paramref name="options"/>.
/// Автор метода: Darkseal (https://stackoverflow.com/users/1233379/darkseal)
/// URL: https://stackoverflow.com/a/46229180/16469671
/// </summary>
/// <param name="options">Объект допустимых параметров пароля, содержащий требования к надежности пароля.</param>
/// <returns>Случайный пароль</returns>
public static string GenerateRandomPassword (PasswordOptions? options)
{
//Проверка options и установка по-умолчанию
options ??= new();
//Получаю массив символов
string[] randomChars = {
"ABCDEFGHJKLMNOPQRSTUVWXYZ", // прописные буквы
"abcdefghijkmnopqrstuvwxyz", // строчные буквы
"0123456789", // цифры
"~!@#$%^&*+-/.,{}[]();:|?<>='`" // символы
};
//Создаю объект Random
Random rand = new(Environment.TickCount);
//Массив результатов
List<char> 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());
}
/// <summary>
/// Проверяет <paramref name="email"/> на соответствие критерию электронной почты
/// Взято с: https://stackoverflow.com/a/1374644/16469671
/// </summary>
/// <param name="email">Проверяемая строка</param>
/// <returns>Является ли <paramref name="email"/> адресом электронной почты</returns>
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;
}
}
/// <summary>
/// Проверяет текст <paramref name="text"/> на совпадение регулярному выражению по шаблону <paramref name="pattern"/> с опциями <paramref name="options"/> (см. <see cref="RegexOptions"/>)
/// </summary>
/// <param name="text">Текст на проверку</param>
/// <param name="pattern">Шаблон</param>
/// <param name="options">Параметры проверки в формате <see cref="RegexOptions"/> (можно игнорировать, по умолчанию: <see cref="RegexOptions.IgnoreCase"/>)</param>
/// <returns>Есть ли совпадения в тексте</returns>
public static bool IsMatchRegExp (string text, string pattern, RegexOptions? options = null)
{
// Задаю настройки проверки регулярных выражений
RegexOptions regexOptions = options ?? RegexOptions.IgnoreCase;
// Возвращаю результат
return Regex.IsMatch(text, pattern, regexOptions);
}
}

View File

@ -0,0 +1,90 @@
namespace anbs_cp.Classes;
/// <summary>
/// Класс проверки временного интервала
/// </summary>
public static class TimestampValidator
{
/// <summary>
/// Проверка попадания в заданный интервал (в мс)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="checkedStamp">Проверяемый временной интервал</param>
/// <param name="deltaMs">Временная дельта в миллисекундах</param>
/// <returns>
/// Попал ли <paramref name="checkedStamp" /> в промежуток <paramref name="timestamp" /> +
/// <paramref name="deltaMs" />
/// </returns>
public static bool Validate(long timestamp, long checkedStamp, ulong deltaMs) =>
new TimeSpan(timestamp) + TimeSpan.FromMilliseconds(deltaMs) > new TimeSpan(checkedStamp);
/// <summary>
/// Проверка попадания текущего времени в заданный интервал (в мс)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="deltams">Временная дельта в миллисекундах</param>
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltams" /></returns>
public static bool ValidateNow(long timestamp, ulong deltams) =>
Validate(timestamp, DateTime.UtcNow.Ticks, deltams);
/// <summary>
/// Проверка временного интервала (в сек)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="checkedstamp">Проверяемый временной интервал</param>
/// <param name="deltasec">Временная дельта в секундах</param>
/// <returns>Попал ли <see cref="checkedstamp" /> в промежуток</returns>
public static bool ValidateFromSec(long timestamp, long checkedstamp, ulong deltasec) =>
Validate(timestamp, checkedstamp, checked(deltasec * 1000UL));
/// <summary>
/// Проверка попадания текущего времени в заданный интервал (в сек)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="deltasec">Временная дельта в секундах</param>
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltasec" /></returns>
public static bool ValidateFromSecNow(long timestamp, ulong deltasec) =>
ValidateFromSec(timestamp, DateTime.UtcNow.Ticks, deltasec);
/// <summary>
/// Проверка временного интервала (в мин)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="checkedstamp">Проверяемый временной интервал</param>
/// <param name="deltamin">Временная дельта в минутах</param>
/// <returns>
/// Попал ли <see cref="checkedstamp" /> в промежуток <paramref name="timestamp" /> + <paramref name="deltamin" />
/// </returns>
public static bool ValidateFromMin(long timestamp, long checkedstamp, ulong deltamin) =>
Validate(timestamp, checkedstamp, checked(deltamin * 60000UL));
/// <summary>
/// Проверка попадания текущего времени в заданный интервал (в мин)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="deltamin">Временная дельта в минутах</param>
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltamin" /></returns>
public static bool ValidateFromMinNow(long timestamp, ulong deltamin) =>
ValidateFromMin(timestamp, DateTime.UtcNow.Ticks, deltamin);
/// <summary>
/// Проверка временного интервала (в час)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="checkedStamp">Проверяемый временной интервал</param>
/// <param name="deltaHour">Временная дельта в часах</param>
/// <returns>
/// Попал ли <see cref="checkedStamp" /> в промежуток <paramref name="timestamp" /> + <paramref name="deltaHour" />
/// </returns>
public static bool ValidateFromHour(long timestamp, long checkedStamp, ulong deltaHour) =>
Validate(timestamp, checkedStamp, checked(deltaHour * 3600000UL));
/// <summary>
/// Проверка попадания текущего времени в заданный интервал (в час)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="deltahr">Временная дельта в часах</param>
/// <returns>Попадает ли текущее время в промежуток <paramref name="timestamp" /> + <paramref name="deltahr" /></returns>
public static bool ValidateFromHourNow(long timestamp, ulong deltahr) =>
ValidateFromHour(timestamp, DateTime.UtcNow.Ticks, deltahr);
}

View File

@ -0,0 +1,165 @@
using System.Globalization;
using Newtonsoft.Json;
namespace anbs_cp.Classes;
/// <summary>
/// Конвертер типов на манер Delphi
/// </summary>
public static class TypeConverter
{
#region Конвертация числа в строку
/// <summary>
/// Преобразование <see cref="int"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string IntToStr (int value) => value.ToString();
/// <summary>
/// Преобразование <see cref="uint"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string IntToStr (uint value) => value.ToString();
/// <summary>
/// Преобразование <see cref="long"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string IntToStr (long value) => value.ToString();
/// <summary>
/// Преобразование <see cref="ulong"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string IntToStr (ulong value) => value.ToString();
/// <summary>
/// Преобразование <see cref="byte"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string IntToStr (byte value) => value.ToString();
/// <summary>
/// Преобразование <see cref="decimal"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string DecimalToStr (decimal value) => value.ToString(CultureInfo.InvariantCulture);
/// <summary>
/// Преобразование <see cref="double"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Число</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string DoubleToStr (double value) => value.ToString(CultureInfo.InvariantCulture);
/// <summary>
/// Преобразование <see cref="bool"/> в <see cref="string"/>
/// </summary>
/// <param name="value">Значение правда/ложь</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string BoolToStr (bool value) => value.ToString();
/// <summary>
/// Преобразование любого типа в <see cref="string"/> (сериализация)
/// </summary>
/// <typeparam name="T">Тип</typeparam>
/// <param name="value">Значение типа</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string TypeToStr<T> (T value) => JsonConvert.SerializeObject(value);
#endregion
#region Конвертация строки в число
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="int"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="int"/></returns>
public static int StrToInt (string value, int defaultValue = 0) =>
int.TryParse(value, out int result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="uint"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="uint"/></returns>
public static uint StrToUInt (string value, uint defaultValue = 0) =>
uint.TryParse(value, out uint result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="long"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="long"/></returns>
public static long StrToInt64 (string value, long defaultValue = 0) =>
long.TryParse(value, out long result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="ulong"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="ulong"/></returns>
public static ulong StrToUInt64 (string value, ulong defaultValue = 0) =>
ulong.TryParse(value, out ulong result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="byte"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="byte"/></returns>
public static byte StrToByte (string value, byte defaultValue = byte.MinValue) =>
byte.TryParse(value, out byte result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="decimal"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию (<see cref="decimal.Zero"/>)</param>
/// <returns>Значение в <see cref="decimal"/></returns>
public static decimal StrToDecimal (string value, decimal defaultValue = decimal.Zero) =>
decimal.TryParse(value, out decimal result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="double"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="double"/></returns>
public static double StrToDouble (string value, double defaultValue = 0) =>
double.TryParse(value, out double result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в <see cref="bool"/>
/// </summary>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="bool"/></returns>
public static bool StrToBool (string value, bool defaultValue = false) =>
bool.TryParse(value, out bool result) ? result : defaultValue;
/// <summary>
/// Преобразование <see cref="string"/> в тип <see cref="T"/> (десериализация)
/// </summary>
/// <typeparam name="T">Тип</typeparam>
/// <param name="value">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="T"/></returns>
public static T StrToType<T>(string value, T defaultValue) =>
JsonConvert.DeserializeObject<T>(value) ?? defaultValue;
#endregion
}

View File

@ -0,0 +1,87 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Абстрактный класс конвертера величин для отображения (улучшенный аналог ValueFormatter)
/// </summary>
public abstract class ValueConverter: IValueConverter
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="divider">Делитель</param>
/// <param name="decimalPlaces">Число знаков после запятой</param>
protected ValueConverter (string[] valueNames, long divider, byte decimalPlaces)
{
ValueNames = valueNames;
Divider = divider;
DecimalPlaces = (byte)(decimalPlaces < 3 ? decimalPlaces : 2);
}
#region Реализация интерфейса
/// <summary>
/// Массив имён размерностей
/// </summary>
public string[] ValueNames { get; init; }
/// <summary>
/// Делитель
/// </summary>
public long Divider { get; init; }
/// <summary>
/// Знаков после запятой (0, 1, 2)
/// </summary>
public byte DecimalPlaces { get; init; }
#endregion
#region Методы
/// <summary>
/// Функция конвертирования в строку
/// </summary>
/// <param name="value">Значение</param>
/// <returns>Конвертирование значение в строку</returns>
public string Convert (long value)
{
//Получаю разделенное значение
(decimal, int) result = DivideIt(value, 0);
//Преобразую значение в строку
string resultValue = DecimalPlaces switch {
0 => $"{result.Item1:F0}",
1 => $"{result.Item1:F1}",
_ => $"{result.Item1:F2}"
};
//Возвращаю результат
return $"{resultValue} {ValueNames[result.Item2]}";
}
/// <summary>
/// Рекурсивная функция деления
/// </summary>
/// <param name="value">Число</param>
/// <param name="count">Счётчик вызова рекурсии</param>
/// <returns>Число в остатке и количество вызовов рекурсии</returns>
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
}

View File

@ -1,34 +0,0 @@
namespace anbs_cp
{
/// <summary>
/// Форматирует число элементов в понятную строку
/// </summary>
public class CountFormatter : IValueFormatter
{
#region ойства класса
/// <summary>
/// Имена чисел (тысяч, миллионов, миллиардов и т.п.)
/// </summary>
public string[] CountNames { get; set; } = { "", "тыс.", "млн.", "млрд." };
/// <summary>
/// Знаков после запятой
/// </summary>
public byte DecimalPlaces { get; set; } = 1;
/// <summary>
/// Делители чисел
/// </summary>
public long[] Delimeters { get; set; } = { 1000, 1000000, 1000000000 };
#endregion
#region Реализация интерфейса
/// <summary>
/// Реализация интерфейса
/// </summary>
public string[] ValueNames { get => CountNames; set => CountNames = value; }
/// <summary>
/// Реализация интерфейса
/// </summary>
public long[] MaxSizes { get => Delimeters; set => Delimeters = value; }
#endregion
}
}

View File

@ -0,0 +1,32 @@
namespace anbs_cp.Enums;
/// <summary>
/// Действия при операции переименования, если файл существует
/// </summary>
public enum EOnExistAction
{
/// <summary>
/// Возбуждать исключение
/// </summary>
RaiseException = 0,
/// <summary>
/// Прервать операцию
/// </summary>
Abort = 1,
/// <summary>
/// Продолжить операцию
/// </summary>
Ignore = 2,
/// <summary>
/// Возбуждать исключение, если папка не пуста (только для папок)
/// </summary>
RaiseExceptionIfNotEmpty = 3,
/// <summary>
/// Прервать операцию, если папка не пуста (только для папок)
/// </summary>
AbortIfNotEmpty = 4
}

View File

@ -1,56 +0,0 @@
namespace anbs_cp
{
/// <summary>
/// Форматирует размер файла/папки в понятную строку
/// </summary>
public class FileSizeFormatter : IValueFormatter
{
#region ойства класса
/// <summary>
/// Имена размеров (байт, килобайт, мегабайт, гигабайт и террабайт)
/// </summary>
public string[] SizeNames { get; set; } = { "Байт", "Кб", "Мб", "Гб", "Тб" };
/// <summary>
/// Знаков после запятой
/// </summary>
public byte DecimalPlaces { get; set; } = 2;
/// <summary>
/// Максимально байт (далее идут Кбайты)
/// </summary>
public long ByteMax { get; set; } = 1024;
/// <summary>
/// Максимально Кбайт (далее идут Мбайты)
/// </summary>
public long KByteMax { get; set; } = 1048576;
/// <summary>
/// Максимально Мбайт (далее идут Гбайты)
/// </summary>
public long MByteMax { get; set; } = 1073741824;
/// <summary>
/// Максимально Гбайт (далее идут Тбайты)
/// </summary>
public long GByteMax { get; set; } = 1099511627776;
#endregion
#region Реализация интерфейса
/// <summary>
/// Реализация интерфейса
/// </summary>
public string[] ValueNames { get => SizeNames; set => SizeNames = value; }
/// <summary>
/// Реализация интерфейса
/// </summary>
public long[] MaxSizes
{
get => new long[] { ByteMax, KByteMax, MByteMax, GByteMax };
set
{
ByteMax = value[0];
KByteMax = value[1];
MByteMax = value[2];
GByteMax = value[3];
}
}
#endregion
}
}

View File

@ -1,82 +0,0 @@
namespace anbs_cp
{
/// <summary>
/// Форматирует размерности в понятную строку
/// </summary>
public interface IValueFormatter
{
#region Определения интерфейса
/// <summary>
/// Имена размерностей
/// </summary>
public string[] ValueNames { get; set; }
/// <summary>
/// Знаков после запятой
/// </summary>
public byte DecimalPlaces { get; set; }
/// <summary>
/// Максимальные размеры (массив ulong[4])
/// </summary>
public long[] MaxSizes { get; set; }
#endregion
#region Методы интерфейса
/// <summary>
/// Форматирование размерности
/// </summary>
/// <param name="value">Размерность, требующая форматирования</param>
/// <returns>Форматированная размерность (например, 20 Мб)</returns>
public string Format(long value)
{
//Левая граница
long leftnum;
//Правая граница
long rightnum;
for (int i = 0; i <= MaxSizes.Length; i++)
{
if (i == 0)
leftnum = 0;
else
leftnum = MaxSizes[i - 1];
if (i == MaxSizes.Length)
rightnum = long.MaxValue;
else
rightnum = MaxSizes[i];
if ((value >= leftnum) && (value < rightnum))
return $"{FormatValue(value, leftnum)} {ValueNames[i]}";
}
return value.ToString();
}
/// <summary>
/// Деление числа на число с DecimalPlaces знаками после запятой
/// </summary>
/// <param name="dividend">Делимое число</param>
/// <param name="divider">Число-делитель</param>
/// <returns>Частное (с DecimalPlaces знаками после запятой)</returns>
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
}
}

View File

@ -0,0 +1,14 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс ошибки
/// </summary>
public interface IActionError : IActionStateMessage
{
/// <summary>
/// Критичность ошибки:
/// при некритичных ошибках продолжение выполнения операции возможно,
/// а при критичных -- нет
/// </summary>
public bool IsCritical { get; init; }
}

View File

@ -0,0 +1,12 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс для информации по статусу
/// </summary>
public interface IActionInfo : IActionStateMessage
{
/// <summary>
/// Статусная информация (например, начало работы)
/// </summary>
public bool IsStatusInfo { get; init; }
}

View File

@ -0,0 +1,24 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс сообщения состояния
/// </summary>
public interface IActionStateMessage
{
/// <summary>
/// Объект сообщения
/// </summary>
public object Object { get; set; }
/// <summary>
/// Текст сообщения
/// </summary>
public string Message { get; set; }
/// <summary>
/// Функция вывода сообщения
/// </summary>
/// <param name="format">Строка-форматирование (например, «[{0}] - {1}»)</param>
/// <returns>Отформатированную строка</returns>
public string PrintMessage (string format) => string.Format (format, Object, Message);
}

View File

@ -0,0 +1,12 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс предупреждения
/// </summary>
public interface IActionWarning : IActionStateMessage
{
/// <summary>
/// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию.
/// </summary>
public bool IsInformWarning { get; init; }
}

View File

@ -0,0 +1,37 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс шифрования
/// </summary>
public interface IEncryptor
{
/// <summary>
/// Метод для шифрования строки <paramref name="value"/>
/// </summary>
/// <param name="value">Строка, которая должна быть зашифрована</param>
/// <param name="salt">Ключ шифрования</param>
/// <returns>Этот метод возвращает зашифрованную строку <paramref name="value"/></returns>
string Encrypt (string value, string salt);
/// <summary>
/// Метод для дешифрования строки <paramref name="encryptedValue"/>
/// </summary>
/// <param name="encryptedValue">Строка, которая должна быть дешифрована</param>
/// <param name="salt">Ключ шифрования</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="encryptedValue"/></returns>
string Decrypt (string encryptedValue, string salt);
/// <summary>
/// Декодирует зашифрованную строку в HTML-пригодный формат
/// </summary>
/// <param name="text">Зашифрованная строка</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="text"/></returns>
string Base64UrlEncode (string text);
/// <summary>
/// Раскодирует из декодированной строки в HTML-пригодный формат
/// </summary>
/// <param name="text">Декодированная строка</param>
/// <returns>Этот метод возвращает шифрованную строку <paramref name="text"/></returns>
string Base64UrlDecode (string text);
}

View File

@ -0,0 +1,22 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс конвертера величин для отображения (улучшенный аналог IValueFormatter)
/// </summary>
public interface IValueConverter
{
/// <summary>
/// Массив имён размерностей
/// </summary>
public string[] ValueNames { get; init; }
/// <summary>
/// Делитель
/// </summary>
public long Divider { get; init; }
/// <summary>
/// Знаков после запятой (0, 1, 2)
/// </summary>
public byte DecimalPlaces { get; init; }
}

View File

@ -0,0 +1,74 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Форматирует размерности в понятную строку
/// </summary>
public interface IValueFormatter
{
#region Определения интерфейса
/// <summary>
/// Имена размерностей
/// </summary>
public string[] ValueNames { get; set; }
/// <summary>
/// Знаков после запятой
/// </summary>
public byte DecimalPlaces { get; set; }
/// <summary>
/// Максимальные размеры (массив ulong[4])
/// </summary>
public long[] MaxSizes { get; set; }
#endregion
#region Методы интерфейса
/// <summary>
/// Форматирование размерности
/// </summary>
/// <param name="value">Размерность, требующая форматирования</param>
/// <returns>Форматированная размерность (например, 20 Мб)</returns>
public string Format(long value)
{
//Левая граница
long leftnum;
//Правая граница
long rightnum;
for (int i = 0; i <= MaxSizes.Length; i++)
{
leftnum = i == 0 ? 0 : MaxSizes[i - 1];
rightnum = i == MaxSizes.Length ? long.MaxValue : MaxSizes[i];
if (value >= leftnum && value < rightnum)
return $"{FormatValue(value, leftnum)} {ValueNames[i]}";
}
return value.ToString();
}
/// <summary>
/// Деление числа на число с DecimalPlaces знаками после запятой
/// </summary>
/// <param name="dividend">Делимое число</param>
/// <param name="divider">Число-делитель</param>
/// <returns>Частное (с DecimalPlaces знаками после запятой)</returns>
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
}

View File

@ -1,48 +0,0 @@
using System.Collections.Generic;
namespace anbs_cp
{
/// <summary>
/// Класс, добавляющий реализацию некоторых методов Delphi, которые упрощают работу в C#.
/// </summary>
public static class LikeDelphi
{
/// <summary>
/// Аналог функции IncludeTrailingBackslash
/// </summary>
/// <param name="path">Путь, к которому нужно добавить slash</param>
/// <returns>Путь со slash в конце</returns>
public static string IncludeTrailingBackslash(string path)
{
string result = path;
int Index = path.Length - 1;
if (path[Index] != '\\')
{
result = $"{path}\\";
}
return result;
}
/// <summary>
/// Парсер строки в множество строк
/// </summary>
/// <param name="astring">Строка, которую нужно разбить</param>
/// <param name="delim">Символ-делитель строки</param>
/// <returns>Массив строк</returns>
public static List<string> ParseString(string astring, char delim)
{
int from = -1;
int to;
List<string> 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;
}
}
}

View File

@ -0,0 +1,51 @@
namespace anbs_cp.Structs;
/// <summary>
/// Пара ключ-значение
/// </summary>
/// <typeparam name="TK">Тип ключа</typeparam>
/// <typeparam name="TV">Тип значения</typeparam>
public struct KeyValue<TK, TV>
{
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public KeyValue ()
{
Key = default;
Value = default;
}
/// <summary>
/// Конструктор со значениями
/// </summary>
/// <param name="key">Ключ</param>
/// <param name="value">Значение</param>
public KeyValue (TK key, TV value)
{
Key = key;
Value = value;
}
#endregion
#region Свойства
/// <summary>
/// Ключ
/// </summary>
public TK? Key { get; set; }
/// <summary>
/// Значение
/// </summary>
public TV? Value { get; set; }
#endregion
#region Методы
/// <summary>
/// Получает ключ-значение по умолчанию
/// </summary>
/// <returns>Ключ-значение по умолчанию</returns>
public static KeyValue<TK, TV> GetDefault() => new();
#endregion
}

View File

@ -0,0 +1,61 @@
namespace anbs_cp.Structs;
/// <summary>
/// Двумерный размер
/// </summary>
public struct TwoDimSize
{
#region Приватные поля
/// <summary>
/// Длина (приватное)
/// </summary>
private int _pWidth;
/// <summary>
/// Высота (приватное)
/// </summary>
private int _pHeight;
#endregion
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public TwoDimSize ()
{
Width = 0;
Height = 0;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="width">Длина</param>
/// <param name="height">Высота</param>
public TwoDimSize (int width, int height)
{
Width = width;
Height = height;
}
#endregion
#region Свойства
/// <summary>
/// Длина
/// </summary>
public int Width
{
readonly get => _pWidth;
set => _pWidth = value < 0 ? 0 : value;
}
/// <summary>
/// Высота
/// </summary>
public int Height
{
readonly get => _pHeight;
set => _pHeight = value < 0 ? 0 : value;
}
#endregion
}

View File

@ -1,114 +0,0 @@
namespace anbs_cp
{
/// <summary>
/// Конвертер типов на манер Delphi
/// </summary>
public static class TypeConverter
{
#region Конвертация числа в строку
/// <summary>
/// Преобразование int в string
/// </summary>
/// <param name="AInt">Число</param>
/// <returns>Строка</returns>
public static string IntToStr(int AInt) => AInt.ToString();
/// <summary>
/// Преобразование uint в string
/// </summary>
/// <param name="AInt">Число</param>
/// <returns>Строка</returns>
public static string IntToStr(uint AInt) => AInt.ToString();
/// <summary>
/// Преобразование long в string
/// </summary>
/// <param name="AInt">Число</param>
/// <returns>Строка</returns>
public static string IntToStr(long AInt) => AInt.ToString();
/// <summary>
/// Преобразование ulong в string
/// </summary>
/// <param name="AInt">Число</param>
/// <returns>Строка</returns>
public static string IntToStr(ulong AInt) => AInt.ToString();
/// <summary>
/// Преобразование byte в string
/// </summary>
/// <param name="AInt">Число</param>
/// <returns>Строка</returns>
public static string IntToStr(byte AInt) => AInt.ToString();
#endregion
#region Конвертация строки в число
/// <summary>
/// Преобразование строки в число
/// </summary>
/// <param name="AStr">Строка</param>
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
/// <returns>Число</returns>
public static int StrToInt(string AStr, int ADefault = 0)
{
if (!int.TryParse(AStr, out int result))
{
result = ADefault;
}
return result;
}
/// <summary>
/// Преобразование строки в число
/// </summary>
/// <param name="AStr">Строка</param>
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
/// <returns>Число</returns>
public static uint StrToUInt(string AStr, uint ADefault = 0)
{
if (!uint.TryParse(AStr, out uint result))
{
result = ADefault;
}
return result;
}
/// <summary>
/// Преобразование строки в число
/// </summary>
/// <param name="AStr">Строка</param>
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
/// <returns>Число</returns>
public static long StrToInt64(string AStr, long ADefault = 0)
{
if (!long.TryParse(AStr, out long result))
{
result = ADefault;
}
return result;
}
/// <summary>
/// Преобразование строки в число
/// </summary>
/// <param name="AStr">Строка</param>
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
/// <returns>Число</returns>
public static ulong StrToUInt64(string AStr, ulong ADefault = 0)
{
if (!ulong.TryParse(AStr, out ulong result))
{
result = ADefault;
}
return result;
}
/// <summary>
/// Преобразование строки в число
/// </summary>
/// <param name="AStr">Строка</param>
/// <param name="ADefault">Значение по умолчанию (по умолчанию, 0)</param>
/// <returns>Число</returns>
public static byte StrToByte(string AStr, byte ADefault = 0)
{
if (!byte.TryParse(AStr, out byte result))
{
result = ADefault;
}
return result;
}
#endregion
}
}

View File

@ -1,36 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.20211111.0</Version>
<Authors>Alexander Babaev</Authors>
<Product>ANB Software Components Pack</Product>
<Description>Library of some useful functions in C# language.</Description>
<Copyright>Alexander Babaev</Copyright>
<TargetFramework>net8.0</TargetFramework>
<Version>2023.1114.0</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software</Product>
<Description>Библиотека полезных методов языка C#</Description>
<Copyright>Александр Бабаев</Copyright>
<AssemblyName>anbs_cp</AssemblyName>
<RootNamespace>anbs_cp</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<SignAssembly>False</SignAssembly>
<PackageProjectUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</PackageProjectUrl>
<RepositoryUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</RepositoryUrl>
<AssemblyVersion>1.2021.1111</AssemblyVersion>
<FileVersion>1.2021.1111</FileVersion>
<SignAssembly>True</SignAssembly>
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
<AssemblyVersion></AssemblyVersion>
<FileVersion></FileVersion>
<PackageId>ANBSoftware.ComponentsPack</PackageId>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<AnalysisLevel>6.0</AnalysisLevel>
<RepositoryType>git</RepositoryType>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<WarningLevel>2</WarningLevel>
<WarningLevel>7</WarningLevel>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<WarningLevel>2</WarningLevel>
<WarningLevel>7</WarningLevel>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop" Version="17.0.31902.203" />
<PackageReference Include="MimeTypes" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="Enums\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>

View File

@ -0,0 +1,369 @@
using anbs_cp.Database.Interfaces;
using Dapper;
using MySqlConnector;
namespace anbs_cp.Database.Classes;
public class MySqlEngine: IDbEngine
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="connectionString">Строка подключения базы данных</param>
public MySqlEngine (string connectionString) => ConnectionString = connectionString;
/// <summary>
/// Строка подключения базы данных
/// </summary>
public string ConnectionString { get; set; }
#region Базовые операции
/// <summary>
/// Выполняем команду
/// </summary>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Количество затронутых строк</returns>
public async Task<int> ExecuteAsync (string sql, object? values = null)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
// Открываем соединение
await connection.OpenAsync();
// Выполняем команду и выводим результат
return await connection.ExecuteAsync(sql, values);
}
/// <summary>
/// Выполняем команду
/// </summary>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Количество затронутых строк</returns>
public int Execute (string sql, object? values = null) => ExecuteAsync(sql, values).GetAwaiter().GetResult();
/// <summary>
/// Запрос
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
public async Task<IEnumerable<T>> QueryAsync<T> (string sql, object? values = null)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
// Открываем соединение
await connection.OpenAsync();
// Выполняем запрос и выводим результат
return await connection.QueryAsync<T>(sql, values);
}
/// <summary>
/// Запрос
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
public IEnumerable<T> Query<T> (string sql, object? values = null) => QueryAsync<T>(sql, values).GetAwaiter().GetResult();
/// <summary>
/// Запрос строки
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
public async Task<T?> QueryRowAsync<T> (string sql, object? values = null)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
// Открываем соединение
await connection.OpenAsync();
// Выполняем запрос и выводим результат
return await connection.QuerySingleOrDefaultAsync<T>(sql, values);
}
/// <summary>
/// Запрос строки
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
public T? QueryRow<T> (string sql, object? values = null) => QueryRowAsync<T>(sql, values).GetAwaiter().GetResult();
#endregion
#region Получение данных
/// <summary>
/// Получает массив данных (SELECT * FROM...)
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Массив результата запроса</returns>
public async Task<IEnumerable<T>> GetResultsAsync<T> (string sql, object? values = null) => await QueryAsync<T>(sql, values);
/// <summary>
/// Получает массив данных (SELECT * FROM...)
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Массив результата запроса</returns>
public IEnumerable<T> GetResults<T> (string sql, object? values = null) => GetResultsAsync<T>(sql, values).GetAwaiter().GetResult();
/// <summary>
/// Получает строку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Строки данных или null</returns>
public async Task<T?> GetRowAsync<T> (string sql, object? values = null)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
// Открываем соединение
await connection.OpenAsync();
// Выполняем запрос и выводим результат
return await connection.QuerySingleOrDefaultAsync<T>(sql, values);
}
/// <summary>
/// Получает строку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Строки данных или null</returns>
public T? GetRow<T> (string sql, object? values = null) => GetRowAsync<T>(sql, values).GetAwaiter().GetResult();
/// <summary>
/// Получает колонку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Колонка данных или null</returns>
public async Task<IEnumerable<T>> GetColAsync<T> (string sql, object? values = null)
where T : IComparable, IConvertible, IEquatable<T> => await QueryAsync<T>(sql, values);
/// <summary>
/// Получает колонку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Колонка данных или null</returns>
public IEnumerable<T> GetCol<T> (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable<T> =>
GetColAsync<T>(sql, values).GetAwaiter().GetResult();
/// <summary>
/// Получение значение единичного поля
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Поле или null</returns>
public async Task<T?> GetVarAsync<T> (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable<T>
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
// Открываем соединение
await connection.OpenAsync();
// Выполняем запрос и выводим результат
return await connection.QuerySingleOrDefaultAsync<T>(sql, values);
}
/// <summary>
/// Получение значение единичного поля
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Поле или null</returns>
public T? GetVar<T> (string sql, object? values = null) where T : IComparable, IConvertible, IEquatable<T> =>
GetVarAsync<T>(sql, values).GetAwaiter().GetResult();
#endregion
#region CRUD данные
/// <summary>
/// Вставляет данные в таблицу
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <returns>Результат выполнения</returns>
public async Task<bool> InsertAsync<T> (T data, string tableName) where T : class
{
// Получение список имён свойств в data
List<string> propertyNamesList = (from dataProperty in data.GetType().GetProperties() select dataProperty.Name).ToList();
// Получаем список имён в data, обрамленные @
List<string> 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 = $"""
INSERT
INTO {tableName} ({propertyNames})
VALUES ({propertyValues})
""";
// Выполняю запрос
return await connection.ExecuteAsync(sql, data) > 0;
}
/// <summary>
/// Вставляет данные в таблицу
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <returns>Результат выполнения</returns>
public bool Insert<T> (T data, string tableName) where T : class => InsertAsync(data, tableName).GetAwaiter().GetResult();
/// <summary>
/// Обновляет строку в таблице
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
public async Task<bool> UpdateAsync<T> (T data, string tableName, string whereConditionColumn) where T : class
{
// Получение список имён свойств в data
List<string> propertyNamesList = (from dataProperty in data.GetType().GetProperties()
where dataProperty.Name != whereConditionColumn
select dataProperty.Name).ToList();
// Получаем список имён в data, обрамленные @
List<string> 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;
}
/// <summary>
/// Обновляет строку в таблице
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
public bool Update<T> (T data, string tableName, string whereConditionColumn) where T : class =>
UpdateAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult();
/// <summary>
/// Удаляет строки
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
public async Task<bool> DeleteAsync<T> (T data, string tableName, string whereConditionColumn) where T : class
{
// Создаю соединение
await using MySqlConnection connection = new(ConnectionString);
// Создаю запрос
string sql = $"""
DELETE FROM
{tableName}
WHERE
{whereConditionColumn}=@{whereConditionColumn}
""";
// Выполняю запрос
return await connection.ExecuteAsync(sql, data) > 0;
}
/// <summary>
/// Удаляет строки
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
public bool Delete<T> (T data, string tableName, string whereConditionColumn) where T : class =>
DeleteAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult();
/// <summary>
/// Удаляет строку
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
public async Task<bool> DeleteRowAsync<T> (T data, string tableName, string whereConditionColumn) where T : class
{
// Создаю соединение
await using MySqlConnection connection = new(ConnectionString);
// Создаю запрос
string sql = $"""
DELETE FROM
{tableName}
WHERE
{whereConditionColumn}=@{whereConditionColumn}
LIMIT 1
""";
// Выполняю запрос
return await connection.ExecuteAsync(sql, data) > 0;
}
/// <summary>
/// Удаляет строку
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
public bool DeleteRow<T> (T data, string tableName, string whereConditionColumn) where T : class =>
DeleteRowAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult();
#endregion
}

View File

@ -0,0 +1,221 @@
using System.Transactions;
namespace anbs_cp.Database.Interfaces;
/// <summary>
/// Интерфейс для работы с базой данных
/// </summary>
public interface IDbEngine
{
/// <summary>
/// Строка подключения
/// </summary>
string ConnectionString { get; set; }
#region Базовые операции
/// <summary>
/// Выполняем команду
/// </summary>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Количество затронутых строк</returns>
Task<int> ExecuteAsync (string sql, object? values = null);
/// <summary>
/// Выполняем команду
/// </summary>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Количество затронутых строк</returns>
int Execute (string sql, object? values = null);
/// <summary>
/// Запрос
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
Task<IEnumerable<T>> QueryAsync<T> (string sql, object? values = null);
/// <summary>
/// Запрос
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
IEnumerable<T> Query<T> (string sql, object? values = null);
/// <summary>
/// Запрос строки
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
Task<T?> QueryRowAsync<T> (string sql, object? values = null);
/// <summary>
/// Запрос строки
/// </summary>
/// <typeparam name="T">Тип передаваемого значения</typeparam>
/// <param name="sql">Запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Возвращает массив типа <see cref="T"/> или значение по умолчанию</returns>
T? QueryRow<T> (string sql, object? values = null);
#endregion
#region Получение данных
/// <summary>
/// Получает массив данных (SELECT * FROM...)
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Массив результата запроса</returns>
Task<IEnumerable<T>> GetResultsAsync<T> (string sql, object? values = null);
/// <summary>
/// Получает массив данных (SELECT * FROM...)
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Массив результата запроса</returns>
IEnumerable<T> GetResults<T> (string sql, object? values = null);
/// <summary>
/// Получает строку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Строки данных или null</returns>
Task<T?> GetRowAsync<T> (string sql, object? values = null);
/// <summary>
/// Получает строку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Строки данных или null</returns>
T? GetRow<T> (string sql, object? values = null);
/// <summary>
/// Получает колонку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Колонка данных или null</returns>
Task<IEnumerable<T>> GetColAsync<T> (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable<T>;
/// <summary>
/// Получает колонку в массиве данных
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Колонка данных или null</returns>
IEnumerable<T> GetCol<T> (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable<T>;
/// <summary>
/// Получение значение единичного поля
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Поле или null</returns>
Task<T?> GetVarAsync<T> (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable<T>;
/// <summary>
/// Получение значение единичного поля
/// </summary>
/// <typeparam name="T">Тип получаемых данных</typeparam>
/// <param name="sql">SQL-запрос</param>
/// <param name="values">Данные запроса</param>
/// <returns>Поле или null</returns>
T? GetVar<T> (string sql, object? values = null) where T: IComparable, IConvertible, IEquatable<T>;
#endregion
#region CRUD данные
/// <summary>
/// Вставляет данные в таблицу
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <returns>Результат выполнения</returns>
Task<bool> InsertAsync<T> (T data, string tableName) where T: class;
/// <summary>
/// Вставляет данные в таблицу
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <returns>Результат выполнения</returns>
bool Insert<T> (T data, string tableName) where T: class;
/// <summary>
/// Обновляет строку в таблице
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
Task<bool> UpdateAsync<T> (T data, string tableName, string whereConditionColumn) where T: class;
/// <summary>
/// Обновляет строку в таблице
/// </summary>
/// <typeparam name="T">Класс данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
bool Update<T> (T data, string tableName, string whereConditionColumn) where T: class;
/// <summary>
/// Удаляет строки
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
Task<bool> DeleteAsync<T> (T data, string tableName, string whereConditionColumn) where T: class;
/// <summary>
/// Удаляет строки
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
bool Delete<T> (T data, string tableName, string whereConditionColumn) where T: class;
/// <summary>
/// Удаляет строку
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
Task<bool> DeleteRowAsync <T> (T data, string tableName, string whereConditionColumn) where T: class;
/// <summary>
/// Удаляет строку
/// </summary>
/// <param name="data">Данные</param>
/// <param name="tableName">Имя таблицы</param>
/// <param name="whereConditionColumn">Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data</param>
/// <returns>Результат выполнения</returns>
bool DeleteRow <T> (T data, string tableName, string whereConditionColumn) where T: class;
#endregion
}

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>anbs_cp_db</AssemblyName>
<RootNamespace>anbs_cp.Database</RootNamespace>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ANBSoftware.ComponentsPack.Database</PackageId>
<Version>2023.11.14.0</Version>
<Company>Александр Бабаев</Company>
<Product>Набор компонентов ANB Software для работы с БД</Product>
<Description>Библиотека полезных методов языка C# для работы с базами данных</Description>
<Copyright>Александр Бабаев</Copyright>
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.21" />
<PackageReference Include="MySqlConnector" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>

View File

@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Http;
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Класс -- расширение для класса File
/// </summary>
public class NetFileExtension
{
/// <summary>
/// Получает MIME-тип файла
/// </summary>
/// <param name="file">Загружаемый файл</param>
/// <returns>MIME-тип файла</returns>
public static string MIMEType (IFormFile file) =>
file.ContentType;
}

View File

@ -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
{
/// <summary>
/// Получение md5-хэша загружаемого файла.
/// Взято с https://stackoverflow.com/a/67081012/16469671
/// </summary>
/// <param name="file">Загружаемый файл</param>
/// <returns>Массив хэша</returns>
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;
}
}

View File

@ -0,0 +1,35 @@
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Расширение конвертера типов на манер Delphi
/// </summary>
public static class NetTypeConverter
{
#region Конвернтация IHtmlContent
/// <summary>
/// Преобразует тип <see cref="IHtmlContent"/> в строку <see cref="string"/>.
/// </summary>
/// <param name="content">Значение, которое нужно преобразовать.</param>
/// <returns><see cref="string"/></returns>
public static string HtmlContentToString(IHtmlContent content)
{
//Создаём writer
using StringWriter writer = new();
//Конвертируем IHtmlContent в string
content.WriteTo(writer, HtmlEncoder.Default);
//Возвращаем результат
return writer.ToString();
}
/// <summary>
/// Преобразует строку <see cref="string"/> в тип <see cref="IHtmlContent"/>.
/// </summary>
/// <param name="content">Значение, которое нужно преобразовать.</param>
/// <returns><see cref="IHtmlContent"/></returns>
public static IHtmlContent StringToHtmlContent(string content) => new HtmlContentBuilder().AppendHtml(content);
#endregion
}

View File

@ -0,0 +1,56 @@
using System.Text;
using anbs_cp.Interfaces;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Класс шифрования пароля
/// </summary>
public sealed class PasswordEncrypt: IEncryptor
{
/// <summary>
/// Шифрование пароля
/// </summary>
/// <param name="password">Пароль</param>
/// <param name="salt">Хэш-код пароля</param>
/// <returns>Зашифрованный пароль</returns>
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);
}
/// <summary>
/// Этот метод не требует реализации в этом классе!
/// </summary>
/// <param name="encryptedValue">НЕ РАБОТАЕТ</param>
/// <param name="salt">НЕ РАБОТАЕТ</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Decrypt (string encryptedValue, string salt) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
/// <summary>
/// Этот метод не требует реализации в этом классе!
/// </summary>
/// <param name="text">НЕ РАБОТАЕТ</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Base64UrlEncode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
/// <summary>
/// Этот метод не требует реализации в этом классе!
/// </summary>
/// <param name="text">НЕ РАБОТАЕТ</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Base64UrlDecode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
}

View File

@ -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;
/// <summary>
/// Расширение URLHelper
/// </summary>
public static class UrlHelperExtension
{
/// <summary>
/// Очищает URL, удаляя ненужные QueryString
/// </summary>
/// <param name="helper">
/// <see cref="IUrlHelper" />
/// </param>
/// <param name="context">
/// <see cref="HttpContext" />
/// </param>
/// <param name="url">Ссылка, которую нужно почистить</param>
/// <param name="clearQueryString">Массив ключей, которые нужно удалить</param>
/// <param name="getLocalURL">Возвращать только локальную ссылку</param>
/// <returns></returns>
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<string, StringValues> query = QueryHelpers.ParseQuery(uri.Query);
//Если он содержит параметр для очистки, то удаляю его
foreach (KeyValuePair<string, StringValues> queryItem in query.Where(queryItem =>
clearQueryString.Contains(queryItem.Key)))
query.Remove(queryItem.Key);
//Создаю список запроса, пригодный для QueryBuilder
List<KeyValuePair<string, string>> queryList = query.Select(static queryItem =>
new KeyValuePair<string, string>(queryItem.Key, queryItem.Value.ToString())).ToList();
//Запускаю построение новых параметров
QueryBuilder qBuilder = new(queryList);
//Создаю переменную-результат
string result = "";
//Если нужно получить полную ссылку
if (!getLocalURL)
result = baseUri;
//формирую переменную-результат
result = $"{result}/{localUri}{qBuilder.ToQueryString()}";
//Вывожу результат
return result;
}
/// <summary>
/// Получает локальный url-адрес
/// </summary>
/// <param name="helper"><see cref="IUrlHelper" /></param>
/// <param name="url">url-адрес</param>
/// <returns>Локальный url-адрес</returns>
public static string ToLocalURL (this IUrlHelper helper, string url)
{
//Создаю uri из url
Uri uri = new(url);
//Вывожу результат
return helper.IsLocalUrl(url) ? url : uri.PathAndQuery;
}
/// <summary>
/// Преобразует локальную ссылку в полную
/// </summary>
/// <param name="helper">
/// <see cref="IUrlHelper" />
/// </param>
/// <param name="context">
/// <see cref="HttpContext" />
/// </param>
/// <param name="url">Ссылка</param>
/// <returns>
/// <see cref="string" />
/// </returns>
public static string? LocalToFullURL (this IUrlHelper helper, HttpContext context, string? url) =>
helper.IsLocalUrl(url) ? $"{context.Request.Scheme}://{context.Request.Host}{url}" : url;
}

View File

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ANBSoftware.ComponentsPackForNet</PackageId>
<Version>2023.11.14.0</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software для ASP.NET Core</Product>
<Description>Библиотека полезных методов языка C# для ASP.NET Core</Description>
<Copyright>Александр Бабаев</Copyright>
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RootNamespace>anbs_cp.ForNet</RootNamespace>
<AssemblyName>anbs_cp_fn</AssemblyName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\anbs_cp\anbs_cp.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Extensions\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>

View File

@ -0,0 +1,59 @@
using anbs_cp.OsInfo.Enums;
using anbs_cp.OsInfo.Interfaces;
namespace anbs_cp.OsInfo.Classes;
/// <summary>
/// Информация о дисках
/// </summary>
public sealed class OsDriveInfo: IOsDriveInfo
{
/// <summary>
/// Конструктор
/// </summary>
public OsDriveInfo ()
{
Type = EDriveType.DtHardDisc;
Caption = null;
Description = null;
DeviceId = null;
Name = null;
Model = null;
TotalSize = 0;
}
/// <summary>
/// Тип диска
/// </summary>
public EDriveType Type { get; set; }
/// <summary>
/// Заголовок
/// </summary>
public string? Caption { get; set; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Идентификатор устройства
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Имя устройства
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Модель
/// </summary>
public string? Model { get; set; }
/// <summary>
/// Общий размер
/// </summary>
public ulong TotalSize { get; set; }
}

View File

@ -0,0 +1,402 @@
using System.Management;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using anbs_cp.Classes;
using anbs_cp.OsInfo.Enums;
using anbs_cp.OsInfo.Interfaces;
namespace anbs_cp.OsInfo.Classes;
/// <summary>
/// Информация о системе
/// </summary>
public static class OsInfo
{
/// <summary>
/// Конструктор
/// </summary>
static OsInfo ()
{
Windows = GetWindowsInfo();
Processors = GetProcessors();
RAM = GetRAMs();
Videos = GetVideoAdapterInfos();
Drives = GetDriveInfos();
Net = GetNet();
}
/// <summary>
/// Информация о Windows
/// </summary>
public static IOsWindowsInfo Windows { get; }
/// <summary>
/// Список с информацией о процессоре(-ах)
/// </summary>
public static List<IOsProcessorInfo> Processors { get; }
/// <summary>
/// Количество оперативной памяти в байтах
/// </summary>
public static ulong RAM { get; }
/// <summary>
/// Видеоадаптеры
/// </summary>
public static List<IOsVideoAdapterInfo> Videos { get; }
/// <summary>
/// Диски
/// </summary>
public static List<IOsDriveInfo> Drives { get; set; }
/// <summary>
/// Сеть
/// </summary>
public static List<IOsNetInfo> Net { get; set; }
#region Служебные методы
/// <summary>
/// Получает информацию о Windows
/// </summary>
/// <returns></returns>
private static IOsWindowsInfo GetWindowsInfo () =>
new OsWindowsInfo
{
Version = Environment.OSVersion.ToString(),
Is64 = Environment.Is64BitOperatingSystem,
PcName = Environment.MachineName,
WindowsFolder = Environment.SystemDirectory
};
/// <summary>
/// Получение процессоров
/// </summary>
/// <returns>Список информации о процессорах</returns>
private static List<IOsProcessorInfo> GetProcessors ()
{
try
{
//Создаю результирующий список
List<IOsProcessorInfo> processorsList = new();
//Создаю классы менеджмента
ManagementClass management = new("Win32_Processor");
ManagementObjectCollection collection = management.GetInstances();
//Получаю число процессоров
int processorsCount = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["ProcessorId"].Value.ToString()).Count();
//Перебираю массив данных
for (int ind = 0; ind < processorsCount; ind++)
{
//Создаю элемент информации о процессоре
OsProcessorInfo processor = new()
{
Caption = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind),
Description = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind),
DeviceId = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind),
Manufacturer = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind),
MaxClockSpeed = TypeConverter.StrToInt(collection.Cast<ManagementObject>()
.Select(static a =>
a.Properties["MaxClockSpeed"].Value.ToString())
.ElementAtOrDefault(ind) ??
"0"),
Name = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind),
NumberOfCores = TypeConverter.StrToInt(collection.Cast<ManagementObject>()
.Select(static a =>
a.Properties["NumberOfCores"].Value.ToString())
.ElementAtOrDefault(ind) ??
"0"),
NumberOfLogicalProcessors = TypeConverter.StrToInt(collection.Cast<ManagementObject>()
.Select(static a => a.Properties["NumberOfLogicalProcessors"].Value.ToString())
.ElementAtOrDefault(ind) ?? "0")
};
//Добавляю в список
processorsList.Add(processor);
}
//Возвращаю список
return processorsList;
}
catch (NullReferenceException)
{
return new();
}
}
/// <summary>
/// Получение общее количество оперативной памяти
/// </summary>
/// <returns>Список информации о количестве оперативной памяти</returns>
private static ulong GetRAMs ()
{
try
{
//Создаю классы менеджмента
ManagementClass management = new("Win32_ComputerSystem");
ManagementObjectCollection collection = management.GetInstances();
//Получаю результат
return TypeConverter.StrToUInt64(collection.Cast<ManagementObject>()
.Select(static a => a.Properties["TotalPhysicalMemory"].Value.ToString()).FirstOrDefault() ?? "0");
}
catch (NullReferenceException)
{
return 0;
}
}
/// <summary>
/// Получает список видеоадаптеров
/// </summary>
/// <returns>Список информации о видеоадаптерах</returns>
private static List<IOsVideoAdapterInfo> GetVideoAdapterInfos ()
{
try
{
//Создаю результирующий список
List<IOsVideoAdapterInfo> videosList = new();
//Создаю классы менеджмента
ManagementClass management = new("Win32_VideoController");
ManagementObjectCollection collection = management.GetInstances();
//Получаю число адаптеров
int count = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DeviceID"].Value.ToString()).Count();
//Перебираю массив данных
for (int ind = 0; ind < count; ind++)
{
//Создаю элемент информации об адаптере
OsVideoAdapterInfo adapter = new()
{
Caption = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind),
Description = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind),
DeviceId = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind),
AdapterRAM = TypeConverter.StrToInt(collection.Cast<ManagementObject>()
.Select(static a => a.Properties["AdapterRAM"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"),
DriverDate = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DriverDate"].Value.ToString()).ElementAtOrDefault(ind),
Name = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind),
CurrentResolution = (TypeConverter.StrToInt(collection.Cast<ManagementObject>()
.Select(static a => a.Properties["CurrentHorizontalResolution"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"),
TypeConverter.StrToInt(collection.Cast<ManagementObject>()
.Select(static a => a.Properties["CurrentVerticalResolution"].Value.ToString())
.ElementAtOrDefault(ind) ?? "0")),
SystemName = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["SystemName"].Value.ToString()).ElementAtOrDefault(ind),
DriverVersion = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DriverVersion"].Value.ToString()).ElementAtOrDefault(ind),
InstalledDisplayDrivers = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["InstalledDisplayDrivers"].Value.ToString()).ElementAtOrDefault(ind),
VideoProcessor = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["VideoProcessor"].Value.ToString()).ElementAtOrDefault(ind)
};
//Добавляю в список
videosList.Add(adapter);
}
//Возвращаю список
return videosList;
}
catch (NullReferenceException)
{
return new();
}
}
/// <summary>
/// Получает список дисков
/// </summary>
/// <returns>Список информации о дисках</returns>
private static List<IOsDriveInfo> GetDriveInfos ()
{
try
{
//Создаю результат
List<IOsDriveInfo> result = new();
//Добавление всех HDD/SSD дисков
result.AddRange(GetHDDs());
//Добавление всех CD/DVD/BD дисков
result.AddRange(GetCDRom());
//Вывожу список
return result;
}
catch (NullReferenceException)
{
return new();
}
}
/// <summary>
/// Получаю список HDD/SSD дисков
/// </summary>
/// <returns>Информация обо всех HDD/SSD дисках</returns>
private static List<IOsDriveInfo> GetHDDs ()
{
try
{
//Создаю результирующий список
List<IOsDriveInfo> driveList = new();
//Создаю классы менеджмента
ManagementClass management = new("Win32_DiskDrive");
ManagementObjectCollection collection = management.GetInstances();
//Получаю число адаптеров
int count = collection.Cast<ManagementObject>()
.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<ManagementObject>()
.Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind),
Description = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind),
DeviceId = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind),
Name = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind),
TotalSize = TypeConverter.StrToUInt64(collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Size"].Value.ToString()).ElementAtOrDefault(ind) ?? "0"),
Model = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Model"].Value.ToString()).ElementAtOrDefault(ind)
};
//Добавляю в список
driveList.Add(drive);
}
//Возвращаю список
return driveList;
}
catch (NullReferenceException)
{
return new();
}
}
/// <summary>
/// Получаю список CD/DVD/BD дисков
/// </summary>
/// <returns>Информация обо всех CD/DVD/BD дисках</returns>
private static List<IOsDriveInfo> GetCDRom ()
{
try
{
//Создаю результирующий список
List<IOsDriveInfo> driveList = new();
//Создаю классы менеджмента
ManagementClass management = new("Win32_CDROMDrive");
ManagementObjectCollection collection = management.GetInstances();
//Получаю число адаптеров
int count = collection.Cast<ManagementObject>()
.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<ManagementObject>()
.Select(static a => a.Properties["Caption"].Value.ToString()).ElementAtOrDefault(ind),
Description = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Description"].Value.ToString()).ElementAtOrDefault(ind),
DeviceId = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["DeviceID"].Value.ToString()).ElementAtOrDefault(ind),
Name = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Name"].Value.ToString()).ElementAtOrDefault(ind),
//Ставится 0, чтобы не проверять корректность загрузки и читаемость диска, а также избежать удлинения получения информации
TotalSize = 0,
Model = collection.Cast<ManagementObject>()
.Select(static a => a.Properties["Manufacturer"].Value.ToString()).ElementAtOrDefault(ind)
};
//Добавляю в список
driveList.Add(drive);
}
//Возвращаю список
return driveList;
}
catch (NullReferenceException)
{
return new();
}
}
/// <summary>
/// Получаю информацию о сети интернет
/// </summary>
/// <returns>Информация о сети интернет</returns>
private static List<IOsNetInfo> GetNet ()
{
try
{
//Создаю результирующий список
List<IOsNetInfo> 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;
}
catch (NullReferenceException)
{
return new();
}
}
#endregion
}

View File

@ -0,0 +1,39 @@
using anbs_cp.OsInfo.Interfaces;
namespace anbs_cp.OsInfo.Classes;
/// <summary>
/// Информация об интернет-соединении
/// </summary>
public sealed class OsNetInfo: IOsNetInfo
{
/// <summary>
/// Заголовок
/// </summary>
public string? Caption { get => Name; set => _ = value; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Идентификатор устройства
/// </summary>
public string? DeviceId { get => Name; set => _ = value; }
/// <summary>
/// Имя устройства
/// </summary>
public string? Name { get; set; }
/// <summary>
/// IP-адрес
/// </summary>
public string? IPAddress { get; set; }
/// <summary>
/// MAC-адрес
/// </summary>
public string? MacAddress { get; set; }
}

View File

@ -0,0 +1,64 @@
using anbs_cp.OsInfo.Interfaces;
namespace anbs_cp.OsInfo.Classes;
/// <summary>
/// Класс информации о процессоре
/// </summary>
public sealed class OsProcessorInfo: IOsProcessorInfo
{
/// <summary>
/// Конструктор
/// </summary>
public OsProcessorInfo ()
{
Caption = null;
Description = null;
DeviceId = null;
Manufacturer = null;
MaxClockSpeed = 0;
Name = null;
NumberOfCores = 0;
NumberOfLogicalProcessors = 0;
}
/// <summary>
/// Заголовок
/// </summary>
public string? Caption { get; set; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Идентификатор процессора в системе
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Производитель
/// </summary>
public string? Manufacturer { get; set; }
/// <summary>
/// Максимальная тактовая частота
/// </summary>
public int MaxClockSpeed { get; set; }
/// <summary>
/// Имя процессора
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Число ядер
/// </summary>
public int NumberOfCores { get; set; }
/// <summary>
/// Число потоков
/// </summary>
public int NumberOfLogicalProcessors { get; set; }
}

View File

@ -0,0 +1,82 @@
using anbs_cp.OsInfo.Interfaces;
namespace anbs_cp.OsInfo.Classes;
/// <summary>
/// Информация о видеокарте
/// </summary>
internal sealed class OsVideoAdapterInfo: IOsVideoAdapterInfo
{
/// <summary>
/// Конструктор
/// </summary>
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;
}
/// <summary>
/// Память
/// </summary>
public int AdapterRAM { get; set; }
/// <summary>
/// Заголовок
/// </summary>
public string? Caption { get; set; }
/// <summary>
/// Текущее разрешение
/// </summary>
public (int, int) CurrentResolution { get; set; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Идентификатор устройства
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Дата установки драйвера
/// </summary>
public string? DriverDate { get; set; }
/// <summary>
/// Версия драйвера
/// </summary>
public string? DriverVersion { get; set; }
/// <summary>
/// Название драйверов
/// </summary>
public string? InstalledDisplayDrivers { get; set; }
/// <summary>
/// Имя
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Имя в системе
/// </summary>
public string? SystemName { get; set; }
/// <summary>
/// Видео процессор
/// </summary>
public string? VideoProcessor { get; set; }
}

View File

@ -0,0 +1,62 @@
using anbs_cp.OsInfo.Interfaces;
namespace anbs_cp.OsInfo.Classes;
/// <summary>
/// Информация о Windows
/// </summary>
public sealed class OsWindowsInfo: IOsWindowsInfo
{
/// <summary>
/// Конструктор
///</summary>
public OsWindowsInfo ()
{
Version = null;
Is64 = true;
PcName = null;
WindowsFolder = null;
}
/// <summary>
/// Версия
/// </summary>
public string? Version { get; set; }
/// <summary>
/// 64-разрядная ОС
/// </summary>
public bool Is64 { get; set; }
/// <summary>
/// Имя компьютера
/// </summary>
public string? PcName { get; set; }
/// <summary>
/// Путь к папке Windows
/// </summary>
public string? WindowsFolder { get; set; }
#region Реализация интерфейса IBasicInfo
/// <summary>
/// Заголовок
/// </summary>
public string? Caption { get => Version; set => _ = value; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get => Version; set => _ = value; }
/// <summary>
/// Идентификатор
/// </summary>
public string? DeviceId { get => Version; set => _ = value; }
/// <summary>
/// Имя
/// </summary>
public string? Name { get => Version; set => _ = value; }
#endregion
}

View File

@ -0,0 +1,17 @@
namespace anbs_cp.OsInfo.Enums;
/// <summary>
/// Тип носителя
/// </summary>
public enum EDriveType
{
/// <summary>
/// HDD/SSD/M2
/// </summary>
DtHardDisc = 0,
/// <summary>
/// Диск CD/DVD/BD
/// </summary>
DtCDRom = 1
}

View File

@ -0,0 +1,27 @@
namespace anbs_cp.OsInfo.Interfaces;
/// <summary>
/// Базовые параметры устройства
/// </summary>
public interface IOsBasicInfo
{
/// <summary>
/// Заголовок
/// </summary>
public string? Caption { get; set; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get; set; }
/// <summary>
/// Идентификатор устройства
/// </summary>
public string? DeviceId { get; set; }
/// <summary>
/// Имя устройства
/// </summary>
public string? Name { get; set; }
}

View File

@ -0,0 +1,24 @@
using anbs_cp.OsInfo.Enums;
namespace anbs_cp.OsInfo.Interfaces;
/// <summary>
/// Информация о дисках
/// </summary>
public interface IOsDriveInfo: IOsBasicInfo
{
/// <summary>
/// Тип диска
/// </summary>
public EDriveType Type { get; set; }
/// <summary>
/// Модель
/// </summary>
public string? Model { get; set; }
/// <summary>
/// Общий размер
/// </summary>
public ulong TotalSize { get; set; }
}

View File

@ -0,0 +1,17 @@
namespace anbs_cp.OsInfo.Interfaces;
/// <summary>
/// Информация об интернет-соединении
/// </summary>
public interface IOsNetInfo: IOsBasicInfo
{
/// <summary>
/// IP-адрес
/// </summary>
public string? IPAddress { get; set; }
/// <summary>
/// MAC-адрес
/// </summary>
public string? MacAddress { get; set; }
}

View File

@ -0,0 +1,31 @@
namespace anbs_cp.OsInfo.Interfaces;
/// <summary>
/// Информация о процессоре
/// </summary>
public interface IOsProcessorInfo: IOsBasicInfo
{
/// <summary>
/// Заголовок
/// </summary>
/// <summary>
/// Производитель
/// </summary>
public string? Manufacturer { get; set; }
/// <summary>
/// Максимальная тактовая частота
/// </summary>
public int MaxClockSpeed { get; set; }
/// <summary>
/// Число ядер
/// </summary>
public int NumberOfCores { get; set; }
/// <summary>
/// Число потоков
/// </summary>
public int NumberOfLogicalProcessors { get; set; }
}

View File

@ -0,0 +1,42 @@
namespace anbs_cp.OsInfo.Interfaces;
/// <summary>
/// Информация о видеокарте
/// </summary>
public interface IOsVideoAdapterInfo: IOsBasicInfo
{
/// <summary>
/// Память
/// </summary>
public int AdapterRAM { get; set; }
/// <summary>
/// Текущее разрешение
/// </summary>
public (int, int) CurrentResolution { get; set; }
/// <summary>
/// Дата установки драйвера
/// </summary>
public string? DriverDate { get; set; }
/// <summary>
/// Версия драйвера
/// </summary>
public string? DriverVersion { get; set; }
/// <summary>
/// Название драйверов
/// </summary>
public string? InstalledDisplayDrivers { get; set; }
/// <summary>
/// Имя в системе
/// </summary>
public string? SystemName { get; set; }
/// <summary>
/// Видео процессор
/// </summary>
public string? VideoProcessor { get; set; }
}

View File

@ -0,0 +1,27 @@
namespace anbs_cp.OsInfo.Interfaces;
/// <summary>
/// Информация о Windows
/// </summary>
public interface IOsWindowsInfo: IOsBasicInfo
{
/// <summary>
/// Версия
/// </summary>
public string? Version { get; set; }
/// <summary>
/// 64-разрядная ОС
/// </summary>
public bool Is64 { get; set; }
/// <summary>
/// Имя компьютера
/// </summary>
public string? PcName { get; set; }
/// <summary>
/// Путь к папке Windows
/// </summary>
public string? WindowsFolder { get; set; }
}

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>anbs_cp.OsInfo</RootNamespace>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ANBSoftware.ComponentsPackOsInfo</PackageId>
<Version>2023.11.14</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software для получения информации о Windows</Product>
<Description>Библиотека полезных методов языка C# для получения информации об Windows</Description>
<Copyright>Александр Бабаев</Copyright>
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\anbs_cp\anbs_cp.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>

View File

@ -5,11 +5,17 @@ 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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpfn", "anbs_cpfn\anbs_cpfn.csproj", "{EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -23,6 +29,18 @@ 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
{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
{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

View File

@ -0,0 +1,30 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CD/@EntryIndexedValue">CD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HD/@EntryIndexedValue">HD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HDD/@EntryIndexedValue">HDD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RA/@EntryIndexedValue">RA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RAM/@EntryIndexedValue">RAM</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=abcdefghijkmnopqrstuvwxyz/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ABCDEFGHJKLMNOPQRSTUVWXYZ/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=anbs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Darkseal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Encryptor/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Glendower/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0412_0435_0440_043D_0451_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0412_0438_0434_0435_043E_043A_0430_0440_0442_0430/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_041F_0430_0440_0441_0435_0440/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_043E_0437_0434_0430_0451_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0432_0432_0435_0434_0451_043D/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0432_0438_0434_0435_043E_043A_0430_0440_0442_0435/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0448_0438_0444_0440_043E_0432_0430_043D_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0448_0438_0444_0440_043E_0432_0447_0438_043A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0438_043C_0451_043D/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043A_0440_0438_043F_0442_043E_0433_0440_0430_0444/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_0443_0442_0451_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0447_0451_0442/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0447_0451_0442_0447_0438_043A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0445_044D_0448_0430/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0445_044D_0448_0435_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0445_044D_0448_0435_0440/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -1,39 +1,40 @@
namespace demo
namespace demo;
sealed partial class CountValueTest
{
partial class CountValueTest
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
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
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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.calculateConvButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// InsertDataLabel
@ -41,16 +42,17 @@
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.Size = new System.Drawing.Size(341, 17);
this.InsertDataLabel.TabIndex = 0;
this.InsertDataLabel.Text = "&Insert any int value:";
this.InsertDataLabel.Text = "&Введите любое целочисленное значение:";
//
// 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.Size = new System.Drawing.Size(457, 24);
this.InsertDataBox.TabIndex = 1;
this.InsertDataBox.TextChanged += new System.EventHandler(this.InsertDataBox_TextChanged);
//
// ResultLabel
//
@ -59,19 +61,19 @@
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.Size = new System.Drawing.Size(478, 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.Text = "&Вставьте любое целочисленное значение в поле выше и нажмите кнопку \"Вычислить\", " +
"чтобы увидеть результат...";
this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// CalculateButton
//
this.CalculateButton.Location = new System.Drawing.Point(81, 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 = "Calc&ulate";
this.CalculateButton.Text = "В&ычислить обработчиком";
this.CalculateButton.UseVisualStyleBackColor = true;
this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click);
//
@ -80,9 +82,9 @@
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.Size = new System.Drawing.Size(188, 17);
this.SelectFormatterLabel.TabIndex = 4;
this.SelectFormatterLabel.Text = "&Select formatter:";
this.SelectFormatterLabel.Text = "В&ыберете обработчик:";
//
// SelectFormatterBox
//
@ -90,18 +92,29 @@
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.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(270, 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);
@ -115,20 +128,20 @@
this.Name = "CountValueTest";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Formatter Test Unit";
this.Text = "Тест модуля форматирования строки";
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;
private Button calculateConvButton;
}

View File

@ -1,42 +1,56 @@
using anbs_cp;
namespace demo
using anbs_cp.Classes;
using anbs_cp.Interfaces;
namespace demo;
public sealed 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)
private void CountValueTest_Load (object sender, EventArgs e)
{
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();
}
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
{
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;
}
0 => new CountConverter(CountConverter.DefaultNames).Convert(value),
1 => new FileSizeConverter(FileSizeConverter.DefaultNames).Convert(value),
_ => new CountConverter(CountConverter.DefaultNames).Convert(value)
};
}
}

125
demo/FileHashAndMimeTypeTest.Designer.cs generated Normal file
View File

@ -0,0 +1,125 @@
namespace demo;
sealed partial class FileHashAndMimeType
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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;
}

View File

@ -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 = new FileHash(fileNameEdt.Text).ToString();
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();
}
}

View File

@ -0,0 +1,63 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

102
demo/MainMenu.Designer.cs generated Normal file
View File

@ -0,0 +1,102 @@
namespace demo;
sealed partial class MainMenu
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
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
//
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 = "Новый тест модуля форматирования строки";
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 = "Новый тест модуля 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);
//
// 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);
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 = "Главное меню";
this.ResumeLayout(false);
}
#endregion
private Button CountValueTest;
private Button SimpleMapperTest;
private Button FileExtensionTest;
private Button OsInfoBtn;
}

32
demo/MainMenu.cs Normal file
View File

@ -0,0 +1,32 @@
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();
}
private void FileExtensionTest_Click (object sender, EventArgs e)
{
FileHashAndMimeType formTest = new();
formTest.ShowDialog();
}
private void OsInfoBtn_Click (object sender, EventArgs e)
{
OsInfoFrm formTest = new();
formTest.ShowDialog();
}
}

60
demo/MainMenu.resx Normal file
View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

65
demo/OsInfoFrm.Designer.cs generated Normal file
View File

@ -0,0 +1,65 @@
namespace demo;
sealed partial class OsInfoFrm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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;
}

28
demo/OsInfoFrm.cs Normal file
View File

@ -0,0 +1,28 @@
using anbs_cp.OsInfo.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);
}
}

60
demo/OsInfoFrm.resx Normal file
View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,15 +1,14 @@
namespace demo
namespace demo;
internal static class Program
{
internal static class Program
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main ()
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new CountValueTest());
}
ApplicationConfiguration.Initialize();
Application.Run(new MainMenu());
}
}

189
demo/SampleMapperTest.Designer.cs generated Normal file
View File

@ -0,0 +1,189 @@
namespace demo;
sealed partial class SampleMapperTest
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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 = "СВЯЗАТЬ";
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(819, 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(167, 21);
this.MapModeLabel.TabIndex = 11;
this.MapModeLabel.Text = "Режим связывания:";
//
// SampleMapperTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1151, 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";
((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;
}

71
demo/SampleMapperTest.cs Normal file
View File

@ -0,0 +1,71 @@
using anbs_cp.Classes;
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>());
string serialize2 = JsonConvert.SerializeObject(demo2);
// ReSharper disable once LocalizableElement
ResultArea.Text = $"Класс Demo2 до связывания:\r\n{serialize1}\r\nи после:\r\n{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; }
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -2,15 +2,31 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<Configurations>Release;Debug.CNF</Configurations>
<StartupObject>demo.Program</StartupObject>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.CNF|AnyCPU'">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\anbs_cposinfo\anbs_cposinfo.csproj" />
<ProjectReference Include="..\anbs_cp\anbs_cp.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="FileHashAndMimeTypeTest.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>