Установка Linux и шифрование ее и всего содержимого жесткого диска. Часть II

Этап #11.
Добавление tcplay в образ initrd.

Для этого создаем какой-нибудь временный каталог и распаковываем туда из пакета (tc-play-2.0-i486-1.tgz в моем случае) полученного на этапе 8 файлы (дальнейшие пути внутри пакета)
usr/lib/libtcplay.so.2.0
usr/sbin/tcplay
Я просто воспользовался mc, зашел им в архив и нужное скопировал клавишей F5 в /tmp/tc-play, mc сам вызвал архиватор и распаковал все за меня.
Далее, выходим из архива и копируем во временный каталог (ну чтоб все нужные файлы были в одном месте и мы не запутались) файл
/lib/libdevmapper.so.1.02 (если при создании initrd, вы пользовались опцией –L, то эта библиотека уже на месте)
Теперь из временного каталога (да, можно было и сразу) скопируем файлы
libtcplay.so.2.0
libdevmapper.so.1.02
в /boot/initrd-tree/lib
(каталог библиотек файловой системы initrd)
а файл
tcplay
в /boot/initrd-tree/bin

Также tcplay во время своей работы, а конкретно подключения зашифрованных разделов вызывает из каталога /usr/sbin программу dmsetup. Соответственно, необходимо положить dmsetup в /boot/initrd-tree/usr/sbin

Чтобы dmsetup работал правильно, ему необходим каталог /dev/mapper, его тоже надо создать
mkdir /boot/initrd-tree/dev/mapper

Далее выходим из каталога initrd-tree, удаляем из директории /boot ранее созданный initrd.gz и запускаем mkinitrd без параметров, далее примонтируем нашу загрузочную флешку, заменяем файл /mnt/sda2/absolute/initrd.gz на пересозданный initrd.gz, перезагружаем компьютер и выбираем созданный на этапе 8 пункт для тестирования initrd.gz

Если все сделано правильно, то в конце загрузки будет выведено сообщение «Hello, world!» и приглашение оболочки, в котором мы введем команду tcplay. Программа должна выдать краткую справку по своим параметрам. После чего вводим команду exit и загружаемся в основную ОС.

Этап #12.
Генерация ключа для шифрования.

Для генерации ключа можно взять данные из /dev/urandom.
Если было несколько перезагрузок основной ОС и ОС некоторое время работала, то это должно быть довольно надежно. Хотя при написании данной статьи я и сомневался в этом, но мои сомнения были развеяны более опытными специалистами 🙂
Можно также воспользоваться генератором ключевых файлов, входящим в комплект Windows или Linux-версии Truecrypt, в таком случае следует использовать версию 7.1a, последнюю на момент закрытия проекта Truecrypt, скачать каковую можно, например отсюда.

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

Вот команда для генерации ключа с помощью /dev/random – стандартного устройства для получения псевдослучайных последовательностей
dd if=/dev/random of=/путь/к/файлу/имя_файла bs=1 count=256

Команда dd подробно описана, например, здесь

Далее под катом

Установка Linux и шифрование ее и всего содержимого жесткого диска.

Нам понадобятся:
1. Дистрибьютив Linux. Я здесь и далее использовал Slackware 14.2
2. Live CD Linux, я использовал Puppy Rus Slacko,

Идея в том, чтоб наша ОС и данные находились на надежно зашифрованных разделах, на жестком диске внешне не должно быть никакой разбивки, а система загружалась без ввода парольной фразы или ключа.
Как это можно реализовать
Загрузчик системы и ключ доступа будут храниться на небольшом(<50Mb) разделе флешки, при включении загрузчик разблокирует доступ к шифрованному винту, загружает ядро, далее происходит обычная загрузка системы.

Я не стал использовать LVM, а вместо LUKS выбрал клон truecrypt’а — tcplay

Этап #1. Разбиение диска на разделы

