October 2025
|
|
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
|
9/20/24 07:52 am
Аццкий погодный информер 2
 Взял и сломался. Че-то я неделю где-то браться за этот говнокод не хотел, ну там реально говнокод, на сайт посмотрел краем глаза, подумал, что переделали сайт, и пиздец. Но друзья уговорили, бо пользуются аж с 2019-го года и им удобно. Хряпнул винища, полез разбираться, оказалось довольно смешно: 1. Если на сайте зайти на несуществующую страницу, то сайт, вместо того, чтобы нормально выдать код 404, который у меня спокойно обрабатывается обработчиком соединения, выдает код 200, но рисует страницу с надписью "Ошибка 404" 2. Сам себе злобный буратино. Искал начало таблицы с данными в своем недопарсере примерно так StartIdx = sData.IndexOf(StartText); И, конечно же, забыл проверку, что если ничего не найдено, тогда StartIdx == -1 , и надо выходить из функции и выдавать ошибку, а не пытаться Substring 'ом вырезать кусок, который не найден. Т.е. ошибка абсолютно детская, аж самому смешно. Итого, кому надо, могут взять здесьКому надо знают, где брать ключик и пароль от архива. Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2024/09/20/atstskij-pogodnyj-informer-2/
12/10/23 11:03 pm
C#: Учебное задание. Конвертер температур Кельвин - Цельсий - Фаренгейт
Скриншоты



