feat: add tray control, priority restoration and session logging
This commit is contained in:
1 parent
4f8f6218ad
commit
4880aa46dc
25 files changed
+3072
-676
No files matched your search
@@ -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`.
|
||||
Reference in new issue
Block a user