Итак, первым делом создаем нужные разделы на диске. Я сделал это в графической оболочке Puppy Rus с помощью имеющегося на диске gparted, но ничего не мешает вам сделать это с помощью другой программы.

Этап #2.
Подготовка загрузочной флешки.

Действуем как в вышеупомянутой статье – разбиваем флешку на 2 раздела, первый большой и видимый из Windows и других ОС, второй маленький – с загрузчиком операционной системы и ключами, отформатированный в Ext2. В статье рекомендуется сделать его приблизительно 50 Мб, и для загрузчика GRUB, ядра, хранения начальных настроек этого хватит. Я же сделал второй раздел побольше (1Гб) и перенес на него дополнительно Live дистрибутив Puppy Linux (чтоб в процессе настроек не грузиться с CD или другой флэшки).

Этап #3.
Установка загрузчика GRUB

Необходимо извлечь загрузочные флешки с которых ставили ОС, и/или с которых загружали Puppy Slacko, если таковые были использованы, и вставить нашу размеченную подготовленную загрузочную флешку.

Я воспользовался графической утилитой установки GRUB c LiveCD Puppy Slacko, доступ к которой можно получить из главного меню Puppy Slacko (оно по-умолчанию там же где и «Пуск» у Windows) «Система» — «Настройка загрузчика GRUB»
1. В первом диалоговом окне выбираем способ установки simple
2. Во втором предлагается выбрать разрешение экрана при загрузке, я выбрал standart, ибо для Slackware потом все равно необходимо перенастроить параметры разрешения экрана при загрузке в конфиге GRUB.
3. В следующем окне необходимо указать местоположение директории boot, это второй раздел нашей флешки, который у меня называется sdb2, соответственно указывается устройство /dev/sdb2
4. В следующем окне выбираем запись загрузчика в MBR
5. В следующем окне вводим устройство, в MBR которого будет записан загрузчик, в данном случае это наша флешка, которая обозначена как /dev/sdb (у меня)

Продолжение под катом

Поздравляю! Мы загрузились с помощью образа initrd до загрузки основной ОС.
Для продолжения загрузки надо ввести exit и нажать enter. Управление будет передано программе init из основной ОС и основная ОС загрузится.

Домашний сервер на базе Slackware Linux

Давно хотел собрать в кучу заметки про то, как можно организовать домашний сервер (или сервер для малого офиса) на базе Slackware Linux с VPN, I2P, Tor, файл-помойкой на локальном FTP, возможностью установки с сервера ПО и операционных систем, а возможно и с внутренними Web-сайтами, чатами и что там еще надо в зависимости от ваших задач. А еще и с полным шифрованием жесткого(-их) дисков.

Это пост-оглавление. Тут буду копить внутренние ссылки на заметки, относящиеся к организации сервера. Нумерация и последовательность также может меняться, т.к. я пишу как придется, а в содержании буду по мере накопления материала сортировать как надо.

Что примерно надо построить на начальном этапе. Сервер в локальной сети, позволяющий клиентам выходить в Интернет, как минимум через два различных IP (VPN и IP основного провайдера), поддерживающий локальный FTP и/или Samba (файловое хранилище), поддерживающий проходную ноду Tor и I2P-роутер, а также обеспечивающий локальным клиентам доcтуп в сети Tor и I2P.

Ремарка про железо. На самом деле, чем круче, тем круче, но изначально все делалось на старом Celeron с 500 Гб HDD и 512 Мб ОП, сейчас все вертится на Dual Core Intel Celeron E3200 (2400МГц) с гигабайтом встроенной памяти и встроенным видео, тоже не самая новая машина, но получше. А вообще хочу, чтоб оно на PIII-700 заработало. Сетевая карта одна (расскажу, как из одной реальной виртуальных наделать).

Оглавление