Как синхронизировать три поля ввода, так чтоб в одном был ввод, а в других отображался результат1. Создаем три поля ввода типа InputDigitControl Поля надо назвать соответственно idcC , idcK и idcF для значений в цельсиях, кельвинах и фаренгейтах. 2. Создаем три переменных в коде формы, они будут флагами, показывющими в каком поле происходит ввод: bool enC = false; bool enK = false; bool enF = false; 3. Для всех полей прописываем общее событие типа Enter idc_Enter 4. В обработчике события захватываем текущий контрол в отдельную переменную: InputDigitControl idc = (InputDigitControl)sender; 5. Вытаскиваем последний символ в имени контрола: string fldID = idc.Name.Substring(3, 1); 6. Организуем switch , устанавливающий флаги switch (fldID)
{
case "C":
{
enC = true;
enK = false;
enF = false;
}; break;
case "K":
{
enC = false;
enK = true;
enF = false;
}; break;
case "F":
{
enC = false;
enK = false;
enF = true;
}; break;
}
Копия функции целиком на PasteBin7. Событие типа Changed тоже назначаем одно для всех контролов. 8 Внутри обработчика события анализируем флаги, производим расчеты и выводим результаты. Копия функции целиком на PasteBinВвод чиселС помощью моего компонента InputDigitControlФормулы для перевода температурC2K: K = C + 273.15 C2F: F = C * 9.0 / 5.0 + 32.0 K2C: C = K - 273.15 K2F: F = (K - 273.15) * 9.0 / 5.0 + 32.0 F2C: C = (F - 32.0) * 5.0 / 9.0 F2K: K = (F - 32.0) * 5.0 / 9.0 + 273.15 Скомпилированный файлНа GitHubИсходники проектаНа GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2023/12/10/c-uchebnoe-zadanie-konverter-temperatur-kelvin-tselsij-farengejt/
2/14/22 08:50 am
Перевод температурных шкал: Цельсий/Кельвин/Фаренгейт
И заодно функции на C# для знакомого школьника, шоб себя проверил.
Градусы Цельсия в градусы Кельвина
K = C + 273.15double C2K(double C)
{
return C + 273.15;
} Градусы Цельсия в градусы Фаренгейта
F = C * 9/5 + 32double C2F(double C)
{
return C * 9.0 / 5.0 + 32.0;
} Градусы Кельвина в градусы ЦельсияC = K - 273.15double K2C(double K)
{
return K - 273.15;
} Градусы Кельвина в градусы Фаренгейта F = (K - 273.15) * 9/5double K2F(double K)
{
return (K - 273.15) * 9.0 / 5.0 + 32.0;
} Градусы Фаренгейта в градусы Цельсия C = (F - 32) * 5/9double F2C(double F)
{
return (F - 32.0) * 5.0 / 9.0;
} Градусы Фаренгейта в градусы Кельвина K = (F - 32) * 5/9 +273.15double F2K(double F)
{
return (F - 32.0) * 5.0 / 9.0 + 273.15;
} Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2022/02/14/perevod-temperaturnyh-shkal-tselsij-kelvin-farengejt/
11/21/21 03:31 am
C#, вывод цветного текста на консоль и изменение цвета фона консоли.
Делается очень просто, цветом текста управляет свойство ForegroundColor объекта Console , а цветом фона - свойство BackgroundColor , которые принимают значения из перечисления ConsoleColor .
Например, если установить свойства таким образом:
Console.BackgroundColor = ConsoleColor.DarkGray; Console.ForegroundColor = ConsoleColor.Green;
то при выводе текста, например, командой:
Console.WriteLine("Demo Text");
мы получим зеленый текст:
Demo Text
на темно-сером фоне. Всего консоль поддерживает 16 цветов. Сброс цветовой схемы консолиДля возврата к цветовой схеме по умолчанию используется метод Console.ResetColor(); ПримерДемонстрационный пример на GitHub (выводит все цвета текста и фона)Скриншоты
Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2021/11/21/c-vyvod-tsvetnogo-teksta-na-konsol-i-izmenenie-tsveta-fona-konsoli/
11/8/21 03:12 am
C#, как сделать транслитерацию. Перевод русской строки в latinitsu.
ПреамбулаДумаю, что объяснять, что такое транслит, никому не нужно - это написание русских слов latinskimi bukvami, понадобилось сделать это на C#. Первая проблема, которая возникла, это то, что четкого стандарта транслитерации нет, к сожалению, кто в лес, кто по дрова. Я находил даже стандарты с мерзкой диакритикой, т.е. всякими кракозяблями над буквами. В общем, для своего примера я выбрал какой-то довольно пожилой телеграфный стандарт (нашел в печатной книжке), благо, если кому-то что-то не нравится, всегда можно подправить в исходнике, тут меня больше интересует сам пример. Русская буква | А | Б | В | Г | Д | Е | Ё | Ж | Латинская буква или буквосочетание | A | B | V | G | D | E | Yo | Zh | Русская буква | З | И | Й | К | Л | М | Н | О | Латинская буква или буквосочетание | Z | I | J | K | L | M | N | O | Русская буква | П | Р | С | Т | У | Ф | Х | Ц | Латинская буква или буквосочетание | P | R | S | T | U | F | Kh | Ts | Русская буква | Ч | Ш | Щ | Ъ | Ы | Ь | Э | Ю | Латинская буква или буквосочетание | Ch | Sh | Shch | '' | Y | ' | E | Ju | Русская буква | Я | | | | | | | | Латинская буква или буквосочетание | Ja | | | | | | | |
Вторая проблема - этот стандарт проблематично использовать для транслитерации URL или имен файлов, надо что-то делать с пробелом (который в именах файлов и URL смотрится, как говно), так что в другом варианте таблицы, для замены Ъ , Ь и пробела , был выбран знак подчеркивания ( _ ). Класс, для транслитерации символов и строкСоздаем новый класс Translit : public class Translit
{
}
В класс Translit добавляем словарь ( Dictionary ), который, в качестве ключа, будет использовать тип char (русскую букву), а в качестве значения string , содержащий ее латинский эквивалент. Думаю, ясно, почему string - некоторые русские буквы передаются латинскими буквосочетаниями: private Dictionary<char, string> TranslitDict = new Dictionary<char,string>(); Теперь надо создать две функции, которые будут заполнять словарь нужными значениями. Для общего случая: private void FormDictStandart()
{
TranslitDict.Clear();
//Заглавные буквы (общий случай)
TranslitDict.Add('А', "A");
//часть кода вырезана для экономии места
TranslitDict.Add('Ъ', "''");
TranslitDict.Add('Ы', "Y");
TranslitDict.Add('Ь', "'");
TranslitDict.Add('Э', "E");
TranslitDict.Add('Ю', "Ju");
TranslitDict.Add('Я', "Ja");
//строчные буквы (общий случай)
TranslitDict.Add('а', "a");
//часть кода вырезана для экономии места
TranslitDict.Add('ъ', "''");
TranslitDict.Add('ы', "y");
TranslitDict.Add('ь', "'");
TranslitDict.Add('э', "e");
TranslitDict.Add('ю', "ju");
TranslitDict.Add('я', "ja");
}
И для "режима совместимости": private void FormDictCompat()
{
TranslitDict.Clear();
//Заглавные буквы (режим совместимости)
TranslitDict.Add('А', "A");
//часть кода вырезана для экономии места
TranslitDict.Add('Ъ', "_");
TranslitDict.Add('Ы', "Y");
TranslitDict.Add('Ь', "_");
TranslitDict.Add('Э', "E");
TranslitDict.Add('Ю', "Ju");
TranslitDict.Add('Я', "Ja");
//строчные буквы (режим совместимости)
TranslitDict.Add('а', "a");
//часть кода вырезана для экономии места
TranslitDict.Add('ъ', "_");
TranslitDict.Add('ы', "y");
TranslitDict.Add('ь', "_");
TranslitDict.Add('э', "e");
TranslitDict.Add('ю', "ju");
TranslitDict.Add('я', "ja");
//пробел
TranslitDict.Add(' ', "_");
}
Теперь необходимо добавить в класс свойство, чтобы переключать режимы и переформировывать словарь. Классически, добавляем внутреннюю переменную compatibility типа bool , для хранения текущего значения свойства, и само свойство, при изменении которого, будет вызываться одна из вышеуказанных функций: private bool compatibility = false;
public bool Compatibility
{
get
{
return compatibility;
}
set
{
if (value)
{
FormDictCompat();
compatibility = true;
}
else
{
FormDictStandart();
compatibility = false;
}
}
}
Добавим простой конструктор класса: public Translit(bool Compat)
{
Compatibility = Compat;
} Транслитерация символаАлгоритм простой: надо проверить, содержится ли переданный в функцию символ в словаре, если да, то выдать соответствующее значение, если нет (т.е. передана латинская буква, знак препинания, цифра, или что-то иное), выдать этот же символ, преобразованный в строку: public string TranslitChar(char Rus)
{
if (TranslitDict.ContainsKey(Rus))
{
return TranslitDict[Rus];
}
else
{
return Rus.ToString();
}
} Проверка строки на наличие русских символов.Это я уже делал в маленьком примере ( копия), так что просто вставлю функции оттуда: //русские буквы
public static bool ContainsRus(string TestString)
{
return
Regex.IsMatch(TestString, @"[а-я]", RegexOptions.IgnoreCase);
}
//русские буквы и пробелы
public static bool ContainsRusOrSpace(string TestString)
{
return
Regex.IsMatch(TestString, @"[а-я]|\s", RegexOptions.IgnoreCase);
} Транслитерация строки1. Проверяем, содержит ли строка русские буквы или русские буквы и пробел, в зависимости от режима работы. Примечание: Сильно работу алгоритма это замедлить не должно, а вот ускорить, в случае какой-нибудь гигантской строки может, т.к. Regex , который используется в функции поверки, работает со строкой напрямую в памяти, средствами .NET. Если искомого нет - возвращаем оригинальную строку. 2. Проходимся по символам строки, транслитерируем их, возвращаем новую строку. Примечание: Для формирования новой строки лучше использовать StringBuilder вместо простой конкатенации, опять же, на случай, если строка может оказаться гигантской. См. подробности в статье на Хабреpublic string TranslitString(string Rus)
{
string sBuf = "";
StringBuilder sb = new StringBuilder();
if (compatibility)
{
if (!ContainsRusOrSpace(Rus)) return Rus;
}
else
{
if (!ContainsRus(Rus)) return Rus;
}
for (int i = 0; i < Rus.Length; i++)
{
if (TranslitDict.ContainsKey(Rus[i]))
{
sBuf = TranslitDict[Rus[i]];
}
else
{
sBuf = Rus[i].ToString();
}
sb.Append(sBuf);
}
return sb.ToString();
} ИсходникиКласс Translit на GitHubТестовый пример на GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2021/11/08/c-kak-sdelat-transliteratsiyu-perevod-russkoj-stroki-v-latinitsu/
11/7/21 11:55 pm
C#, как присвоить char значение null или его аналог.
Пост из серии спрашивали - отвечаем.
Значение null переменной типа char не присвоить никак, т.к. char относится к "простым" (в другой литературе "базовым") типам, которые не могут принимать значение null , и обязательно должны быть проинициализированы каким-то значением.
Но иногда надо объявить переменную типа char , с которой работать будем потом, например, в цикле. Как тогда быть? Можно инициализировать переменную символом с кодом 0 (0x00 ). Проще всего сделать это так:
char Chr = '\0';
Но можно и другими способами:
char Chr = char.MinValue; char Chr = (char)0;
Или даже с извращениями:
char Chr = "\0".ToCharArray()[0];
Или с извращениями, используя большой и тяжелый класс Convert , который лучше избегать, если он не очень нужен:
char Chr = Convert.ToChar(0);
Это репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2021/11/04/c-kak-prisvoit-char-znachenie-null-ili-ego-analog/
11/4/21 10:19 pm
C#, регулярное выражение для кириллицы.
Понадобилось тут узнать, содержит ли строка кириллицу. Решение через Regexp.
Кириллица[а-я] Кириллица или пробел[а-я]|\s Пример использованияПодключаем System.Text.RegularExpressions : using System.Text.RegularExpressions; Код: public static bool ContainsRus(string TestString)
{
return
Regex.IsMatch(TestString, @"[а-я]", RegexOptions.IgnoreCase);
}
public static bool ContainsRusOrSpace(string TestString)
{
return
Regex.IsMatch(TestString, @"[а-я]|\s", RegexOptions.IgnoreCase);
} Код на PasteBinЭто репост с сайта http://tolik-punkoff.com Оригинал: https://tolik-punkoff.com/2021/11/03/c-regulyarnoe-vyrazhenie-dlya-kirillitsy/
8/26/21 08:49 am
C#, как записать в STDERR сообщение об ошибке из консольного приложения.
Пост из серии спрашивали - отвечаем.
Итак, как в C# записать в STDERR . STDERR - это стандартный поток вывода для сообщений об ошибках, туда правильно организованные консольные приложения отправляют, собственно, сообщения об ошибках. Отправить в STDERR сообщение можно с помощью объекта Console.Error :
Console.Error.WriteLine("Write to STDERR.");
Код тестового приложенияstatic void Main(string[] args)
{
Console.WriteLine("Write to STDOUT.");
Console.Error.WriteLine("Write to STDERR.");
} ПроверкаДля проверки можно создать BAT-файл, вызывающий тестовое приложение и переопределяющий ( копия) вывод со стандартных потоков в файлы stderr_.txt и stdout_.txt . stderr и stdout являются зарезервированными системными именами, потому к именам файлов надо что-то добавить, знак _ в данном случае: Экран при выполнении тестового приложения: Z:\...\write2stderr\write2stderr\bin\Debug>write2stderr.exe Write to STDOUT. Write to STDERR.
При выполнении BAT-файла экран останется пустым, но в директории с файлом появятся два файла stderr_.txt и stdout_.txt со следующим содержимым. stderr_.txt:
Write to STDERR.
stdout_.txt:
Write to STDOUT. Пример на GitHubИсходникТестовый BAT-файлBAT-файл и скомпилированный EXEЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/08/26/c-kak-zapisat-v-stderr-soobshhenie-ob-oshibke-iz-konsolnogo-prilozheniya/
8/12/21 04:36 am
C#, ввод только цифр (чисел) в текстовое поле (TextBox).
Или окончательное решение цифирьного вопроса.
ПреамбулаРанее мы показывали простые способы, как обеспечить, чтобы в TextBox можно было ввести только цифры, т.е. целое число ( копия), а потом расширили пример до ввода в TextBox отрицательных ( копия) и дробных чисел ( копия) К сожалению, во всех этих примерах есть фатальный недостаток, текст в них все-таки вставить можно, если воспользоваться стандартным контекстным меню или комбинацией клавиш CTRL+V. На уровне простого взаимодействия с формой и контролами это перехватить невозможно, придется несколько извернуться, т.к. для перехвата события "вставить", придется перехватить сообщение Windows WM_PASTE , которое отправляется окну, или элементу управления окна при выполнении операции вставки. Для Windows, тащемта, однохуйственно, кому отправлять сообщение, форме (окну) или, например, текстовому полю. Т.к. для Windows, и текстовое поле на самом деле окно, просто дочернее, т.е. размещенное в другом окне (форме, в нашем случае). Но это я залез глубоко в бок. Нам нужно добраться до сообщений. А это можно сделать только изнутри самого контрола, но не из событий стандартных контролов, так что будем писать свой! Постановка задачи: необходимо создать свой контрол на основе текстового поля, который позволяет вводить только числа определенного типа - целые, целые отрицательные, отрицательные и положительные/отрицательные с дробной частью. НачалоПодключим необходимые пространства имен: using System.Windows.Forms; using System.ComponentModel; using System.Globalization; Начнем делать свой контрол, наследуемый от TextBox . Т.е. создадим новый класс: public class InputDigitControl:TextBox
{
//тут будет код :)
}
Для начала необходимо определить сообщения, которые будем перехватывать. Заводим в классе константы, определяющие коды нужных сообщений: const int WM_PASTE = 0x0302; //Сообщение "Вставка" (через к.м. и комбинацию клавиш) const int WM_CHAR = 0x0102; //Сообщение - нажатие алфавитно-цифровой клавиши
WM_CHAR будет отправлено форме системой только тогда, когда будет нажата алфавитно-цифровая клавиша, его будем перехватывать для отслеживания цифр (и прочего). Правда есть важный нюанс - WM_CHAR посылается и при нажатии комбинаций клавиш, например Ctrl+C и т.д., а также некоторых клавиш, которые не совсем подходят под понятие "алфавитно-цифровая", например BACKSPACE. Это надо будет учесть. Анализ ввода с клавиатуры будем производить в функции PreProcessMessage() , которую переопределим. PreProcessMessage() вызывается для предварительной обработки входящих сообщений, и нужно будет вернуть true , если это сообщение было обработано. Т.е. алгоритм действий таков - мы проверяем входящий символ на соответствие, и, либо пропускаем его дальше (возвращаем base.PreProcessMessage(ref msg) или false ), либо что-то делаем с содержимым текстового поля, если символ нужен (это понадобится при вводе отрицательных и дробей) и возвращаем true . Или ничего не делаем, если символ нежелательный, и просто вызываем true . В последнем случае, символ просто не попадет в поле ввода, т.к. контрол будет думать, что он уже обработан. Вставку, как я уже говорил выше, тоже нужно будет обработать, но, естественно, несколько иначе, это будем делать в переопределенной функции WndProc() ( Под катом еще много )ИсходникиКонтрол Тестовое приложениеРепозиторийЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/08/10/c-vvod-tolko-tsifr-chisel-v-tekstovoe-pole-textbox/
8/4/21 10:21 pm
C#, перехват вывода консольной программы в реальном времени из собственного приложения.
Преамбула.Итак, необходимо перехватить в реальном времени вывод консольной программы, которая запущена собственным приложением в фоновом режиме, например, как это делает GUI Openvpn для Windows.  На моделировании формы приложения особо останавливаться не буду, сделаем там элемент управления для вывода данных, организуем возможность выбора консольного приложения или BAT/CMD-файла, вывод которого будем перехватывать, кнопки для запуска, останова внешнего приложения, и кнопку для очистки лога. Замечу только, что для вывода перехваченных сообщений использовал немного модифицированный ListView ( копия)  Главное окно основной программыКонсольные тестовые приложения и командные файлы.Теперь надо подготовить несколько приложений для теста, одно будет консольное приложение на C#, которое генерирует случайное число, выводит его на консоль, ожидает 250 мс, и так повторяет в бесконечном цикле: Бинарник testapp.exe Исходный кодИ несколько вариантов BAT-файлов, реализующий тот же функционал, только время ожидания составляет 1 секунду. Правда с BAT-файлами есть пока нерешенный вопрос, некоторые, а именно в которых содержатся команды timeout и choice , при перехвате работают нестабильно. Вариант с choice зависает, начиная нагружать процессор, timeout - не выполняет свои функции, т.е. никакого таймаута, а потом зависает. Пока не понял, с чем это связано, но включил эти файлы отдельно, в комплект к тестовымЕще одна вводная1. В более современных версиях .NET можно использовать оператор async , но я решил обойтись без него, т.к. все возможности для перехвата данных с консоли были еще в .NET Framework 2.0. были, а слова такого не было. Как в анекдоте про Вовочку. 2. Запускать вызываемую консольную программу следует в отдельном потоке, с которым мы будем общаться как обычно - с помощью событий. Иначе чуда не получится - все будет висеть и не работать. Т.е алгоритм примерно понятен - надо запустить вызываемую консольную программу в отдельном потоке, а потом рулить основной программой, перехватывая данные при наличии события (т.е вывода запущенной программой новых данных). Основной класс. Создадим новый класс, например Runner : public class Runner Выше класса добавляем публичный делегат (он нам потом для события понадобится) public delegate void LogMessage(string Data); Подключаем нужные пространства имен: using System.Threading; using System.Diagnostics; Внутри класса заводим публичное свойство, определяющее путь к процессу: public string ProcessPath { get; set; } Заводим событие, которое будем генерировать при перехвате сообщения с консоли. public event LogMessage LogSend; И приватные переменные типов ProcessStartInfo , Process , для управления вызываемым процессом и типа Thread , для управления потоком, в котором будет запущен дочерний процесс. private ProcessStartInfo Info = null; private Process Proc = null; private Thread t = null; В конструкторе инициализируем переменную Info : public Runner(string processpath)
{
ProcessPath = processpath; //устанавливаем значение свойства ProcessPath
Info = new ProcessStartInfo(ProcessPath);
Info.RedirectStandardError = true; //перехват STDERR
Info.RedirectStandardOutput = true; //перехват STDOUT
Info.UseShellExecute = false; //иначе перехват работать не будет, см. MSDN
Info.CreateNoWindow = true; //не запускать процесс в новом окне
//это скроет консоль запускаемой программы
} Примечание: Присвоение свойству ShellExecute значения false позволяет перенаправлять потоки ввода, вывода и ошибки.Запуск процесса и перехват вывода консолиВ функции StartProcess() непосредственно выполняем запуск процесса и перехват. try
{
Proc = Process.Start(Info);
}
catch (Exception ex)
{
LogSend("INTERNAL ERROR: "+ex.Message);
return;
}
Запускаем процесс, если произошла ошибка, вызываем событие, ответственное за отправку сообщения и выходим. Для перехвата создаем цикл, в котором вызываем Process.StandardOutput.ReadLine() , пока результат не будет равен null . StandardOutput.ReadLine() будет ждать, пока программа не выведет на консоль строку, и тогда вернет ее, или же вернет null , когда программа завершится. string ConOut = "";
do
{
ConOut = Proc.StandardOutput.ReadLine();
if (ConOut != null)
{
LogSend(ConOut);
}
} while (ConOut != null);
Поскольку запуск этой функции вызовет "зависание", если запустить ее в основном потоке, то вызывать ее нужно в отдельном: public void Start()
{
t = new Thread(StartProcess);
t.Start();
}
Ну и функция для остановки вызванного процесса: public void Stop()
{
if (Proc != null)
{
Proc.Kill();
Proc = null;
}
if (t != null)
{
t.Abort();
t = null;
}
} Основная формаВ коде основной формы создаем объект Runner , регистрируем обработчик событий, запускаем перехват, не забывая про останов по нажатию нужной кнопки: Runner runner = null;
//...
private void btnStart_Click(object sender, EventArgs e)
{
runner = new Runner(txtPath.Text);
runner.LogSend += new LogMessage(runner_LogSend);
runner.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
if (runner != null)
{
runner.Stop();
}
}
В обработчике события отправляем данные в нужный элемент управления, не забывая про Invoke : void runner_LogSend(string Data)
{
Invoke((MethodInvoker)delegate
{
lvConsole.Items.Add(Data);
lvConsole.EnsureVisible(lvConsole.Items.Count - 1);
});
} Результат
Перехват вывода из BAT-файлаИсходникиНа GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/08/04/c-perehvat-vyvoda-konsolnoj-programmy-v-realnom-vremeni-iz-sobstvennogo-prilozheniya/
7/30/21 06:05 am
C#, тайм-аут (sleep) в консольной программе.
Проще всего это сделать с помощью остановки потока (thread):
System.Threading.Thread.Sleep(время_в_миллисекундах);
Например:
System.Threading.Thread.Sleep(250);
остановит выполнение основного потока программы (если поток один, соответственно, программу) на 250 миллисекунд:
static void Main(string[] args)
{
//какой-то код
System.Threading.Thread.Sleep(250);
//какой-то код
} Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/07/30/c-tajm-aut-sleep-v-konsolnoj-programme/
7/28/21 03:28 pm
Калькулятор пропорций
ОписаниеИзначально было написано как простое школьное задание, программа для подсчета пропорций с отображением схемы алгоритма подсчета пропорций. Внезапно, пригодилась и в реальной жизни для мелких химических и прочих расчетов с пропорциями. Несколько позже в программу была добавлена возможность подсчитать минимальный платеж с комиссией, например, вам необходимо внести 100$ с комиссией терминала на внесенную сумму 3%, алгоритм вычисляет минимальную сумму внесения с учетом суммы и комиссии на вносимую сумму. История версийv 0.0.1Простой калькулятор пропорций. Запускается без установки. v 0.0.2Добавлена функция вычисления суммы платежа с комиссией. v 0.0.3Усовершенствован ввод чисел. Используется контрол InputDigitControl Скриншоты



