Я портировала знаменитую утилиту Fetch на ReactOS
Если вы думаете, что я сделала качественный фотошоп, то я демонстрирую полноценный скриншот:
Это мой первый опыт в программировании. И в качестве первого опыта я выбрала не Hello World, а перенос популярной утилиты на ReactOS с использованием языка Си. Я никогда не программировала.
Зачем я переносила утилиту Fetch на ReactOS?
Как я писала выше, я никогда не умела программировать. Внезапно мне пришла идея научится программированию. Простые примеры меня не интересовали, но что-то супер-сложное на Python или Lua я бы не смогла сделать. К задаче (которая является темой статьи на Хабре) я обнаружила один факт.
Я думаю, что утилиты neofetch, fastfetch и screenfetch на Хабре все в курсе. На дистрибутивах Linux Fetch-подобные утилиты обрели сумасшедшую популярность. Каждый второй или третий пост в Reddit в разделе UnixPorn демонстрирует информацию о своей системе на Fetch.
На современных Windows 10 и Windows 11 есть нативная версия утилиты neofetch. Про Linux, MacOS, chromeOS, freeBSD и остальные UNIX-системы и не стоит говорить. Где вы возможно не ожидали увидеть Fetch-подобной утилиты - это DOS:
И KolibriOS:
Я обнаружила, что Fetch-подобной утилиты нет на ReactOS. На старые Windows (вплоть до Windows 8.1) есть разные порты Fetch-подобной утилиты, но они на ReactOS не работают. Поэтому я решила сделать Fetch-подобную утилиту для ReactOS на языке Си. Язык Си выбран неслучайно - так как я расчитывала, что мою работу по портированию Fetch-подобной утилиты на ReactOS добавят в систему-сабж.
AI make only FAIl
Изначально я хотела (в качестве эксперимента) использовать ИИ-чатботы для написания утилиты для ReactOS. Я использовала разные ИИ-чатботы: ChatGPT, Гигачат и ЯндексГПТ.
Сначала я использовала ГигаЧат и AlisaGPT, от Сбер и Яндекс соответственно. Оба вышеуказанных ИИ-чатбота написали нерабочий код, который явно не имеет отношения к ReactOS и KolibriOS. ГигаЧат и AlisaGPT использованы мной для написания программ и для KolibriOS - и тут FAIL. Поэтому после первой попытки я перестала их использовать в программировании.
В начале эксперимента я считала ChatGPT лучшим ИИ для программирования. Потому что я смотрела видео ютубера DepoSit, ChatGPT написал код, который скачивает все карты из мастерской CS:GO. То, что он задумал, явно уровнем выше HelloWorld. Вот его видео:
Это был конец 2023 года. Код от ChatGPT успешно скачал все карты из мастерской CS:GO. Спасибо ютуберу DepoSit, что сделал вышеуказанное. Потому что Valve потихоньку удаляют карты CS:GO из мастерской стима. К счастью, он выложил архив. Этот оффтоп объясняет, почему я считала ChatGPT лучшим ИИ для кодинга.
Но и с ChatGPT что-то пошло не так. Код, который написал ChatGPT, не что не собирается в ReactOS, он не запускался. Плюс ChatGPT написал непонятную тягомотину. Вначале ЧатГПТ писал код как часть командной строки ReactOS. Потом он писал код как отдельную консольную утилиту. ChatGPT провалил задачу, которую я ему задала.
Забегая на раздел статьи вперёд, стоит сказать, что код я написала самостоятельно и он работает на ReactOS и Windows XP (я не проверяла - однако если на ReactOS без проблем работает, то и на Windows XP точно работает).
Нужно как-то адаптировать для сборки в ReactOS. Для сборки из исходного кода я использовала DeepSeek и ChatGPT. Оба ИИ-чатбота не справились со своей задачей. Сначала утилита Fetch не собиралась. Потому утилита собиралась успешно, но при попытке запуска происходила ошибка что на ReactOS, что на Windows 10 (основная ОС на моём компьютере).
Я разочарована в ИИ для написания кода. Теперь понятно, почему среди разработчиков ReactOS ИИ по типу ChatGPT не стал популярен.
Как я кодила?
Так как я не умею программировать, то для того чтобы понять кодинг - я зашла на сайт Метанит. Потому что Метанит даёт базовые знания про язык Си, при этом не надо пиратить книги про программирования (я не сторонница лицензий если что). Какую-то базу я освоила.
Многие Windows-приложения без проблем работают на ReactOS. Одно из них - IDE Code:Blocks. Данное IDE настолько хорошо и без проблем работает в ReactOS, что доступен для скачивания в RAPPS (пакетный менеджер приложений ReactOS). Именно это IDE я и использовала.
Ещё одна важная причина почему я использовала Code::Blocks - это тот факт, что в комплекте Code::Blocks из коробки есть компилятор MinGW. MinGW - это порт компилятора GNU GCC, который компилирует как минимум половину линукса и UNIX. MinGW используется для компиляции и сборки ReacOS из исходного кода.
Так работоспособность ReactOS на реальных компьютерах плохая, то я использовала эмулятор. В данном случае виртуальная машина VirtualBox 7.0. У VirtualBox самый низкий порог входа, потому что: VirtualBox - простой и VirtualBox освоит любая девушка (как я), в отличии от QEMU.
Весь код, который я писала, он в одном единственном файле. Все используемые в коде .h-файлы - это стандартные файлы из компилятора. Скажу проще: я не использовала никаких внешних/дополнительных .h или .c-файлов, весь функциональный код написан в одном файле.
Возможно кто-то спросит, зачем я использовала устаревший GlobalMemoryStatus вместо современного GlobalMemoryStatusEx. Дело в том, что ReactOS пытается быть "заменой" Windows XP. Функция GlobalMemoryStatusEx не работает в Windows XP. Да и к тому же, ReactOS до сих пор не умеет полноценно, без багов и без ошибок работать на старых 32-битных компьютерах. На современных 64-битных ПК ReactOS не будет работать никак. Поэтому я использовала функцию GlobalMemoryStatus.
ASCII-логотип
Сделать ASCII-логотип ReactOS для меня оказалось не менее сложной задачей, чем кодить что-то новое на языке Си. Одним из условием было ограничение на длину в 24 символа. Я использовала разные сайты, генерирующие ASCII-арты. Было несколько попыток. И только спустя несколько несколько попыток и несколько сайтов получился более менее смотрибельный вариант:
Я выбрала синий цвет, так официальный логотип ReactOS так или иначе использует синий цвет. Красный и зелёный для ASCII-арта логотипа не подходят на мой взгляд. Ещё в командной строке ReactOS (читайте Windows XP) есть ограничения на цвета. Поэтому светло-синий цвет.
Исходный код
Так как весь функциональный и работающий код написан в одном файле, а выкладывать на GitHub мне не хочется - то я могу смело выложить код на статью Хабра.
Вот исходный код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <cpuid.h>
#include <tchar.h>
const char *Logo[9];
void ros_logo(){
Logo[0]=" $$ $$ $$$ $$$ $$ $$ ";
Logo[1]=" $ $$$$$$$$$ $ ";
Logo[2]=" $$ $$$$$$$$$$$$$$$ $$ ";
Logo[3]=" $$$$$$$$$$$$$$$$$$$$$ ";
Logo[4]=" $ $$$$$$$$$$$$$ $ ";
Logo[5]=" $$$$ $$$$$$$$$ $$$$ ";
Logo[6]="$ $$$$ $$$$$$$ $$$$ $";
Logo[7]="$ $$$$$ $$$ $$$$$ $";
Logo[8]="$ $$ $ $$ $";
Logo[9]=" $$ $ $$ $$ $ $$ ";
}
void kernelver()
{
DWORD dwVersion = 0;
DWORD dwMajorVersion = 0;
DWORD dwMinorVersion = 0;
DWORD dwBuild = 0;
dwVersion = GetVersion();
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
if (dwVersion < 0x80000000)
dwBuild = (DWORD)(HIWORD(dwVersion));
printf("Kernel: %d.%d (%d)\n",
dwMajorVersion,
dwMinorVersion,
dwBuild);
}
void uptime(){
DWORD ticks = GetTickCount();
DWORD milliseconds = ticks % 1000;
ticks /= 1000;
DWORD seconds = ticks % 60;
ticks /= 60;
DWORD minutes = ticks % 60;
ticks /= 60;
DWORD hours = ticks; // may exceed 24 hours.
printf("Uptime: %d hours, %02d minutes, %02d seconds\n", hours, minutes, seconds);
}
void screen(){
DWORD xsize = GetSystemMetrics(SM_CXSCREEN);
DWORD ysize = GetSystemMetrics(SM_CYSCREEN);
printf("Resolution: %dx%02d\n", xsize, ysize);
}
void get_cpuid(int code, unsigned int* a, unsigned int* b, unsigned int* c, unsigned int* d) {
__asm__ __volatile__ (
"cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
: "a" (code)
);
}
void ram(){
MEMORYSTATUS statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatus(&statex);
DWORD totalPhys = statex.dwTotalPhys;
DWORD usedPhys = statex.dwTotalPhys - statex.dwAvailPhys;
printf("RAM: %.2f Mb /", (double)usedPhys / (1024 * 1024));
printf(" %.2f Mb ", (double)totalPhys / (1024 * 1024));
printf("(%lu%%)\n", statex.dwMemoryLoad);
}
void main(){
int i;
ros_logo();
for (i=0; i<=sizeof(Logo)/sizeof(Logo[0]); i++)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
printf(Logo[i]);
if (i>=0 && i<=5)
{
printf(" ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}
if (i==0)
{
printf("OS: ReactOS\n");
}
if (i==1)
{
kernelver();
}
if (i==2)
{
uptime();
}
if (i==3)
{
screen();
}
if (i==4)
{
unsigned int a, b, c, d;
char cpu_brand[49] = {0};
get_cpuid(0x80000000, &a, &b, &c, &d);
if (a >= 0x80000004) {
unsigned int* brand = (unsigned int*)cpu_brand;
get_cpuid(0x80000002, &brand[0], &brand[1], &brand[2], &brand[3]);
get_cpuid(0x80000003, &brand[4], &brand[5], &brand[6], &brand[7]);
get_cpuid(0x80000004, &brand[8], &brand[9], &brand[10], &brand[11]);
}
printf("CPU: %s\n", cpu_brand);
}
if (i==5)
{
ram();
}
if (i>5)
{
printf("\n");
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}
}
Итоги
Исходный код работает на ReactOS. Свою задачу, которую я поставила себе, я выполнила. Надеюсь, что утилиту Fetch, которую я портировала, добавят в ReactOS. Это мой первый опыт в кодинге, при чём интересный опыт. Мой эксперимент по программированию оказался удачным.
Я желаю, чтобы ReactOS стал юзабельным на всех компьютерах. Я желаю, чтобы на ReactOS без проблем и багов работали все Windows-приложения и игры. Короче, я желаю удачи ReactOS.