Установка Linux и шифрование жесткого диска:
Часть I Копия
Часть II Копия
Часть III Копия
Часть IV Копия
Пример конфига GRUB для загрузки сервера Копия
Эта часть целиком в PDF

Начальная настройка сети Копия
Network namespaces или несколько виртуальных сетевых карт (интерфейсов) с разными IP на одной машине. Копия
Настройка файерволла (IPTABLES) Копия

Локальный FTP Копия
Нода TOR Копия
Настройка доступа к I2P Копия
PXE (установка и запуск различных ОС со своего сервера на локальных машинах) Копия

Локальный прокси-сервер:
Запускающий скрипт Копия
Инструкция по установке Копия
Изменения в конфигурации последней версии Копия

Квест про панка Punk’s Not Dead V2.0

Нам, внезапно, прислали довольно милый квест про панка. Punk’s Not Dead V2.0, ажно 2005 года выпуска, написано на Flash, и, к сожалению, не дописано аффтарами, посему последний уровень, по сообщениям читателей, является непроходимым.

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

Сохранения тоже нет, при перезапуске игра начинается сначала, так что если кого вдруг попрет — играйте на виртуалке, там есть Save State.

Нате вам скриншотов из начала:



И ссылку на скачивание:
Скачать с Mega.nz

Как вручную распаковать пакет nuget.

И извлечь из него сборки (библиотеки).

Часто бывает, что нужная библиотека лежит на nuget.org. Если у вас современная Visual Studio, то проблем нет — инструментарий nuget доступен, во всяком случае, из командной строки. Можно установить nuget и отдельно, но что делать, если устанавливать ничего не хочется?

На самом деле пакет nuget (файл *.nuget) это обыкновенный ZIP-архив. Поэтому можно скачать пакет, переименовать его в *.zip и открыть любимым архиватором.

Например, нам нужен упомянутый в предыдущем посте HtmlAgilityPack, версии 1.11.15.

1. Переходим по ссылке https://www.nuget.org/packages/HtmlAgilityPack/1.11.15
2. Выбираем справа Download package
3. Сохраняем пакет
4. Меняем ему расширение на zip
5. Открываем любимым архиватором

В архиве в подкаталоге \lib находятся каталоги различных сборок:

Net20
Net35
Net40
Net40-client
Net45
NetCore45
netstandard1.3
netstandard1.6
netstandard2.0
portable-net45+netcore45+wp8+MonoAndroid+MonoTouch
portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch
uap10.0

C# Парсер HTML (под .NET Framework 2.0).

Понадобился тут для одного проекта все-таки полноценный парсер HTML, да еще желательно чтоб под не очень свежий .NET Framework 2.0. Ну не хочу я ради небольшого проекта жертвовать совместимостью да и переходить на новый .NET вообще, потому что в старом все прекрасно работает.

В общем выбирал-выбирал и остановился на HtmlAgilityPack, который в версии 1.11.15 поддерживает в т.ч. и .NET 2.0. Версия 1.11.16 .NET 2.0 уже не поддерживает, все остальное, начиная с .NET 3.5 есть.

Скачать можно через NuGet. Как быть тем, у кого NuGet нет читать здесь.

Прямая ссылка
Обсуждение на StackOwerflow

Держаться корней

Чуковский пишет Толстому:
«Лев, знал бы ты, как хочется вот так просто взять и нажраться! Набухаться в хлам, как Есенин. Или нанюхаться, как Маяковский!»
Толстой отвечает:
«Надо держаться, Корней!»

Настройка IPTables на сервере. Часть вторая, с поправками.

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

Товарищ [info]wasserstrahl@ljr внес поправку:

Открытие порта на исходящие соединения.

Ну чтоб с чем-то связаться по определенному порту.

iptables -A INPUT -p tcp —sport <# порта> -j ACCEPT
iptables -A OUTPUT -p tcp —dport <# порта> -j ACCEPT»

Нет.

iptables -A OUTPUT -p tcp —dport <# порта> -j ACCEPT» — это верно вроде,

