feat: add tray control, priority restoration and session logging

This commit is contained in:
lzrdblzzrd committed 2026-10-04 19:00:59 +03:00
1 parent 4f8f6218ad
commit 4880aa46dc
25 files changed
+3072 -676

No files matched your search

+92 -87
View File
@@ -1,106 +1,111 @@
# autoPriority
Отслеживает использование памяти процессами в Windows и автоматически управляет их приоритетом: ресурсоемким процессам назначает HIGH, а менее ресурсоемким снижает приоритет до NORMAL, только если он был выше. При превышении повышенного порога может включать **игровой режим**, назначая обнаруженному процессу HIGH, а всем остальным — IDLE.
Windows-утилита для управления приоритетами процессов по расходу оперативной памяти. Работает из одного EXE, без установки и службы.
**Только для Windows.**
## Запуск и выход
## Принцип работы
Запустите `autoPriority.exe`. Первая проверка процессов выполняется при запуске, последующие — через заданный интервал, по умолчанию раз в минуту.
### Обычный режим
Значок в трее открывает меню с пунктом **«Выход»** по левой, правой, средней или дополнительной кнопке мыши. Меню доступно и с клавиатуры. При выходе программа останавливает проверки, восстанавливает доступные для восстановления приоритеты и убирает значок. Консольная сборка также поддерживает Ctrl+C.
Через заданный интервал программа проверяет все запущенные процессы:
В одном сеансе Windows работает один экземпляр. Повторный запуск завершается, не затрагивая работающий экземпляр и его журнал. Программа не настраивает автозапуск и не запрашивает повышение прав.
| RSS относительно `-mem` | Текущий приоритет | Действие |
## Как назначаются приоритеты
Порог памяти применяется к рабочему набору процесса (RSS).
| Режим и условие | Приоритет |
|---|---|
| Обычный режим: RSS не меньше `-mem` | HIGH |
| Обычный режим: RSS меньше `-mem`, текущий приоритет выше NORMAL | NORMAL |
| Обычный режим: RSS меньше `-mem`, текущий приоритет NORMAL, BELOW_NORMAL или IDLE | Без изменения |
| Игровой режим: процесс достиг `-game-mem` | HIGH |
| Игровой режим: остальные процессы | IDLE |
**Игровой режим не распознаёт игры.** Его может включить любой процесс, достигший `-game-mem`, в том числе браузер. Такой процесс остаётся участником режима до завершения, даже если расход памяти уменьшился. Если участников несколько, режим заканчивается после выхода последнего.
После окончания игрового режима программа снимает временное понижение и применяет обычные правила. При штатном выходе самой autoPriority она восстанавливает собственные изменения, включая повышения вне игрового режима. Замеченное внешнее изменение приоритета становится новой исходной точкой.
## Параметры
| Флаг | По умолчанию | Описание |
|---|---|---|
| ≥ порога | любой, кроме HIGH | → HIGH (запись `PROMOTE` в журнале) |
| ≥ порога | уже HIGH | пропустить |
| < порога | ABOVE_NORMAL, HIGH или REALTIME | → NORMAL (запись `DEMOTE` в журнале) |
| < порога | NORMAL, BELOW_NORMAL или IDLE | пропустить |
| `-mem` | `512M` | Обычный порог памяти: положительное целое число с необязательным суффиксом K/M/G |
| `-game-mem` | `2G` | Порог игрового режима: больше `-mem`; `0` отключает режим |
| `-interval` | `1m` | Интервал проверок; значения меньше 10 секунд ограничиваются 10 секундами |
| `-dry-run` | `false` | Запись предполагаемых изменений в журнал без изменения приоритетов |
### Игровой режим (`-game-mem`)
Когда любой процесс достигает или превышает порог `-game-mem`:
1. Этому процессу назначается **HIGH** (запись `GAME` в журнале).
2. Всем остальным процессам назначается **IDLE** с сохранением исходных приоритетов.
3. В журнал добавляется запись `GAME MODE ON`.
Когда все такие процессы завершаются:
1. Всем процессам, приоритет которых был снижен в игровом режиме, **возвращается исходный приоритет** (запись `RESTORE` в журнале).
2. В журнал добавляется запись `GAME MODE OFF`.
3. Возобновляется обычный режим, и приоритеты пересчитываются по правилам `-mem`.
Если изменить приоритет процесса невозможно, например из-за античита или системных ограничений, процесс добавляется во внутренний список исключений и больше не изменяется (запись `BLOCK` в журнале). Его RSS продолжает измеряться, поэтому он может включить игровой режим. Процессы, память которых прочитать не удалось, пропускаются до следующей проверки.
При штатном завершении программа несколько раз пытается восстановить приоритеты всех процессов, измененных в игровом режиме. Если Windows отклоняет восстановление, в журнал записывается предупреждение.
В одном сеансе Windows может работать только один экземпляр программы. Второй экземпляр завершается, не прерывая работу первого.
## Сборка
Требуется Go 1.26 или новее.
```
# Обычная сборка с окном консоли
go build -o autopriority.exe .
# Фоновая сборка без консоли, минимальный размер
go build -trimpath -buildvcs=false -gcflags="all=-l" -ldflags="-H=windowsgui -s -w -buildid=" -o autopriority.exe .
```
## Использование
```
autopriority [flags]
```
| Флаг | Значение по умолчанию | Описание |
|-------------|---------------|----------------------------------|
| `-mem` | 512M | Порог памяти, например 512M, 1G или 2048M |
| `-game-mem` | 2G | Порог игрового режима, например 2G или 4G. Должен быть больше `-mem`. 0 отключает режим |
| `-interval` | 1 минута | Интервал проверки, минимум 10 секунд |
| `-dry-run` | false | Только записывать решения в журнал, не менять приоритеты |
Примеры:
```
# Порог 1 ГБ, проверка каждые 30 секунд
autopriority -mem=1G -interval=30s
# Запуск со значениями по умолчанию: порог 512M, игровой порог 2G
autopriority
# Обычный порог 512M, игровой порог 4G
autopriority -mem=512M -game-mem=4G
# Пробный запуск: записывать решения, ничего не изменяя
autopriority -dry-run
```text
autoPriority.exe
autoPriority.exe -mem=1G -game-mem=4G -interval=30s
autoPriority.exe -game-mem=0
autoPriority.exe -dry-run
```
## Журнал
Журнал всегда записывается в `%TEMP%\autopriority.log`. При каждом запуске создается новый файл, а предыдущий удаляется.
Файл журнала находится во временной папке Windows: **`%TEMP%\autopriority.log`**. Путь определяется через `os.TempDir`.
Типы записей:
При каждом запуске журнал очищается, архив предыдущей сессии удаляется. В текущей сессии сохраняются основной файл и один архив `autopriority.log.1`, каждый размером до 4 МиБ. Слишком длинная запись сокращается с отметкой.
| Префикс | Значение |
|---|---|
| `PROMOTE` | Приоритет повышен до HIGH в обычном режиме |
| `DEMOTE` | Приоритет снижен до NORMAL в обычном режиме |
| `GAME DETECT` | Впервые обнаружен процесс, превысивший порог `-game-mem` |
| `GAME` | Процессу назначен HIGH или IDLE в игровом режиме |
| `GAME MODE ON` | Игровой режим включен |
| `GAME MODE OFF` | Игровой режим выключен, приоритеты восстановлены |
| `BLOCK` | Ошибка OpenProcess или SetPriorityClass, процесс добавлен в список исключений |
| `SKIP` | Не удалось прочитать сведения о процессе, попытка повторится при следующей проверке |
| `RESTORE` | Восстановлен исходный приоритет при выходе из игрового режима или завершении программы |
| `[DRY-RUN]` | Приоритет был бы изменен в пробном режиме |
Изменения выводятся ASCII-таблицей:
## Автозапуск
```text
Процесс | PID | Память | Повышено | Понижено
```
Нажмите **Win+R**, введите `shell:startup` и нажмите Enter. Поместите ярлык `autopriority.exe` в открывшуюся папку.
При включении игрового режима его участники идут первыми, фоновые процессы — ниже. Уже установленный HIGH отмечается как «уже HIGH». Если изменить приоритет участника не удалось, его строка содержит отметку «в блоклисте».
## Зависимости
Ошибки выводятся отдельным блоком «ОШИБКИ»:
Отсутствуют. Программа напрямую вызывает Windows API (`kernel32`, `psapi`) через syscall.
```text
Процесс | PID | Описание ошибки
```
Под таблицей нет дублирующих сообщений. Режим `-dry-run` явно помечает записи как план. При ошибке записи журнала программа завершает работу с попыткой восстановления приоритетов.
## Блоклист
После ошибки чтения или изменения приоритета процесс попадает в блоклист. Повторных попыток для него нет, в том числе при выходе; остальные процессы обрабатываются независимо. Блоклист хранится в памяти и очищается при перезапуске autoPriority.
Если время создания доступно, блокировка привязана к PID и времени создания. Другой экземпляр с тем же PID обрабатывается отдельно. Если Windows запрещает даже чтение процесса, запись снимается при исчезновении PID из снимка либо смене имени или родителя. Замену недоступного процесса другим с тем же PID, именем и родителем между двумя снимками надёжно различить нельзя.
Процесс, доступный для чтения, но недоступный для изменения, может включать игровой режим по расходу памяти.
## Ограничения
- Восстановление незаблокированного процесса выполняется один раз. Если Windows отказывает в доступе, программа сообщает о невосстановленных приоритетах.
- Принудительное завершение, сбой ОС или отключение питания не позволяют гарантировать восстановление.
- Между чтением и записью приоритета другая программа может изменить его значение.
- Наследованный дочерними процессами IDLE определяется по родству и времени создания. Это эвристика: она может затронуть явно заданный ребёнку IDLE и не обнаружить цепочку, если родитель завершился между проверками.
- Программа не обходит защиту процессов, не включает SeDebugPrivilege и не гарантирует совместимость с античитом или прирост FPS.
## Сборка и проверки
Для сборки нужны Windows и Go 1.26 или новее. Сторонние Go-модули и CGO не требуются.
```text
go build -trimpath -buildvcs=false -ldflags="-H=windowsgui -s -w -buildid=" -o autoPriority.exe .
go test ./...
go vet ./...
```
Для консольной сборки уберите `-H=windowsgui`.
Обычные тесты используют синтетические процессы. Нативные проверки включаются переменными окружения:
- `AP_NATIVE_PROCESSES=1`: проверка Windows API только на специально созданных дочерних процессах.
- `AP_NATIVE_GUI=1`: проверка собственного значка и меню трея; может кратко переключить фокус.
Нативные тесты не запускают системный сканер программы. Запускайте их вне защищённой игры.
## Иконки
Программа использует `chart_bar_edit` для трея и `cross` для пункта «Выход». PNG встроены в EXE.
Silk 1.3, **Mark James**, Creative Commons Attribution 2.5.
- Автор: http://www.famfamfam.com/lab/icons/silk/
- Источник: https://github.com/legacy-icons/famfamfam-silk
- Ревизия: `d6056f5c28e46c28403888ab7c013aced3928ec8`.
- Лицензия и контрольные суммы: `assets/SILK-LICENSE.md`, `assets/SILK-SOURCE.json`.