Linux, curl, обнаружение и анализ ошибок HTTP. Улучшаем скрипт.

В первой части я показал, как просто обнаружить ошибки HTTP при работе с curl. Но на самом деле, подход, использованный в скрипте, немного неправильный:

Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода. В настоящее время выделено пять классов кодов состояния.

Т.е. объясняя по рабоче-крестьянски, не только код 200 может свидетельствовать об успешном завершении запроса, а другие коды, кроме явных клиентских или серверных ошибок, могут требовать от нас каких-либо действий.

Вообще, коды ответа HTTP разделены на 5 классов:
1xx — информационные
2xx — успешное завершение
3xx — требуется переопределение
4xx — ошибка, допущенная со стороны клиента
5xx — ошибка, допущенная со стороны сервера

Вот и модифицируем наш скрипт в соответствии со стандартом.
В общем, надо из кода ответа HTTP извлечь первую цифру, и, соответственно прореагировать. Привожу часть скрипта, ответственного за более подробную реакцию на код ответа HTTP:

curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null
EXITCODE=$?
if [ $EXITCODE -ne 0 ]; then
    echo "CURL error $EXITCODE"
else
    HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'` #get HTTP status code
    HTTPSTATUSMESS=`cat $HEADERDUMP|head -1|cut -d '  ' -f 3-
    HTTPSTATUSID=`echo $HTTPSTATUS|cut -c 1` #get first char status code
    
    case "$HTTPSTATUSID" in
	1 ) echo -n "Informational: ";;
	2 ) echo -n "Success: ";;
	3 ) echo -n "Redirection: ";;
	4 ) echo -n "Client Error: ";;
	5 ) echo -n "Server Error: ";;
	* ) echo -n "Unknow status: ";;
    esac
    
    echo "$HTTPSTATUS $HTTPSTATUSMESS"
fi


Жирным шрифтом выделена строка, в которой мы получаем этот самый класс кода возврата.

Курсивом — строка, где мы получаем пояснения текстовые пояснения к коду ответа.

Используемая в процессе анализа утилита cut, в первом случае, позволяет нам вывести в переменную все символы после с третьего пробела.
Перед первым у нас версия протокола http, потом код ошибки, а потом пояснение, которое может содержать несколько пробелов, поэтому awk тут не подходит.
cut так же может работать с текстовыми данными, в которых есть разделители, например пробелы, или же с отдельными символами, как в той строке кода, что выделена жирным — так мы можем извлечь первую цифру из кода ответа.

Дальнейший анализ осуществляется с помощью оператора case

Пример работы

Скрипты

Расширенный анализ кодов состояния HTTP:
На Pastebin
На Github

PHP скрипт для проверки:
На Pastebin
На Github

Дополнительные источники

Краткий справочник по командам curl и wget Копия
Утилита cut
Коды статуса HTTP
Оператор case

Начало

curl в Linux, ошибка 404, обнаружение и использование кодов ответа HTTP

Итак, возникла следующая задача — определить, когда curl получил вменяемые данные от http-сервера, а когда нет. В общем, и самом распространенном случае, задача сводится к тому, чтобы определить, отдал ли нам сервер запрашиваемый файл, или отобразил «страница не найдена».

Впрочем, это работает и для других возможных кодов ответа.

Ясно, что сервер, на наш запрос GET может ответить, как возвратив нам запрашиваемую страницу, так и отправив код, например, 404 (не найдено), и возвратив страницу-заглушку для этого случая. Так вот, на уровне скрипта bash или скрипта php необходимо проанализировать ответ сервера, чтобы не выдать пользователю вместо ожидаемых данных, всяческую лабуду. Далее я рассматриваю исключительно консольную Linux-утилиту curl. Для php, синтаксис, по-моему, отличается.

Есть страница, которую мы хотим получить: http://example.org/page.html, сохранить ее в файл page.html и есть curl, команда будет такая:

curl -o "page.html" http://example.org/page.html

Если страница на месте, то мы получим ее, и ничего анализировать не требуется.
Если же нет, то от большинства web-серверов мы получим страницу-заглушку, например такую, но никакой ошибки при этом.

Как же быть:

Проверяем код ошибки самого curl, если нет связи с сетью, URL неправильный, или задан неподдерживаемый curl протокол, если так, то мы получим соответствующий код возврата, наподобие:

curl: (1) Protocol htt not supported or disabled in libcurl

А вот если адрес правильный, и никакой ошибки в адресе или соединении нет, то код возврата не сработает, нам самим придется думать дальше.

Надо получить код ответа HTTP!

Сделать это можно, если получить отдельно заголовки ответа сервера, и после их проанализировать. Благо, для этого никакого страшного колдунства не требуется, достаточно указать утилите curl опцию -D (т.е. dump) и файл, куда выгружать заголовки.

Покажу это на примере конкретного скрипта:

#!/bin/bash

HEADERDUMP="/tmp/headerdump.txt"
SAVEFILE="/tmp/httpfile"
HTTPSTATUS=""

curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null
EXITCODE=$?
if [ $EXITCODE -ne 0 ]; then
    echo "CURL error $EXITCODE"
else
    HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`
    
    if [ "$HTTPSTATUS" == "200" ];then
	echo "OK"
    else
	echo "HTTP error $HTTPSTATUS"
    fi