а «iptables -A INPUT -p tcp —sport <# порта> -j ACCEPT» — нет. Потому что это правило позволяет любой входящий пакет с указанного порта с любого адреса. Если ты хочешь открыть ответы на исходящий трафик, то нужно писать что-то в стиле iptables -A INPUT -p tcp -m state —state RELATED,ESTABLISHED -j ACCEPT

Поправка верная, потому изменяем настройку IPTables в скрипте инициализации сервера.

Удаляем все правила файерволла:

# Delete all rules
echo "Delete firewall rules..."
iptables -F
iptables -F -t nat
iptables -F -t mangle
iptables -X
iptables -t nat -X
iptables -t mangle -X

Устанавливаем основную политику по умолчанию. Запретить все соединения (параноидальный режим):

# Drop all traffic
echo "Set main policy..."
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Разрешаем принимать все установленные входящие соединения. Это надо для того, что если мы откроем порт на исходящие соединения, для того, чтоб сервер мог с чем-то связываться (например с WWW или rsync), то ответ был бы принят.

#prinimat' vse ustanovlennye vhodashie soedineniya
echo "Accepts all established inbound connections..."
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Открываем порт для клиентов, которые подключаются к серверу по протоколу PPTP (входящий трафик):

#open VPN ports and GRE
echo "Open VPN ports and GRE..."
#to computer
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1723 -j ACCEPT

И разрешаем для них же протокол GRE:

iptables -A INPUT -p gre -j ACCEPT
iptables -A OUTPUT -p gre -j ACCEPT

Поскольку сам сервер не будет соединяться с VPN-провайдером по протоколу PPTP (есть OpenVPN), то следующие строки я убрал:

iptables -A INPUT -p tcp --sport 1723 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 1723 -j ACCEPT

Разрешаем весь трафик на loopback (lo) интерфейсе. Если у нас будут сервисы, такие как Web-сервер и сервер баз данных MySQL на одном сервере, то связываться они будут как раз через lo-интерфейс.

#accept all traffic an lo interface
echo "Accept all lo interface traffic..."
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Открываем на вход 22 порт (ssh) для клиентов, которые подключатся к серверу через PPTP VPN:

# ssh (22 port)
echo "Open 22 port (ssh) for VPN clients..."
iptables -A INPUT -s 172.16.1.0/24 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 172.16.1.0/24 -p tcp --sport 22 -j ACCEPT

Так же разрешаем им доступ к удаленному рабочему столу (XDMCP):

# XDMCP
echo "Open 177 port UDP (XDMCP) for VPN clients..."
iptables -A INPUT -s 172.16.1.0/24 -p udp --dport 177 -j ACCEPT
iptables -A OUTPUT -s 172.16.1.0/24 -p udp --sport 177 -j ACCEPT

echo "Open 6000:6005 ports (Windows XDMCP) in both directions for VPN clients..."
iptables -A INPUT -s 172.16.1.0/24 -p tcp -m multiport --dports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s 172.16.1.0/24 -p tcp -m multiport --sports 6000:6005 -j ACCEPT

iptables -A INPUT -s 172.16.1.0/24 -p tcp -m multiport --sports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s 172.16.1.0/24 -p tcp -m multiport --dports 6000:6005 -j ACCEPT

Разрешаем VPN-клиентам доступ к DNS:

echo "Open DNS for VPN clients..."
iptables -A INPUT -s 172.16.1.0/24 -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -s 172.16.1.0/24 -p udp --sport 53 -j ACCEPT

iptables -A INPUT -s 172.16.1.0/24 -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -s 172.16.1.0/24 -p tcp --sport 53 -j ACCEPT

Разрешаем протокол ICMP (ping):

# Allow ICMP
echo "Allow ICMP and ports for TRACEROUTE..."
iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT

И исходящие порты для TRACEROUTE (ответы, входящий трафик уже разрешен командой iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT):

#open ports from traceroute
iptables -A OUTPUT -p udp -m multiport --dports 33434:33534 -j ACCEPT

Открываем стандартные порты (HTTP, HTTPS, email, rsync) для доступа к соответствующим сервисам с сервера (входящие):

#Open standart ports (from computer)
echo "Open standart ports (DNS,WWW, email) from server"
# 53-DNS,80 8080/tcp - WWW, 443/tcp - https, 110,443,25,587 - e-mail 873/tcp - rsync (for sbopkg)
iptables -A OUTPUT -p udp -m multiport --dports 53,443 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --dports 53,80,8080,443,110,443,25,587,873 -j ACCEPT

Запускаем PPTP VPN сервер (к его настройке вернусь несколько позже):

#start VPN server
echo "Starting PPTD VPN server..."
pptpd &

Производим окончательную настройку файервола для PPTP VPN клиентов:
1. Организуем NAT (маскарадинг):

echo "Final firewall settings for VPN clients..."
#NAT for VPN clients
iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE

И немного подправляем пакеты (без этого виснут некоторые соединения). Буду благодарен, если мне кто-нибудь объяснит почему, но кстати, в Ростелекомовском файерволе такая настройка не установлена, потому это плохой провайдер, и их VPN висючий. В свое время задолбался с этим глюком.

#popravlaem pakety (bez etogo visnut nekotorye soedinenia)
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Скрипт целиком на PasteBin

Источники к сожалению пролюбил.

tinyproxy свалился после обновления

Черт меня дернул обновить tinyproxy, о настройке которого я писал здесь копия

Свалился вот с такой ошибкой:

"Bind" cannot be used with transparent support enabled.
Syntax error on line 37
Unable to parse config file. Not starting.
Not starting (code 70)

Хотя никакое прозрачное проксирование я не включал.

Решилось тем, что строку 37:

Bind <адрес_сервера>

я просто закомментировал. После этого он штатно заработал.

Правда, нифига понять не могу, с чего это вдруг он так странно упал. В прошлой версии все работало, и вроде команда Bind правильная, нужная и на месте.

C#, проверить, открыта ли форма.

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

Например, такой код при нажатии на кнопку создаст столько форм frmChild, сколько раз кнопка будет нажата:

private void btnOpenForm_Click(object sender, EventArgs e)
{
    frmChild fChild = new frmChild();
    fChild.Show();
}

Конечно, можно сделать форму модальной, с помощью fChild.ShowDialog(), тогда мы не будем иметь доступа к первой форме, пока вторая не закроется. Но если это не нужно, например, мы хотим свободно переключаться между двумя формами, но вторую создать только один раз.

Открытые формы содержатся в Application.OpenForms. И фактически, надо просто перебрать этот массив, чтобы посмотреть, открыта или нет форма, например по ее имени:

foreach (Form f in Application.OpenForms)
    {
        if (f.Name == "frmChild")
        {
            lblFormOpened.Text = "Form #2 already opened!";
            return;
        }
    }

Код обработчика нажатия кнопки целиком:

private void btnOpenForm_Click(object sender, EventArgs e)
{
    lblFormOpened.Text = "";
    
    foreach (Form f in Application.OpenForms)
    {
        if (f.Name == "frmChild")
        {
            lblFormOpened.Text = "Form #2 already opened!";
            return;
        }
    }
    frmChild fChild = new frmChild();
    fChild.Show();
}

Источник
Код примера на GitHub

Электроника MK-45

Принесли вот такую няшечку, и оставили на наше попечение.
После замены конденсатора в блоке питания заработал. Показывает факториал из числа 666:

Шильдик:

Да, стоил достаточно дорого, две зарплаты продавца в магазине, или техника на метеостанции. Если примерно советский рубль по покупательной способности считать за евро (а примерно так и выходит), то на наши деньги 125 евро или 9000 путинских рублей. С учетом отсутствия в СССР кредитов, купить его мог профессор или какая-нибудь контора. Минус нашего прибора — даже после чистки клавиш, они все равно периодически залипают, потому подробного видеообзора не будет.
Зато нам едет настоящий программируемый МК, который мог даже в игры — доедет, на него будет полновесный обзор с видео.

Питается от 220 вольт, дисплей вакуумно-люминисцентный (т.е. вместо жидких кристаллов внутри у него хитросделанная вакуумная лампа).

Задняя часть

Микрокалькулятор «Электроника МК-45» является настольным вариантом калькулятора «Электроника МК-36». В настольном варианте не используется клавиша совмещения функций «F», а все функции вынесены в отдельные блоки клавиш. Калькулятор производился с 1983 года на заводах «Эльтав» в Дагестане и на заводе «Электронприбор» в городе Фрязино Московской области и продавался по цене 85 рублей.
Дизайн корпуса калькулятора повторяет модель «Электроника МК-44», однако количество клавиш позволяет легко различить эти модели.
Результат вычисления отображается на четырнадцатиразрядном вакуумно-люминесцентном индикаторе, при этом два разряда[SP1] никак не используются. Это было сделано специально ради экономии, чтобы не изготавливать новую модель индикатора, а использовать уже выпущенную и проверенную.

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

Питание калькулятора осуществляется от сети переменного тока 220 В.

Габаритные размеры — 241✕185✕77 мм.
Вес не более 1,0 кг.

Описание с elektronika.su

Настройка IPTABLES

На самом деле, жутко не люблю настраивать IPTables, поскольку синтаксис у него несколько инопланетный. Дома и на работе я как-то настроил один раз лет 10 назад и благополучно все забыл. Теперь вот приходится мучительно вспоминать: «Чем ты это делал? Ну вот этой вот мясорубкой.».

Настройки обновлены, старые под катом

Вроде все правильно, но стойкое ощущение, что где-то накосячил. Кто больше шарит в IPTABLES, приму все комментарии по поводу данной темы.

Природо-интернетозащитная песня про Ёлочку

В лесу родилась ёлочка,
В лесу она росла.
Зимой и летом стройная,
Зеленая была.

Метель ей пела песенку:
«Спи, ёлочка, бай-бай!»
А сисадмин на ёлочку
Прикручивал вай-фай

Трусишка зайка серенький
И Леший с Водяным
Собралися под елочкой
С планшетом дорогим.

А кто и с ноутбуками
Под елочку пришел
Здесь нет Роскомнадзора, ведь
Халавный ВэПэЭн!

Везёт лошадка дровенки,
На дровнях — мужичок
А шел бы ты отсюда нах
От ёлки петушок.

И вот уже его бошка
На елочке висит
И наш Darknet Мизулина
Никак, бля, не сломит.

Аццкий погодный информер.

Не, он и правда настолько аццкий и быдлокод, что я всем его даже не покажу. Редкий случай, когда мне почти стыдно. Там все, и наглое выдирание данных прямо из HTML, и стукнутое преобразование их в таблицу, CSV, а потом и DataSet, для дальнейшего анализа, и прочее, и прочее. Если дизайнер изменит сайт, с которого берется погода, то оно работать не будет, и не факт, что я буду это переделывать.

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

Единственное, что в нем действительно мне нравится — иконка в трее, отображающая последнюю температуру с заданной метеостанции.

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

C# Всплывающая форма над областью уведомлений, делаем сами.

Продолжаем разговор о своем окне, всплывающем возле области уведомлений, там где NotifyIcon. Как в тех же мессенджерах при появлении нового сообщения.

На самом деле все оказывается довольно просто, и даже Ктулху вызывать пользоваться WinAPI не надо.