ИсходникиРепозиторий на GitHubСкачатьФайл в архиве (без установки).УстановщикЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/kalkulyator-proportsij/
7/28/21 05:50 am
C#, получение списка дисков, доступных в системе, и некоторых их параметров
Заметка от склероза.
Делается с помощью функции DriveInfo[] Drives = DriveInfo.GetDrives(); из пространства имен System.IO .
СсылкиDriveInfo.GetDrives() на MSDNКласс DriveInfo на MSDNПример кода на PasteBinЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/07/28/c-poluchenie-spiska-diskov-dostupnyh-v-sisteme-i-nekotoryh-ih-parametrov/
7/22/21 01:38 pm
Менеджер отложенной автозагрузки
Назначение программыПрограмма предназначена для автозагрузки программ, недоступных при фактическом старте системы, т.е. тех программ, которые могут находиться на съемных дисках, зашифрованных томах или сетевых дисках и сетевых папках. Описание программыПрограмма помещается на системный диск и должна находиться в автозагрузке системы. Пользователь, в настройках программы указывает пути к программам и документам, которые необходимо запустить, когда соответствующие носители с указанными программами будут доступны в ОС. Это могут быть внешние носители, такие как USB-диск, зашифрованный контейнер TrueCrypt/VeraCrypt и аналогичных систем, а также сетевые диски или сетевые папки. Программа StartupDelayed периодически проверяет доступность указанных пользователем программ, и при их наличии запускает их. По умолчанию программа работает в портативном режиме (т.е. все настройки и список запускаемых программ, хранятся в директории с программой). Запуск без параметров открывает окно настройки, где можно добавить нужные для запуска задачи, а также в отдельном меню установить время проверки доступности задач, прочие параметры и добавить сам менеджер в автозагрузку ОС. В качестве запускаемой задачи можно указать не исполняемый файл (exe, com, bat, cmd), но и документ, тогда он откроется в ассоциированной с ним программе. Для исполнения задач, необходимо запустить менеджер с параметром командной строки /run . Скриншоты Основное окно настроек
 Опции «Менеджера отложенной автозагрузки»
 Окно добавления/редактирования задачиCправка по параметрам командной строкиПараметры командной строки: StartupDelayed /help StartupDelayed [/run] [/d] /help - эта справка /run - выполнение задач /d - запускать в "не-портативном режиме" (конфигурационные файлы в директории %LocalApplicationsData%\StartupDelayed ) По умолчанию программа будет запущена в режиме конфигурации, и будет искать конфигурационные файлы в директории с исполняемым файлом. СкачатьПортабельная версия (ZIP)ИнсталляторИсходники на GitHubОфициальные страничкиНа tolik-punkoff.comКопия странички программы на LJRЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/menedzher-otlozhennoj-avtozagruzki/