fi

заводим 3 переменные

HEADERDUMP="/tmp/headerdump.txt" — файл, в который будем получать заголовки
SAVEFILE="/tmp/httpfile" — файл с сервера, который мы хотим получить
HTTPSTATUS="" — переменная для статуса (состояния) HTTP

curl -o $SAVEFILE $1 -D $HEADERDUM

пытаемся скачать нужный файл (получить страницу):
-o «имя_файла» — куда сохранять результат
$1 — внутренняя переменная, первый параметр скрипта, при вызове его с командной строки. В своем скрипте надо заменить на свой случай.
можно добавить >/dev/null 2>/dev/null — для красоты, чтоб не вылезали сообщения о процессе и ошибках.

-D <файл> — файл, куда будем копировать заголовки

Файл headerdump.txt выглядит примерно так:

HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Fri, 30 Mar 2018 00:17:23 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.33
Link: ; rel="https://api.w.org/"
Set-Cookie: quick_chat_alias=Anon_240883; path=/
Upgrade: h2,h2c
Vary: Accept-Encoding,User-Agent

В первой строке — интересующая нас информация. Версия протокола (не интересно), код ответа (вот он) и информационное сообщение (не особо надо).

Вычленяем код:

HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`

1. Берем первую строчку (head -1)
2. Сохраняем в переменную 2-е значение после пробела (разделитель пробел): awk '{print $2}'

Дальше можно анализировать:

    if [ "$HTTPSTATUS" == "200" ];then
	echo "OK"
    else
	echo "HTTP error $HTTPSTATUS"
    fi

Результат

Также, впрочем, можно поступить и для анализа запросов POST, вот тестовый скрипт php для отладки подобных возможностей и скрипт bash

Скачать

Пример с запросом GET
Пример с запросом GET на Гитхаб

Пример с запросом POST
Пример с запросом POST на Гитхаб

Тестовый php скрипт для запроса POST
На Гитхаб

Скачать одним архивом

HTML и CSS мелочи

Простой двухколоночный макет на DIV’ах

HTML
CSS
Скачать

Таблица с помощью DIV

HTML
CSS
Скачать

Ограничение размера изображения в CSS

Абсолютный размер в пикселях
По размеру DIV’а
Пример

Источники

Киберфорум
Кот из примера
Еще какие-то

L.S.

Про «Жизнь»

Спрашивают, есть ли что-то подобное в текстовом режиме. Есть, только предупреждаю, там такой говнокодище, что самому смотреть страшно. И некрасиво выглядит, в отличие от графической версии. Если переделаешь, сойдет за зачет, наверное.
Даже картинки не будет.

LIVE.PAS
Архив с экзешником и исходником

C# Пример Charmap (таблицы символов) для различных кодировок.

Очередное студенческое задание, да. Причем опять, то ли препод не совсем адекватный, то ли студент, то ли мы дебилы и не видим чего-то лежащего на поверхности. Потому что «совсем для всех» кодировок, поддерживаемых .NET оно не получается.

Для начала, пришлось задачу все-таки глобально поделить на 3 больших части:
— кодировки однобайтовые (Windows 1251, DOS 866 и т.д.)
— кодировка Unicode
— кодировки многобайтовые, но не Unicode (всякие там японские, китайские и прочие).

Однобайтовые

С ними проще всего. Достаточно перебрать все символы от 0 до 255, перекодировать их последовательно в UTF-16 стандартной функцией класса Encoding и вывести на экран.

Encoding enc = Encoding.GetEncoding(CP);
for (int i = 0; i < 256; i++)
{
	string sChr = enc.GetString(new byte[] { (byte)i });
	//...
}

Отделить их от остальных тоже просто, у объекта Encoding есть свойство IsSingleByte

Unicode

С этим тоже особой сложности нет, весь стандарт открытый, можно взять список диапазонов Юникода прямо с официального сайта. Разобрать, залить в ComboBox и отображать кусками, для больших кусков сделать постраничное листание.

Главная проблема была побороть глюк с отображением символа с кодом > FFFFh Копия, из-за чего пришлось использовать RichTextBox и периодически пересчитывать ему размер в зависимости от используемого шрифта и символа, а также в нужных местах перерисовывать таблицу, чтоб та не расползалась.

Вторая проблема - изобрести какое-то подобие "композитных" шрифтов в BabelMap, т.е. подгружать разные шрифты для разных диапазонов Unicode, поскольку шрифта, абсолютно поддерживающего все символы Unicode нет, он бы получился чудовищно большим. И те, которые есть-то, не маленькие, из нескольких файлов, и весят под сотню мегабайт.

Чтоб ради задания не загадить систему шрифтами, пришлось предусмотреть возможность грузить их из файлов, а тут поджидал уже другой глюк, на этот раз Framework'а Копия.

В общем, процентов 90 кода (да и процессорного времени) уходит на возню со шрифтами и отрисовку таблицы.

Отделить варианты кодирования Unicode от других кодовых страниц тоже несложно, благо всего этих вариантов не так много (UTF16 LE/BE, UTF32 LE/BE, UTF8 и UTF7).

public static bool IsUnicode(int CodePage)
        {

            if (CodePage == 65001 ||
                CodePage == 65000 ||
                CodePage == 1201 ||
                CodePage == 1200 ||
                CodePage == 12000 ||
                CodePage == 12001)
                return true;
            else return false;            
        }


А получить конкретный символ можно вот таким способом:

if ((num >= 0x00d800) && (num <= 0x00dfff))
{
	st = Convert.ToString((char)num);
}
else
{
	st = char.ConvertFromUtf32(num); 
}


if ((num >= 0x00d800) && (num <= 0x00dfff)) - это чтобы не попасть в диапазоны суррогатов, но все-таки на их месте что-то отображать (в шрифтах там обычно пустые символы или знаки ?), а char.ConvertFromUtf32() при попадании в диапазон суррогатов свалится с ошибкой.

Остальные многобайтные кодировки

А вот тут уже так легко не получится, все-таки единственный вменяемый способ, это искать спецификации на каждую. Поэтому, в рамках задания, эта часть задачи была признана некорректной и не решаемой.

Нет, был, конечно, вариант простого перебора всех возможных вариантов. Максимальное количество байт, необходимых для кодирования символа в указанной кодировке можно получить с помощью Encoding.GetEncoding(cp).GetMaxByteCount(1), но перебрать все возможные значения, например, для массива размером уже в 4 байта, перебирая его, например, так, да еще и фильтруя все лишнее, непомерно долго.

В общем, вроде бы того, что сделали, оказалось достаточно.
Пришлось студенту писать пояснительную записку с источниками 🙂

Исходник примера на GitHub
Скачать

Leha S, NKT

C# Ошибка «Попытка чтения или записи в защищенную память» при работе со шрифтами из PrivateFontCollection

Понадобилось грузить TTF-шрифты из файлов, что делается с помощью PrivateFontCollection.AddFontFile(FileName). И, внезапно, стал проявляться плавающий глюк, возникающий, если периодически пересоздавать объект PrivateFontCollection. Например, при попытке сделать MeasureString(Text, LoadedFont).ToSize(), программа стала вываливаться с ошибкой "Попытка чтения или записи в защищенную память".

Пишут, что это глюк Framework’а и толковое решение только одно, создавать PrivateFontCollection один раз при запуске программы, например, в каком-нибудь статическом классе, и больше ее не трогать. Т.е. подгружать новые шрифты можно, а пересоздавать коллекцию не надо.
Минус решения — можно загадить память подгружаемыми шрифтами, если подгрузить много файлов. Но лучше пока ничего не нашел.

В принципе, можно создать вот такой статический класс, который будет подгружать шрифт в коллекцию, и хранить в Dictionary сопоставление между именем файла и шрифтом в коллекции. Если файл еще не был загружен — подгружать, если был, возвращать позицию в коллекции.

Ну и чтоб два раза не вставать, класс FileFont, который заодно меняет параметры шрифта (размер и начертание).

На Cyberforum’е тоже пока ничего более дельного не предложили.

C# Отображение суррогатной пары (символа с кодом >FFFF)

Известно, что внутренний формат строк в .NET — UTF16, что значит, что символы из основной многоязыковой плоскости (BMP) Unicode, т.е. с кодом меньше FFFF кодируются одним машинным словом, а остальные символы — двумя, одно из которых т.н. суррогат.

Так вот, как оказалось, с отображением суррогатных пар может возникнуть проблема. Контролы Windows Forms могут воспринимать символ с кодом >FFFF не как один символ, как должно быть, а как два. Для примера пробуем отобразить анатолийский иероглиф

с кодом 0x14476

Как видно, TextBox и Label воспринимают символ, как два символа, и, соответственно, его не отображают, а RichTextBox видит, что это один символ, но не отображает его, даже при правильно заданном шрифте.
MessageBox также отображает символ не как один, а как два:

Устранение проблемы с RichTextBox

Для устранения проблемы с RichTextBox достаточно задать нужный шрифт перед тем, как присвоить свойству Text нужные символы.

         int Code = 0x14476; //анатолийский иероглиф        
        Font AnFont = new Font("Anatolian", 24, FontStyle.Regular,
 GraphicsUnit.Pixel, 1);
        private void Form1_Load(object sender, EventArgs e)
        {
            string strSP = char.ConvertFromUtf32(Code);
            
            lblTest.Font = AnFont;
            txtTest.Font = AnFont;                        
            lblFont.Text = AnFont.FontFamily.Name;
            rtbTest.Font = AnFont;

            lblTest.Text = strSP;
            txtTest.Text = strSP;
            rtbTest.Text = strSP;
        }

PictureBox также отрисовывает нужный символ без проблем:

Корень проблемы

А корень проблемы кроется не в C#, .NET и компонентах Windows Forms, а в самой Windows. Пакет обновления SP1 для Windows 7 решает проблему полностью.

Наиболее универсальное решение

Наиболее универсальным решением является использование RichTextBox для работы с такими символами, во всяком случае, это работает даже для Windows XP, для которой ждать патчей, понятное дело, не приходится.
Главное, не забывать про то, что шрифт надо задавать до вставки/присвоения символа.

Обсуждение на Киберфоруме Копия

Пример
Пример на GitHub

Шрифты поддерживающие весь Unicode-диапазон

Или, во всяком случае, большинство символов.

TWBh: шрифт, поддерживающий большинство символов Unicode
Дополнительно:
Композитный шрифт для BabelMap (TWBhBabelCompositeFont.xml)
Композитный шрифт для WPF (TWBh.CompositeFont)
Композитный шрифт для примера простой Charmap для Unicode и однобайтных кодировок (babel.cf)

Universalia самый распространенный максимально поддерживающий Unicode набор шрифтов Ссылка Magnet

Набор шрифтов с почти полной поддержкой Unicode, собранный неизвестным пользователем интернета Что и как поддердживает каждый файл шрифта, есть описание в тектовом файле. Плюс есть композитный шрифт для тестовой программы.

Программа BabelMap Копия
Самый совершенный Charmap для Unicode, поддерживает композитные шрифты и все диапазоны Unicode

C# Перевод чисел между системами счисления стандартной функцией класса Convert

Да, совсем забыл выложить исходник, спасибо, что напомнили.
Перевести число в/из десятичной в 2, 8, и 16-ричную систему можно с помощью стандартной функции класса Convert
Convert.ToInt64(s, From)
s — строка, содержащая число.
From — основание системы счисления.

Обратное преобразование:
Convert.ToString(n, To)
n — число
To — основание системы счисления.
На выходе будет строка

В примере еще показал, как ограничить ввод в текстовое поле, чтоб можно было вводить только определенные символы, и добавил отображение символа по его коду (в однобайтной кодировке, для Unicode будет погода на Марсе). Числа можно вводить через пробел.

Скачать исходник
Этот и другие примеры на Github

Иконка для своего приложения Windows. Стандартные размеры иконок

И как сделать ICO файл с несколькими изображениями
Спрашивали, как надо правильно делать иконку для своего Windows-приложения.

В первую очередь нужно ее нарисовать, либо найти изображение. Чем больше, тем лучше, поскольку для хорошей иконки потребуется несколько файлов разного размера.

Если изображение будет одно и маленькое, то иконка будет выглядеть некрасиво, пойдет квадратными пикселями.

То же самое касается и иконки для формы приложения, хотя на самой форме корректно будет отображаться и маленькая иконка 16×16 пикселей, при переключении по Alt+Tab уже будет заметно и некрасиво.


Рисовать, то лучше в каком-нибудь векторном редакторе, чтоб было потом проще создать несколько растровых изображений разных размеров. Мы, например, пользуемся Inkscape, он простой, бесплатный и для простых изображений вполне подойдет.

Еще момент — изображение должно, очевидно, быть квадратным.

Стандартные размеры иконок приложения

Нарисовали, теперь нужно получить несколько изображений стандартных размеров:

— 16×16
— 32×32
— 48×48
— 256×256

Где-то читал рекомендацию, что нужен значок еще 128×128, но на практике пока не заметил, чтобы его наличие было критично.
Для Windows 7 и выше обязательно нужен значок 48×48
Обратите внимание, что размер значка рабочего стола по умолчанию в XP был 32×32, а в Windows 7 — 48×48

В значки для формы, а не для иконки экзешника, лучше не включать значок 256×256 в том случае, если приложение должно работать на XP.
В остальных случаях XP игнорирует значок 256×256, но ничего плохого при этом не происходит, а вот если такой значок используется для формы, то приложение может упасть.

Сборка нескольких изображений в одну иконку

Известно, что в одном файле ICO могут храниться несколько изображений разных размеров. Для сборки есть много приложений и онлайн-сервисов, но мы пользуемся простой бесплатной программкой icon sushi Копия

Пользоваться очень просто.
1. Открываем все нужные изображения
2. Выделяем их в окне программы:

3. Сохраняем иконку (File — Save as Multiple Icon)

ЗЫ. Чтоб два раза не вставать.
Кто-то просил картинки-кнопочки от XuliOrganizzer’а
Так Леша выложил картинки на Github

Текстовый редактор FOTON для DOS

Охрененная софтина была для 1989 года.
Макросы, возможность компиляции программ, не выходя из бассейна из редактора и множество передовых фишек для того времени.

А самое главное, в нем есть одна штука, которой до сей поры нет ни в одном более современном текстовом редакторе. Выделение прямоугольных блоков текста! Которые можно переносить, вставлять и т.д. Вот нет такого больше нигде и все, а надо иногда. Причем настолько надо, что периодически пользуюсь сим олдовым произведением программерского искусства. Хоть сам бери и пиши редактор с подобной функцией, блин.
UPD.
Есть, оказывается. Не знаю насчет vim и emacs, правда, но Notepad++ делает как надо. И Far (по Аlt+стрелки). А вот Студия делает, но не совсем так.


Его собственная внутренняя демка:

https://youtu.be/vc5ONlBnPrg
Скачать

Colors. Утилита для подбора цвета фона и текста в Windows Forms

Опять студенты приходили, на этот раз с мелким заданием, перечислить все названия цветов в Windows Forms. Заодно уж сделал из этого задания утилитку, чтобы подбирать цвет символов на фоне в Windows Forms. Довел задание, так сказать, до логического конца. В общем, кто не успел сегодня на скайп-чатик, где я всякие мелочи объяснял и делал, ходите на Гитхаб, скачивайте там. Только не забудьте хоть что-нибудь переделать, а то преподы будут ругаться.

Принцип очень простой. Все названия цветов есть в перечислении KnownColor, а в классе Enum есть метод GetNames, который позволяет получить строковый массив с именами элементов перечисления.

string[] ColorNames = Enum.GetNames(typeof(KnownColor));

Вытащить конкретное значение элемента перечисления по его имени (если оно в виде строки) можно с помощью Enum.Parse

KnownColor knownColor =
                    (KnownColor)Enum.Parse(typeof(KnownColor), n);


n — строковая переменная с именем.

Все остальное стандартно, заполняем в цикле GridView и красим ячейки.

Ну и в довесок в программе есть пример использования ColorDialog и получение информации о выбранном в диалоге цвете.

И элемента управления TrackBar для выбора цвета и фона по RGB.

Пользуйтесь на здоровье.

Исходник:
На Гитхабе
На Mega.NZ
Cкомпилированная программка

ЗЫ. Спасибо, Леха, огромное за наводку на GitEve, и удобно, можно всё мышей тыкать, не набивать километры команд в консоли, и идет на всех ОС. Все-таки с этим вашим гитом через консоль несколько неудобно работать, или я пока еще не привык.

Игра «Жизнь» на Turbo Pascal for DOS

От ведь блин, нашел лохматого возраста исходник игры «Жизнь». Писалось с другом на Turbo Pascal для DOS в лохматых годах, когда еще в школе учился.

Написано, конечно, криво, косо, неоптимизированно и все это жутко тормозит, особенно «редактирование» картинки. Но все равно круто, аж детство вспомнилось, когда не пил, не курил, мониторы были зеленее, компьютеры медленнее, Ельцин президент, а я хотел вступить в КПРФ.


https://youtu.be/W7VRyfoaOkg
Еще видео

Думал даже переписать сие произведение, Free Pascal вроде умеет в графику. Может и займусь, или найду еще более крутой исходник шизово-психоделических трехмерных графиков и сделаю из него заставку на Юнити, все равно давно хотел попробовать что-нибудь написать, чтоб с триде, да в голову ничего не приходило.
А гадский Ютуб почему-то пакостит в видео, во всяком случае, в эти. На локальной машине все четко видно, а публикуешь, как-то лажовенько выглядит, ерунда какая-то непонятная с ютубом.

Исходник
Скачать

Патчи от WannaCry, NotPetya и скрытых майнеров для Windows XP

Пришлось столкнуться, слава Ктулху не с самими вирями и майнерами, но с незаделанными дырками. Есть два пути обновить пожилую ОС, протестировать на наличие уязвимости Eternal Blue и заткнуть только ее, или сделать кумулятивное обновление.

Тестирование

Протестировать наличие дыры можно с помощью программы Eternal Blues. Пользоваться очень просто, вводим диапазон IP в локальной сети и жмем кнопку SCAN. Где в графе Vulnerable? указано YES, там дырка не заделана.

Заделываем

Качаем официальные патчи от MS

KB4012583
KB4012598

Устанавливаем, перезагружаемся, и проверяем результат программой Eternal Blues

Кумулятивное обновление

Вот тут в прямом смысле слава Украине, а точнее конкретному украинцу под именем Simplix, который заботливо собрал все обновления со времен выхода SP3 в одну кучу, протестировал и выложил в одном пакете.

Скачать можно с его сайта simplix

Я поставил сразу тестовое обновление, но вы можете скачать то, которое уже полностью протестировано, хотя и тестовое вполне себе зашло. 5 машин и неделя времени, полет нормальный.

Установка детально описана на его же форуме.

Большой плюс для виндопользователей пиратской винды, если таковые найдутся :), после обновлений активация не слетает.

Копии на всякий случай

Eternal Blues
KB4012583 и KB4012598
UpdatePackLive-18.2.18 (update.bat запускает пакет обновления с ключом, обновляющим IE до версии 8)

Подводный камень при чтении файла с помощью File.ReadAllText

Иногда проще прочитать файл, как текстовый в однобайтовой кодировке, чтобы что-нибудь там поделать с помощью стандартных string.Replace/string.Remove и т.д., иногда даже если файл не совсем текстовый, потому что таких же удобных функций для работы с массивом байт нет (или я не нашел).
Это, наверняка, адский быдлокод, но все-таки вполне альтернатива изобретению совсем уж дикого велосипеда.

А у меня речь шла о текстовых файлах, правда, неизвестно в какой кодировке, и символах, которые нужно искать/менять. Символы от кодировки не зависели, посему любой файл можно было рассматривать, как текстовый, в любой однобайтовой кодировке. Главное, в какой кодировке открыл, в той же потом и сохранить.
Так вот File.ReadAllText пытается автоматически определить кодировку файла на основе наличия меток порядка следования байтов и принудительная установка кодировки не помогает. Если в файле встретился зловредный BOM, то ReadAllText наплюет на твои указания кодировки с высокой колокольни и откроет в той, на которую ему BOM указывает, а при сохранении, соответственно, будет глюк и текст превратится в тыкву.

Беда, конечно, решается стандартно, чтением файла с помощью StreamReader и записью с помощью StreamWriter, которые себе такой самодеятельности не позволяют, но «осадочек остался».

Пример
Скачать

XuliOrganizzer. Простенький самописный органайзер на C#

Нет, оно не читается, как хули, органайзер. Но, может быть, что и подразумевается. 🙂
Это маленькая программа-органайзер для XP, 7, 8 и Vista. На 10 никто из нас ее запускать не пробовал, из за отсутствия таковой.

Что умеет:
— Собственно, напоминания по расписанию о событиях. Ну там кота покормить, или не забыть выключить самогонный аппарат, или продать славянский шкаф.

Возможны напоминания как в виде всплывающих подсказок в трее, так и в отдельном окне, повтор напоминаний через заданное время, звуковое оповещение.
Имеется возможность активировать/деактивировать задание-напоминание, есть контроль просроченных заданий и возможность немедленного выполнения таковых при старте программы.

— Запуск программ по расписанию, как с уведомлением, так и без.

— Симпатичный таймер обратного отсчета

— Текстовые заметки

Для заметок есть «корзина», т.е. случайно удаленную заметку можно восстановить.

Все данные хранятся в XML, в настройках можно посмотреть путь к файлу.

Писал в основном Леша, изредка виртуально пиная всех вокруг, и в основном для меня, потому что я давно хотел удовлетворяющий меня органайзер с напоминаниями, а в сети не было такого, который бы меня устраивал.

Распространяется свободно, как обычно, по лицензии Хекса.

Еще скриншоты

Скачать
Зеркало

Исходники:

Скачать
На Github

C#. Windows Forms. Режим замены текста по нажатию клавиши Insert в TextBox.

То есть, задача сделать, чтоб было как в нормальном текстовом редакторе, нажимаем Ins, и символы перед курсором заменяются на введенные с клавиатуры. Нажимаем еще раз и символы вставляются как обычно.
Элемент управления TextBox почему-то из коробки это не поддерживает, поддерживает MaskedTextBox, но и стандартный TextBox вполне можно допилить. Не знаю, почему на первых строках в поисковике какой-то ужас со StringBuilder‘ами и чуть ли не вызовом WINAPI, хотя все гораздо проще.

Заводим в форме логическую переменную, которая будет отвечать за то, какой режим ввода сейчас true — замена, false — обычная вставка.

bool InsertMode = false;

В обработчик события KeyUp помещаем код, который будет менять флаг, если был нажата клавиша Insert:

private void txtTest_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Insert)
            {
                InsertMode = !InsertMode;
            }

        }

В обработчике KeyPress код следующий

private void txtTest_KeyPress(object sender, KeyPressEventArgs e)
        {
            //Вытаскиваю объект, который вызвал событие, 
            //чтоб можно было подключить несколько TextBox'ов
            TextBox tb = (TextBox)sender;
            
            //если включен соотв. режим, курсор не в конце текста
            //и не нажата какая-либо управляющая клавиша
            //заменим символ перед курсором
            if (InsertMode && tb.SelectionStart < tb.TextLength 
                && !Char.IsControl(e.KeyChar))
            {                                
                //выделяем 1 символ перед курсором
                //область выделения автоматически заменится 
                //символом, введенным  с клавиатуры
                tb.SelectionLength  = 1;

                //если выделен символ перевода строки, значит это конец строки 
                //в multiline TextBox,  
                if (tb.SelectedText == "\r" || tb.SelectedText == "\n")
                    tb.SelectionLength = 0; //не надо ничего
                                           //заменять, убираем выделение
            }
        }

Вот. Комментарев больше кода 🙂

Можно сделать замену текста по кругу, т.е., когда дошли до последнего возможного символа, начинаем заменять с первого. Может пригодиться, если строка какая-то небольшая, например две цифры секунд, какой-нибудь код, почтовый индекс и т.д.

Надо всего лишь модифицировать первое условие, чтоб исключить проверку на длину строки и добавить проверку на TextBox.MaxLength

if (InsertMode && !Char.IsControl(e.KeyChar))
{
	//замена по кругу
            if (tb.SelectionStart == tb.MaxLength) tb.SelectionStart = 0;
            //   [...]
}

Достигли последнего возможного символа, перескочили в начало текстового поля.

Пример 1 Пример 2
Скачать проекты

C# Windows Forms. Изменение размеров формы без заголовка

Форму с FormBorderStyle None можно сделать такую, чтобы пользователь мог менять и ее размеры мышью, как у обычной формы:
Код под катом
Получаются такие вот симпатичные формочки:


Код на PasteBin
Проект

C# Windows Forms. Перетаскивание формы без границ. Перетаскивание формы не за заголовок.

Т.е. такой формы, у которой FormBorderStyle установлен в None

Вариант 1, это прописать в обработчике MouseDown вот такой код:

base.Capture = false;
Message m = Message.Create(base.Handle, 0xa1, new IntPtr(2), IntPtr.Zero);
this.WndProc(ref m);

Вариант простой, форма будет перетаскиваться, как обычная форма, только за любую ее точку, а не за заголовок.

Вариант №2 вот такой:
Код под катом

Форма также перетаскивается за любую точку формы, но, нужно несколько обработчиков событий, при перетаскивании форма будет перерисовываться вся, а не как обычно, когда появляется только рамка перетаскивания, и к тому же форма чуть-чуть дернется в начале перетаскивания, после нажатия левой кнопки мыши. Но если надо, чтоб во время перетаскивания она вся перерисовывалась, то вариант использовать второй способ.

Код раз Проект раз
Код два Проект два
Источник Копия