На первом этапе моделируем будущую всплывающую форму. Я, например, создал форму без границ (FormBorderStyle = none), поместил на нее TextBox, который будет отображать сообщение и PictureBox, который будет работать в качестве кнопки закрытия формы.

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

1. Заводим переменные, сохраняющие позиции формы:

private int StartPosX; private int StartPosY;

Ну я еще добавил переменную для сообщения и экспортировал функцию WinAPI, прячущую текстовый курсор:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool HideCaret(IntPtr hWnd);
public string MessageText = "";

Плюс настроил в инициализации формы некоторые ее параметры:

public frmPopup()
{
    InitializeComponent();
    //Настройка формы
    this.TopMost = false;
    this.ShowInTaskbar = false;
}

TopMost = false нужен, чтоб форма всплывала из-за области уведомлений, а не загораживала ее собой.

2. Переопределяем обработчик события Load и в нем прячем форму за экран:

protected override void OnLoad(EventArgs e)
{
    //Прячем форму за экран
    StartPosX = Screen.PrimaryScreen.WorkingArea.Width - this.Width;
    StartPosY = Screen.PrimaryScreen.WorkingArea.Height;
    SetDesktopLocation(StartPosX, StartPosY);
    base.OnLoad(e);
    //запуск анимации всплытия
    tmrAni.Interval = 50;
    tmrAni.Start();

}

Туда же можно вставить запуск таймера, который будет анимировать всплытие формы (после base.OnLoad(e)).

Если просто вставить этот код в обработчик события Load, то форма на секунду появится на экране, и будет некрасиво.

3. Далее в обработчиках событий Load и Shown настраиваем нашу форму, например, присваиваем TextBox нужный текст и т.д.

private void frmPopup_Load(object sender, EventArgs e)
{
    //настраиваем TextBox с сообщением
    txtMessage.Height = this.Height - txtMessage.Location.Y - 3;
    txtMessage.Width = this.Width - txtMessage.Location.X - 3;
    txtMessage.BorderStyle = BorderStyle.None;
    txtMessage.BackColor = this.BackColor;
    txtMessage.Text = MessageText;
    txtMessage.ReadOnly = true;
    txtMessage.SelectionStart = 0;

    //и кнопку закрытия
    int CloseX = this.Width - pbClose.Width - 3;
    int CloseY = 3;
    pbClose.Location = new Point(CloseX, CloseY);
}

private void frmPopup_Shown(object sender, EventArgs e)
{
    HideCaret(txtMessage.Handle);
}

3. При каждом срабатывании таймера поднимаем форму на 5 пикселей, а когда форма покажется полностью, то останавливаем таймер и делаем ее «поверх всех окон» (TopMost = true;):

private void tmrAni_Tick(object sender, EventArgs e)
{
    //поднимаем форму на 5 пикселей
    StartPosY -= 5;

    //Если окно видно полностью - останавливаем таймер
    if (StartPosY < Screen.PrimaryScreen.WorkingArea.Height - Height)
    {
        tmrAni.Stop();
        this.TopMost = true;
    }
    else
    {
        SetDesktopLocation(StartPosX, StartPosY);
    }
}

Вот, что получилось:

Код примера целиком

На GitHub

C# Всплывающая форма над областью уведомлений, над NotifyIcon

Спрашивают, как можно сделать всплывающую форму над областью уведомлений, там где «часики» и иконки запущенных в фоне программ. Ну типа как это делается в мессенджерах при получении нового сообщения.

Вот, нашел вам готовый код. Выглядит вполне симпатично.

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

Потом расскажу, как самому сделать что-то подобное, пусть и не такое симпатичное.

Исходный код

У автора
У меня

Фразочка

Выбросил в фукуяму.

Блин, жалко Лейбов свой генератор заголовков не поддерживает, неплохо бы смотрелось что-то типа: «В ходе зачистки аула Херсов-Мурда лидер Антимиайдана Залдостанов выбросил в фукуяму народного мэра Луганска»