7/21/21 02:16 am
Менеджер отложенной автозагрузки / StartupDelayed v 0.0.2
Первая версия (копия)
+ Исправлен баг с сохранением конфигурации при удалении записей (спасибо SCPicker за тестирование и сообщение).
+ Убран режим выбора каталога конфигурации из командной строки, оставлен только обычный (файлы конфигурации в LocalApplicationData\StartupDelayed\ ) и портативный (файлы конфигурации в директории с программой).
+ Оптимизировано обнаружение запускаемых программ, сначала программа проверяет наличие соответствующего диска, если не задан относительный или сетевой путь.
+ Исправлены прочие мелкие недочеты.
+ Инсталлятор изменен на NSIS.
СкачатьПортабельная версия (ZIP)ИнсталляторИсходники на GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/07/21/menedzher-otlozhennoj-avtozagruzki-startupdelayed-v-0-0-2/
5/17/21 06:32 am
Маленький пример обработки событий клавиатуры (KeyUp, KeyDown и KeyPress)
 Пример выводит на экран KeyEventArgs для KeyUp и KeyDown и KeyPressEventArgs для KeyPress . Исходник на GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/05/15/malenkij-primer-obrabotki-sobytij-klaviatury-keyup-keydown-i-keypress/
5/15/21 06:53 am
Калькулятор пропорций v 0.2
Задолбало меня считать сумму внесения платежей с комиссией, через терминалы (или с международными переводами, один хрен, там с комиссией), так что запряг друга $EG'у, чтоб он разобрался в вопросе и допилил эту функцию в калькулятор пропорций. Он, ВНЕЗАПНО, допилил:

Формулаvar paymentWithCommission = payment / (1 - 100 / proc); где: payment - необходимая сумма платежа proc - процент комиссии СкачатьУстановщикБинарник без установки (ZIP)ИсходникНа GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/05/14/kalkulyator-proportsij-v-0-2/
3/15/21 02:43 pm
Пакетный конвертер (перекодировщик) текстовых файлов v 0.0.3b
Обновление пакетного конвертера текстовых файлов.
Благодарим всех, кто сообщил о багах.
Изменения в версии v 0.0.3b+ Изменения в алгоритме поиска файлов + Поправлен баг с сохранением конфигурации (масок файлов) ИсходникиРепозиторий на GitHubСкачатьПортативная версияПостоянная страничка программы ( копия) Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/03/14/paketnyj-konverter-perekodirovshhik-tekstovyh-fajlov-v-0-0-3b/
3/14/21 05:10 am
Пакетный конвертер (перекодировщик) текстовых файлов
Изначально писалось для товарищей в 2016 г., поскольку почему-то все пакетные конвертеры/перекодировщики текстовых файлов были исключительно платными, во всяком случае на тот момент и под Windows.
Основные возможности+ Пакетная перекодировка текстовых файлов + Создание полного дерева каталогов для перекодированных файлов + Доступен расширенный список кодировок (все кодировки, поддерживаемые .NET Framework) Изменения в версии v 0.0.2b+ Добавлена возможность сохранять изменения в целевой каталог (перезаписывать файлы) + Программа по умолчанию работает в портативном режиме, настройки хранятся в каталоге с программой. + Изменен формат файла настроек на XML Изменения в версии v 0.0.3b+ Изменения в алгоритме поиска файлов + Поправлен баг с сохранением конфигурации (масок файлов) Системные требованияWindows XP/7/8/10 .NET Framework 2.0. 256 Мб ОП Ключи командной строки/help - эта помощь /np - отключение портативного режима (настройки программы хранятся в C:\Users\<пользователь>\AppData\Local\Ba tchTextConverter\)
Разработчики
D. Larin Chang Min Ho PunkArr[]
Скриншоты
 Главный экран
 Выбор кодировки
 Выбор кодировок (полный список)
 Маски файлов
Исходники
Репозиторий на GitHub
Скачать
Портативная версия
Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/batch-text-converter/
3/14/21 04:48 am
C#, поиск файла по маске, более правильное решение.
ПреамбулаКогда-то уже говорил ( копия) что стандартная функция C# Directory.GetFiles(); неправильно ищет файлы по маске. И даже сделал на скорую руку кривофикс, но кривофикс действительно оказался именно что криво. Во-первых, срабатывал только для некоторых масок, а во-вторых, оказался чувствительным к регистру имен файлов. Делаем более прямое исправление. Вспомогательные функцииЗаведем вспомогательную функцию, которая будет добавлять конечный слэш ( \ ) к имени директории. Оно не особо надо, но пусть будет для порядка. private static string AddSlash(string st)
{
if (st.EndsWith("\\"))
{
return st;
}
return st + "\\";
}
И функцию, получающую имя файла из полного пути. Конечно, можно было бы воспользоваться классом FileInfo из System.IO , но тут операция совсем уж простая, а FileInfo может сгенерировать ненужный Exception . Проще получить имя файла с помощью строковой операции: private static string GetNameOnly(string FullName)
{
int LastSlash = FullName.LastIndexOf("\\");
if (LastSlash == -1) return FullName;
return FullName.Substring(LastSlash + 1);
} Преобразование маски файла в регулярное выражение.Да, я таки решил воспользоваться нелюбимыми регекспами. Впрочем, маска файла и есть регулярное выражение, только с упрощенным синтаксисом. 1. В имени файла могут встретиться символы, считающиеся служебными в регулярном выражении ( . , ^ , $ , { , } , [ , ] , ( , ) , + ), их необходимо экранировать, чтоб они воспринимались обработчиком регулярных выражений, как обычные, а не служебные символы. //точка в маске файла должна быть точкой в регулярном выражении //экранируем Mask = Mask.Replace(".", "\\."); //^,$,{,},[,],(,),+ в regexp служебные, в именах файла допустимые //экранируем Mask = Mask.Replace("^", "\\^"); Mask = Mask.Replace("$", "\\$"); Mask = Mask.Replace("{", "\\{"); Mask = Mask.Replace("}", "\\}"); Mask = Mask.Replace("[", "\\["); Mask = Mask.Replace("[", "\\["); Mask = Mask.Replace("(", "\\("); Mask = Mask.Replace(")", "\\("); Mask = Mask.Replace("+", "\\+"); 2. * - в маске файла это любой символ, или их отсутствие. В регулярном выражении этому соответствует комбинация .* , заменяем: Mask = Mask.Replace("*", ".*"); 3. ? в маске файла - любой существующий символ. В регулярном выражении это символ . (точка), заменяем: Mask = Mask.Replace("?", "."); 4. Осталось ограничить работу регулярного выражения началом и концом строки, строкой будет являться имя (маска) файла. Начало строки обозначается символом ^ , конец символом $ . Добавляем: Mask = "^" + Mask + "$"; Функция целиком: private static string Mask2Reg(string Mask)
{
//точка в маске файла должна быть точкой в регулярном выражении
//экранируем
Mask = Mask.Replace(".", "\\.");
//^,$,{,},[,],(,),+ в regexp служебные, в именах файла допустимые
//экранируем
Mask = Mask.Replace("^", "\\^");
Mask = Mask.Replace("$", "\\$");
Mask = Mask.Replace("{", "\\{");
Mask = Mask.Replace("}", "\\}");
Mask = Mask.Replace("[", "\\[");
Mask = Mask.Replace("[", "\\[");
Mask = Mask.Replace("(", "\\(");
Mask = Mask.Replace(")", "\\(");
Mask = Mask.Replace("+", "\\+");
//* - любое количество любого символа,
//в regexp любой символ - точка, любое количество *
Mask = Mask.Replace("*", ".*");
//? - любой символ, в regexp любой символ - точка.
Mask = Mask.Replace("?", ".");
//добавляем начало и конец строки к имени файла.
Mask = "^" + Mask + "$";
return Mask;
} Модификация функции поискаВ модифицированную функцию поиска передаются такие же параметры, как и в функцию Directory.GetFiles(); т.е. маска файла, путь до каталога и перечисление SearchOption , которое может принимать два значения: SearchOption.AllDirectories - поиск с подкаталогами и SearchOption.TopDirectoryOnly - поиск только в текущем каталоге. Внутри функции: 1. Преобразуем маску файла в регулярное выражение: string MaskRegStr = Mask2Reg(sMask); 2. Добавляем слеш к пути поиска (на всякий случай): sPath = AddSlash(sPath); 3. Заводим List<string> , куда будем складировать отфильтрованные файлы из найденных (на то, как криво работает Directory.GetFiles() есть ссылки в начале заметки). List<string> FoundFiles = new List<string>(); 4. Создаем обработчик регулярных выражений с опцией RegexOptions.IgnoreCase , чтобы игнорировать регистр входной строки (в нашем случае - имени файла). Regex MaskReg = new Regex(MaskRegStr, RegexOptions.IgnoreCase); 5. Вызываем функцию поиска из System.IO : string[] files = Directory.GetFiles(sPath, sMask, SO); 6. Фильтруем вывод на предмет лишних файлов (см. подробнее по ссылке в начале заметки). Фильтрация производится путем сравнения имени файла с ранее сгенерированным регулярным выражением. Если имя файла соответствует регулярке, оно добавляется в List : foreach (string filename in files)
{
if (MaskReg.IsMatch(GetNameOnly(filename)))
{
FoundFiles.Add(filename);
}
}
7. Результат возвращается в виде строкового массива: return FoundFiles.ToArray(); Функция целиком: public static string[] Find(string sPath, string sMask, SearchOption SO)
{
string MaskRegStr = Mask2Reg(sMask);
sPath = AddSlash(sPath);
List<string> FoundFiles = new List<string>();
Regex MaskReg = new Regex(MaskRegStr, RegexOptions.IgnoreCase);
string[] files = Directory.GetFiles(sPath, sMask, SO);
foreach (string filename in files)
{
if (MaskReg.IsMatch(GetNameOnly(filename)))
{
FoundFiles.Add(filename);
}
}
return FoundFiles.ToArray();
} Пример на GitHubВроде бы в этот раз все предусмотрел, и глюкоопцию встроенной функции поправил, и в регулярке нигде не наебался. Пример на GitHubЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2021/03/11/c-poisk-fajla-po-maske-bolee-pravilnoe-reshenie/
|