Compare commits

..
120 Commits
Author SHA1 Message Date
Mikhail Tergoev e76f49a3bd update wine-11.0-alt-tflex-wow64 with fix name 2026-07-01 17:14:26 +03:00
Mikhail Tergoev 0ed10c72f9 Merge branch 'minergenon-fix-gui' 2026-07-01 15:18:12 +03:00
Mikhail Tergoev 34849c9490 Merge branch 'minergenon-auto-completion' 2026-07-01 15:17:09 +03:00
Mikhail Tergoev ebabc7ebf7 t-flex: update wine to wine-11.0-alt-tflex-wow64 2026-07-01 15:03:35 +03:00
Sergey Palcheh 726f2f4b43 refactor(gui): deduplicate PyQt code and extract shared utilities 2026-06-30 10:16:25 +06:00
Sergey Palcheh 8a94f519a3 fix(gui): eliminated clumping and duplication of lines in the command log 2026-06-29 18:16:58 +06:00
Sergey Palcheh 468ea73aa6 fix(gui): fixed multiple duplication of prefix parameters 2026-06-29 14:00:11 +06:00
Sergey Palcheh a860cacf2c refactor(gui): add script and installation management services
- add ScriptManager for flat script structure support

- add ApplicationInstaller and InstallationManager

- refactor ProcessHandler for safer subprocess handling

- improve script, sha256 and winetricks parsers

- update version selection dialog and icon manager
2026-06-26 16:51:00 +06:00
Sergey Palcheh 416c4e5336 refactor(gui): add desktop entry and settings management
- add DesktopEntry reader/writer with section and escape support

- refactor DesktopFileManager to use DesktopEntry

- add SettingsManager for prefix and application settings

- update settings and prefix dialogs to use new managers
2026-06-26 16:50:47 +06:00
Sergey Palcheh 48f694322a fix(gui): security hardening and stability fixes
- pass CLI arguments as list instead of string to prevent injection

- validate .whdb and .whpack paths inside USER_WORK_PATH

- create cache files with 0o600 permissions

- restrict prefix names to alphanumeric, dash and underscore

- remove QApplication.processEvents() calls

- atomic single-instance check via QLocalServer

- guard against deleted QObject/QProcess before deleteLater()

- queue async winetricks installations
2026-06-26 16:50:33 +06:00
Sergey Palcheh b58d768ca6 added auto-completion commands for bash and zsh 2026-06-26 11:32:55 +06:00
Mikhail Tergoev 28062ff5bb use noexec_warning dialog if need for gui 2026-06-23 14:57:34 +03:00
Mikhail Tergoev 4bd3028c4a add clarifications on the solution 2026-06-23 14:33:10 +03:00
Mikhail Tergoev 8edceb667c Merge branch 'minergenon-info' 2026-06-23 14:25:08 +03:00
Mikhail Tergoev 45b495eff0 add new command 2026-06-23 14:23:28 +03:00
Sergey Palcheh 0469197d77 added the noexec_warning dialog 2026-06-16 11:09:12 +06:00
Mikhail Tergoev 4f067d6850 update README.md 2026-06-05 16:45:15 +03:00
Mikhail Tergoev d0c6bdfdb6 update help 2026-06-05 16:44:52 +03:00
Mikhail Tergoev 41bde9d985 updated changelog to 0.13.0 2026-06-02 12:43:24 +03:00
Mikhail Tergoev ee9bb767a7 replace data-path if need 2026-06-01 23:03:55 +03:00
Mikhail Tergoev 1e0f8255ea revert check noexec and add custom data-path 2026-06-01 14:12:20 +03:00
Mikhail Tergoev af8471ea40 drop prepare_wine_noexec 2026-05-27 15:50:41 +03:00
Mikhail Tergoev 4bfeae6e42 Merge branch 'minergenon-devel' 2026-05-26 13:01:45 +03:00
Sergey Palcheh ccd3176d2a gui: prefix manager layout fixes 2026-05-25 11:29:38 +06:00
Sergey Palcheh 0d23121a14 gui: fixed case-insensitivity in the definition .exe files 2026-05-24 00:31:38 +06:00
Sergey Palcheh 4fbb250a34 gui: added an indicator icon to the buttons of the DXVK/VKD3D versions 2026-05-23 23:27:47 +06:00
Sergey Palcheh 6091bf2cf9 gui: added an indicator icon on the buttons of wine versions 2026-05-23 23:07:44 +06:00
Sergey Palcheh dbe5226d29 gui: added sorting of wine versions in descending order 2026-05-23 21:05:19 +06:00
Sergey Palcheh 08cc66c533 gui: added forced reinstallation of cpcsp_proxy when enabled 2026-05-23 20:26:55 +06:00
Mikhail Tergoev c457dc0d31 Merge branch 'minergenon-devel' 2026-05-22 15:45:35 +03:00
Sergey Palcheh b3e4ae719d gui: added the correct activation of CPCSP_PROXY in the additional prefix settings 2026-05-22 18:29:24 +06:00
Sergey Palcheh dc75805a31 fixed the creation of a minimum .whdb file 2026-05-22 17:30:45 +06:00
Mikhail Tergoev 3aebe55162 replace wine-10.18.1-alt1-wow64 to wine-10.0-alt-tkg-wow64 2026-05-21 20:04:38 +03:00
Mikhail Tergoev 9a7a2d5f50 fix winereg for ocx files 2026-05-21 19:51:27 +03:00
Mikhail Tergoev b4ccebc65d fix replace CService32.exe for daobit and ctm 2026-05-21 17:44:31 +03:00
Mikhail Tergoev 36b009ecd4 daobit-cservice: fix setup name 2026-05-21 17:21:17 +03:00
Mikhail Tergoev 372b4c6a6a replace wine-11.6.1-scadoffice to wine-10.0-alt-scadoffice 2026-05-21 16:35:02 +03:00
Mikhail Tergoev 15d5db87ad replace wine-10.12.1-alt1 to wine-10.0-alt-tkg 2026-05-21 16:00:18 +03:00
Mikhail Tergoev a8a35d5bd8 replace wine-10.0-tkg-amd64 to wine-10.0-alt-tkg-amd64 2026-05-21 15:52:17 +03:00
Mikhail Tergoev 87ad9e12b6 add wine-9.0-alt-tkg (i586, amd64 and wow64) 2026-05-21 15:46:42 +03:00
Mikhail Tergoev 45987c9941 emias: WH_MAIN_DECORATED=0 by default 2026-05-20 15:44:09 +03:00
Mikhail Tergoev a2f25738cf t-flex: use wine with fix crash popup windows 2026-05-20 15:21:33 +03:00
Mikhail Tergoev a1c823017b emias: use wine with fix minimizing windows 2026-05-20 15:16:57 +03:00
Mikhail Tergoev 5e1640a9c6 add and use by default wine-11.0-alt-tkg 2026-05-20 14:39:53 +03:00
Mikhail Tergoev abb6f84c60 add variable: WH_FORCE_UPDATE_CERT 2026-05-19 23:13:02 +03:00
Mikhail Tergoev 985be9b36c olimp: add itss to prefix 2026-05-19 16:05:19 +03:00
Mikhail Tergoev 33ffa28d60 remove unused versions of wine 2026-05-19 15:45:17 +03:00
Mikhail Tergoev e1bbdebfdd olimp: fix help windows 2026-05-19 15:42:16 +03:00
Mikhail Tergoev a1ae2c125d ctm-service: fix name exe for desktop file 2026-05-19 15:10:41 +03:00
Mikhail Tergoev 4b8f94a9cc one prefix for all t-flex and update wine 2026-05-19 00:21:31 +03:00
Mikhail Tergoev db7201f279 add new wine 11.9 (amd64, wow64 and tflex) 2026-05-18 21:37:36 +03:00
Mikhail Tergoev bfe9a3dc91 add check mangohud command 2026-05-15 14:10:31 +03:00
Mikhail Tergoev af2db32352 drop variable: WINE_TOP_WINDOW 2026-05-15 13:53:18 +03:00
Mikhail Tergoev c04b2df049 fix use UPDATE_CPCSP_PROXY from whdb 2026-05-14 17:45:06 +03:00
Mikhail Tergoev e8e068ba3b add variable: WINEDATADIR 2026-05-14 16:55:41 +03:00
Mikhail Tergoev 32ac86ed51 Merge branch 'minergenon-devel' 2026-05-14 16:43:58 +03:00
Sergey Palcheh e33d4037b1 gui: fix QProcess destruction while wine utilities still running 2026-05-14 18:42:05 +06:00
Sergey Palcheh c5cfe30877 gui: running Wine utilities via winehelper (CLI) instead of calling wine directly 2026-05-14 10:09:53 +06:00
Sergey Palcheh b8bd9cd08d added minimal creation .whdb file when manually creating a shortcut 2026-05-13 20:53:09 +06:00
Sergey Palcheh d942cb64c9 gui: hide installed app shortcut if .exe file is missing 2026-05-13 18:05:15 +06:00
Mikhail Tergoev f934d1e705 olimp: fix window focus 2026-05-07 21:15:16 +03:00
Mikhail Tergoev 00c16261a4 Merge branch 'minergenon-devel' 2026-05-07 20:00:35 +03:00
Mikhail Tergoev 9629717ada remove space from StartupWMClass 2026-05-07 20:00:03 +03:00
Sergey Palcheh 6fa71ed871 fix (gui): filter 'export' and '#' from winetricks list output 2026-05-06 14:45:20 +06:00
Mikhail Tergoev ab6629dd9a tflex: new wine with fix 3D and black popup on wayland 2026-05-04 21:04:18 +03:00
Mikhail Tergoev e90c365010 Merge branch 'minergenon-devel' 2026-04-29 22:12:57 +03:00
Sergey Palcheh 4e3ab5fba0 gui: winehelper is used to launch winetricks in the component dialog 2026-04-29 23:35:30 +06:00
Mikhail Tergoev 3dbfea89e3 add launch of third-party scripts 2026-04-24 14:28:13 +03:00
Mikhail Tergoev daa13f2e4c update print_error for cpcsp_setup 2026-04-23 16:19:24 +03:00
Mikhail Tergoev 2aca05928a fix restore pfx and use su_run example.sh with noexec home 2026-04-23 15:03:32 +03:00
Mikhail Tergoev 8b2af7015b add AGENTS.md 2026-04-23 11:40:54 +03:00
Mikhail Tergoev 4315cd0e3f Merge branch 'minergenon-readme' 2026-04-23 11:35:23 +03:00
Mikhail Tergoev fa10a3cf0e Merge branch 'minergenon-adem' 2026-04-23 11:33:09 +03:00
Sergey Palcheh 9f932c4403 Readme and image/handbook files have been updated to current ones 2026-04-23 13:46:03 +06:00
Mikhail Tergoev b725be78d1 add and use wine-11.6.1-scadoffice-alt5-wow64 for scadoffice 2026-04-20 16:14:14 +03:00
Sergey Palcheh 7cbd3cffc7 fixed the RuntimeError error when closing a window during process execution 2026-04-17 09:52:30 +06:00
Mikhail Tergoev 190698a1b4 Merge branch 'minergenon-fixedgui' 2026-04-08 17:17:23 +03:00
Mikhail Tergoev c96033311c Merge branch 'minergenon-nalog' 2026-04-08 17:17:06 +03:00
Mikhail Tergoev 0a225d4c3d Merge branch 'minergenon-devel' 2026-04-08 17:15:34 +03:00
Sergey Palcheh 18b92b66b1 gui: fixed auto-scrolling of the list in the component manager when searching 2026-04-07 21:58:00 +06:00
Mikhail Tergoev 230315bc57 added winedbg for debug 2026-04-07 17:21:57 +03:00
Sergey Palcheh 3d981158b0 gui: Download tab in the Wine version selection window has been removed 2026-04-07 19:00:19 +06:00
Sergey Palcheh 4ad1e38141 added to INSTALL_DLL vb6run testinstall/npul 2026-04-07 17:42:39 +06:00
Mikhail Tergoev ae24b2386e Merge branch 'minergenon-gui' 2026-04-07 13:50:24 +03:00
Sergey Palcheh 8b5b199ff1 update testinstall/npul 2026-04-07 15:24:19 +06:00
Sergey Palcheh af291e9c7a fixed the grep error when deleting all WH data 2026-04-07 11:30:27 +06:00
Sergey Palcheh c8cb60e42c refactor (gui): extract services and utils, replace Var with EnvironmentConfig
- replace global Var class with EnvironmentConfig for environment variables
- extract ScriptManager, InstallationManager, AppLauncher, SettingsManager services
- add CacheService, FileCacheService, ProcessUtils utilities
- add IconManager widget for centralized icon management
- simplify WinetricksCacheService using FileCacheService
- move winetricks parsing logic to WinetricksOutputParser
- add missing directory creation in PrefixManager.save_config
- clean up whitespace and remove unused imports
2026-04-07 10:19:54 +06:00
Mikhail Tergoev 4d508afb44 updated changelog to 0.12.0 2026-04-06 21:22:25 +03:00
Mikhail Tergoev f36869bea5 skip copy desktop file if noexec home 2026-04-06 21:16:35 +03:00
Mikhail Tergoev 0e311b5d07 replaced wine_x_tkg_10-0 to wine-10.12.1-alt1-i586 for win32 2026-04-06 20:30:16 +03:00
Mikhail Tergoev cfbb6030b5 fixed work cpcsp-proxy with noexec home 2026-04-06 19:29:49 +03:00
Mikhail Tergoev 8661d0258d updated changelog to 0.11.0 2026-04-06 15:51:52 +03:00
Mikhail Tergoev 9bb7dc7db0 fixed work with noexec home 2026-04-06 15:39:58 +03:00
Mikhail Tergoev 1f08c75cb2 dropped bc from check log size 2026-04-06 11:03:09 +03:00
Mikhail Tergoev 17802d2bc5 Merge branch 'minergenon-devel' 2026-04-06 10:37:21 +03:00
Mikhail Tergoev 86694b3721 Merge branch 'minergenon-gui' 2026-04-06 10:25:27 +03:00
Sergey Palcheh ad37601b23 added the display of the program icon in the window title 2026-04-03 13:34:17 +06:00
Mikhail Tergoev a6d894ce99 updated wine and script for emias 2026-03-31 14:48:53 +03:00
Mikhail Tergoev 8877012ec4 updated scadoffice_pfx 2026-03-31 14:48:22 +03:00
Sergey Palcheh 5774e033d4 added archiving of logs exceeding a certain size 2026-03-24 17:28:33 +06:00
Mikhail Tergoev de8294b34d Merge branch 'minergenon-devel' 2026-03-19 11:56:29 +03:00
Mikhail Tergoev 273e86958d updated changelog to 0.10.0 2026-03-18 20:11:39 +03:00
Mikhail Tergoev d0f3d0f8d6 used xz for backup; simplified dll registration 2026-03-18 19:44:58 +03:00
Sergey Palcheh fc01de74b2 renaming modules: gui -> winehelperqt 2026-03-14 16:10:32 +06:00
Mikhail Tergoev eb5d6bb613 cleaning and sorting wine 2026-03-05 11:53:16 +03:00
Mikhail Tergoev e65cd2386c added wine-11.3.1-alt1-wow64 2026-03-05 11:10:34 +03:00
Mikhail Tergoev 6b094f4905 fixed change windows version 2026-03-04 21:53:06 +03:00
Mikhail Tergoev 7f44432388 added wine-cpcsp_proxy-0.7.7-alt1.1-em-wow64 2026-03-04 15:29:00 +03:00
Mikhail Tergoev fbfccd0417 updated CPCSP_PROXY_WOW64_VER for emias 2026-03-04 15:15:28 +03:00
Mikhail Tergoev 1942d49f4d added CPCSP_PROXY update in prefix when changing version 2026-03-04 15:14:15 +03:00
Mikhail Tergoev ab2933f8b0 Merge branch 'minergenon-ctm' 2026-03-03 17:33:19 +03:00
Mikhail Tergoev 4b985417c4 olimp: fixed cropped text 2026-03-03 17:32:06 +03:00
Mikhail Tergoev d52bec4798 added WINEDLLOVERRIDES to whdb file 2026-03-03 16:33:10 +03:00
Mikhail Tergoev f2c7ecf926 updated wine and pfx for olimp 2026-03-03 11:54:00 +03:00
Mikhail Tergoev a929411daf updated olimp_pfx_x86 to v02 2026-03-03 11:53:25 +03:00
Mikhail Tergoev 8114b3cb54 do not touch the registry for WH_XDG_OPEN by default 2026-03-03 11:24:31 +03:00
Mikhail Tergoev 04e974a0b7 added wine-10.18.1-alt2-i586 2026-03-03 11:07:26 +03:00
Sergey Palcheh efe8ef7267 updated autoinstall/ctm-service 2026-03-03 13:19:14 +06:00
Sergey Palcheh a4c6ef89bf gui: removed the --force flag for installing components using winetricks 2026-02-25 16:08:52 +06:00
Sergey Palcheh 2bfb574ba1 refactor: separating GUI components into separate modules
- gui package has been created/ with modules: parsers, services, dialogues
- dialog classes have been introduced (WinetricksManagerDialog, SettingsDialog, etc.)
- services have been introduced (PrefixManager, Desktops Filemanager)
2026-02-25 13:07:47 +06:00
125 changed files with 8387 additions and 3565 deletions

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
ENV/
env/
.venv/
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
.project
.pydevproject
.settings/
# OS
.DS_Store
Thumbs.db
# Logs
*.log
# Temporary files
*.tmp
*.bak
+238
View File
@@ -0,0 +1,238 @@
# WineHelper - Руководство для AI агентов
## Обзор проекта
WineHelper — инструмент для упрощения установки Windows-приложений на Linux. Использует подготовленные скрипты, портативные версии Wine и изолированные префиксы, обеспечивая максимальную идентичность на различных операционных системах, основанных на ALT Linux (начиная с релиза p10 и выше).
**Лицензия:** GNU Lesser General Public License v2.1 (LGPL-2.1+)
**Автор:** Mikhail Tergoev (2025)
**Язык документации и комментариев:** Русский
**Статус проекта:** WIP (work in progress)
## Технологический стек
### Основные технологии
- **Bash** — основной язык для CLI-интерфейса (~2692 строк в главном скрипте)
- **Python 3** — графический интерфейс с использованием PyQt5
- **Wine** — запуск Windows-приложений (поддерживаются различные версии: vanilla, staging, Proton, tkg, crossover)
- **DXVK/VKD3D** — трансляция DirectX → Vulkan
### Зависимости Python
- PyQt5 (основной GUI фреймворк)
- Стандартная библиотека Python (os, subprocess, sys, re, shlex, shutil, html)
### Системные зависимости
- i586-версии библиотек (для 32-битных приложений, если не используется wow64)
- wget/curl для загрузки
- 7z, tar для распаковки
- wrestool, icotool для извлечения иконок из .exe
- winetricks для управления компонентами Wine
## Структура проекта
```
winehelper/
├── winehelper # Главный bash-скрипт (CLI)
├── winehelper_gui.py # GUI на PyQt5 (точка входа)
├── winehelperqt/ # Python-модуль GUI
│ ├── __init__.py # Экспорты основных классов
│ ├── dialogs/ # Диалоговые окна
│ │ ├── base_version_dialog.py
│ │ ├── component_version.py
│ │ ├── create_prefix.py # Создание префикса
│ │ ├── file_associations.py
│ │ ├── settings.py # Настройки
│ │ ├── wine_version.py # Выбор версии Wine
│ │ └── winetricks_manager.py
│ ├── parsers/ # Парсеры
│ │ ├── script_parser.py # Парсинг скриптов установки
│ │ ├── sha256_parser.py # Парсинг sha256sum.list
│ │ └── winetricks_parser.py
│ ├── services/ # Бизнес-логика
│ │ ├── application_installer.py
│ │ ├── desktop_file_manager.py
│ │ ├── prefix_manager.py # Управление префиксами
│ │ ├── process_handler.py
│ │ └── winetricks_service.py
│ ├── utils/ # Утилиты
│ │ └── log_handler.py # Обработка логов
│ └── widgets/ # Кастомные виджеты
├── autoinstall/ # Скрипты автоматической установки (43 приложения)
├── manualinstall/ # Скрипты ручной установки (9 приложений)
├── testinstall/ # Тестовые скрипты установки
├── database/ # Базы данных префиксов (.whdb файлы)
├── image/ # Иконки приложений и GUI ресурсы
│ ├── gui/ # Иконки приложения (SVG)
│ └── handbook/ # Скриншоты для документации
├── hiden_scripts/ # Скрытые/вспомогательные скрипты
├── auto_completion/ # Автодополнение для bash
├── dependencies.sh # Установка системных зависимостей
├── sha256sum.list # SHA256 хеши загружаемых файлов
└── winehelper.desktop # Desktop-файл для запуска GUI
```
## Архитектура кода
### CLI (winehelper)
Главный скрипт `winehelper` — монолитный bash-скрипт с функциональными блоками:
1. **Переменные и окружение** — определение путей, версий, флагов
2. **Функции сообщений** — цветной вывод в терминал
3. **Утилиты** — работа с файлами, архивами, скачивание
4. **Управление префиксами** — создание, удаление, бэкап/восстановление
5. **Wine management** — установка версий Wine, DXVK, VKD3D
6. **Desktop integration** — создание .desktop файлов, меню
7. **Основной цикл** — обработка аргументов командной строки
### GUI (winehelperqt)
Модульная архитектура PyQt5:
- **WineHelperGUI** — главное окно, управление вкладками
- **PrefixManager** — CRUD операции с префиксами
- **ApplicationInstaller** — установка приложений
- **ScriptParser** — парсинг информации из скриптов установки
- **Диалоги** — модальные окна для настроек и выбора
### Скрипты установки
Каждый скрипт установки — это bash-скрипт с переменными:
```bash
#!/usr/bin/env bash
# info_ru: Описание программы
export PROG_URL="https://example.com"
export WH_WINE_USE="wine-10.18.1-alt1-wow64" # Версия Wine
export WINEPREFIX="prefix_name" # Имя префикса
export PROG_NAME="Название программы"
export BASE_PFX="base_prefix_v01" # Базовый шаблон (опционально)
export WINEARCH="win64" # Архитектура (win32/win64)
export INSTALL_DLL="corefonts msxml3..." # DLL через winetricks
# Логика установки
prepair_wine
try_download "URL" "${FILE_PATH}"
unpack "${FILE_PATH}" "${DEST_DIR}"
wine_run_install "${SETUP_EXE}" /S
create_desktop "Имя ярлыка" "${EXE_PATH}" "icon_name"
```
## Режимы работы
### Системный режим
Когда скрипт установлен в `/usr/bin/winehelper`:
- Данные в `/usr/share/winehelper/`
- Рабочая директория пользователя: `~/.local/share/winehelper/`
- Иконки в `/usr/share/icons/...`
### Режим разработки
При запуске из репозитория:
- Рабочая директория: `~/test-winehelper/`
- Данные берутся из текущей директории
- Включается проверка синтаксиса скриптов
## Команды CLI
```bash
# Установка
winehelper install list # Список доступных программ
winehelper -i <script_name> # Установить программу
winehelper -i <script_name> /path # Установить из дистрибутива
winehelper -i "/path/to/script" # Установить из стороннего скрипта
# Управление префиксами
winehelper create-prefix # Создать префикс
winehelper remove-prefix [name] # Удалить префикс
winehelper backup-prefix [name] # Создать бэкап (.whpack)
winehelper restore-prefix <path> # Восстановить из бэкапа
# Wine tools
winehelper winefile # Файловый менеджер
winehelper winecfg # Настройки Wine
winehelper winereg # Редактор реестра
winehelper wineconsole # Терминал Wine (cmd.exe)
winehelper winetricks [component] # Winetricks
winehelper <file.exe> # Запустить exe в префиксе
winehelper debug [флаги] [программа] # Запуск программы в отладчике winedbg
winehelper killall # Остановить все процессы Wine
winehelper run-in-prefix <префикс> <файл> # Запустить файл в указанном префиксе
# Управление компонентами
winehelper install-dxvk [version] # Установить DXVK
winehelper install-vkd3d [version] # Установить VKD3D
winehelper change-wine [version] # Сменить версию Wine
winehelper clear-winetricks-cache # Очистить кэш Winetricks
# Другое
winehelper --debug <command> # Режим отладки
winehelper --changelog # История изменений
winehelper gui # Запустить GUI
```
## Разработка
### Запуск в режиме разработки
```bash
# GUI режим
./winehelper gui
# CLI режим
./winehelper install list
./winehelper -i alta-expert
```
### Добавление нового скрипта установки
1. Создать файл в `autoinstall/` (для автоматической установки) или `manualinstall/` (требуется дистрибутив)
2. Добавить обязательные переменные: `PROG_NAME`, `WINEPREFIX`, `WH_WINE_USE`, `PROG_URL`
3. Добавить комментарий `# info_ru:` с описанием
4. Добавить иконку в `image/` (PNG, имя совпадает с переменной в create_desktop)
5. Обновить `sha256sum.list` если требуется загрузка архивов
### Требования к коду
**Bash:**
- Использовать `#!/usr/bin/env bash`
- Проверять наличие переменных перед использованием
- Использовать функции обработки ошибок (`fatal`, `print_error`)
- Экранировать все пути с помощью кавычек
**Python:**
- Импортировать из `winehelperqt` относительно
- Использовать type hints где возможно
- Документация на русском языке
- Классы должны наследоваться от соответствующих QWidget
## Безопасность
- Скрипт запрещает запуск от root
- Проверяет noexec для /home
- Проверяет SHA256 хеши загружаемых файлов
- Использует временные файлы с ограниченными правами (600)
- Поддержка лицензионного соглашения перед установкой
## Особенности ALT Linux
- Требуется репозиторий x86_64-i586 для 32-битных зависимостей
- Интеграция с RPM (версия определяется через `rpm -q winehelper`)
- Использование apt-get для установки зависимостей
- Desktop-файлы размещаются в `~/.local/share/applications/`
## Полезные ссылки
- Официальная документация: https://www.altlinux.org/Winehelper
- Совместимость ПО (P10): https://www.basealt.ru/fileadmin/user_upload/compatibility/P10-view2.html
- Совместимость ПО (P11): https://www.basealt.ru/fileadmin/user_upload/compatibility/P11-view2.html
## Сторонние компоненты
- Wine / Wine-Staging / Proton / wine-tkg
- Wine-Mono, Wine-Gecko
- DXVK, VKD3D
- Winetricks
- wine-cpcsp_proxy (для КриптоПро)
+55
View File
@@ -1,5 +1,60 @@
История изменений:
0.13.0
* обновлен графический режим Qt5:
- исправлены/улучшены основные функции
- запуск утилит Wine выполняется через winehelper (CLI) вместо прямого вызова wine
- добавлены индикаторы-иконки на кнопках версий Wine и DXVK/VKD3D
- добавлена сортировка версий Wine по убыванию
- удалена вкладка "Загрузка" в окне выбора версии Wine
- исправлена автопрокрутка списка в менеджере компонентов при поиске
- исправлено определение .exe файлов без учета регистра
- скрытие ярлыка установленного приложения, если .exe файл отсутствует
- добавлена корректная активация CPCSP_PROXY в дополнительных настройках префикса
- добавлена принудительная переустановка cpcsp_proxy при включении
* добавлены версии wine:
- wine-11.0-alt-tkg
- wine-9.0-alt-tkg (i586, amd64, wow64)
- wine-10.0-alt-tkg (i586, amd64, wow64)
- wine-10.0-alt-scadoffice-wow64
* удалены неиспользуемые версии wine
* обновлены скрипты установок:
- t-flex: единый префикс для всех версий, используется wine с исправлением всплывающих окон и 3D на Wayland
- emias: используется wine с исправлением сворачивания окон
- scadoffice: используется специальная сборка wine (демо версия программы)
- olimp: добавлен itss в префикс, исправлен фокус окна и окна справки
- ctm-service: исправлено имя exe для desktop файла
- daobit-cservice: исправлено имя установщика и замена CService32.exe
* добавлена поддержка запуска сторонних скриптов установки
* добавлена минимальная генерация .whdb файла при ручном создании ярлыка
* возвращено уведомление о монтировании home с флагом noexec
* добавлена возможность выбрать рабочий каталог для WineHelper:
winehelper data-path "/путь/к/каталогу"
0.12.0
* исправлена работа cpcsp_proxy при монтировании home с флагом noexec
* обновлены все скрипты установки ВЭД и СТМ
0.11.0
* исправлена работа WineHelper при монтировании home с флагом noexec
* исправлена иконка графического режима Qt5
* добавлена автоматическая архивация лога, если он больше 10 Мб
* исправлена работа сертификатов для emias (спасибо lav@)
0.10.0
* добавлены скрипты установок:
- apropos-z
- olimp
* обновлены скрипты установок:
- ctm-service
- emias
* добавлены версии wine:
- wine-11.3.1-alt1-wow64
- wine-10.18.1-alt2-i586
- wine-9.0-cx-amd64
* добавлена поддержка wine-cx (форк wine от crossover)
* небольшие улучшения графического режим Qt5
0.9.0
* добавлена поддержка wine-wow64 (не требует установку 32-битных зависимостей в систему)
* добавлена поддержка wine-cpcsp_proxy для wine-wow64 (не требует установку 32-битного КриптоПро в систему)
+84 -18
View File
@@ -48,19 +48,19 @@
$ winehelper -i
```
### Запуск установки приложений
### Запуск установки приложений из списка скриптов
Скрипты установки разделены на два типа:
1. **Список программ с возможностью автоматической установки** — содержит полностью автоматизированные скрипты установок программ у которыx есть дистрибутивы (установщики) в свободном доступе.
1. **Список программ с возможностью автоматической установки** — содержит полностью автоматизированные скрипты установок программ у которых есть дистрибутивы (установщики) в свободном доступе.
Процесс полностью автоматизирован.
Пример:
```
$ winehelper install spravki-bk
$ winehelper install ksamu
```
или сокращенная команда:
```
$ winehelper -i spravki-bk
$ winehelper -i ksamu
```
2. **Список программ с возможностью установки из существующего дистрибутива** — содержит скрипты установок для программ, которых нет в свободном доступе.
Пример:
@@ -72,7 +72,13 @@
$ winehelper -i is-record-station "/путь/до/установочного_файла"
```
### Процесс установки приложений
3. **Установка из стороннего скрипта** — можно передать путь к собственному скрипту установки, подготовленному по шаблону WineHelper.
Пример:
```
$ winehelper -i "/путь/до/скрипта_установки"
```
### Процесс установки приложений из списка скриптов
При первом запуске **WineHelper** проверяются и при необходимости устанавливаются дополнительные зависимости (запрашиваются права root).
@@ -88,6 +94,27 @@
Если устанавливаемое приложение требует дополнительных действий от пользователя (ввод лицензии, настройка), это будет явно указано в терминале.
### Установка своего приложения
Для установки своего приложения (не из списка готовых скриптов) выполните следующие шаги:
**Этап 1: Создание префикса**
Создайте новый префикс с использованием wine-wow64 (рекомендуется для новых приложений):
```
$ winehelper create-prefix
```
Выберите wine-wow64 версию и разрядность 64-bit.
> [!NOTE]
> **Всегда сначала пробуйте wine-wow64**, это упрощает настройку и избавляет от 32-битных зависимостей.
**Этап 2: Запуск установщика**
Запустите установочный файл в созданном префиксе:
```
$ winehelper "/путь/до/установочного_файла.exe"
```
Выберите префикс из списка (введите номер и нажмите Enter).
### Удаление префикса с приложением
Для удаления префикса выполните команду:
@@ -101,14 +128,14 @@
2 - Префикс2
Выберите префикс (0-2):
```
Необходимо указать номер удаляемого префикса и нажать клавишу **Enter**.Далее потребуется подтвердить удаление префикса вводом **y**.
Необходимо указать номер удаляемого префикса и нажать клавишу **Enter**. Далее потребуется подтвердить удаление префикса вводом **y**.
В результате будут удалены:
- сам префикс;
- установленное ПО;
- desktop-файлы (ярлыки для установленного ПО в префиксе).
###
### Cоздание резервной копии префикса
Команда создания резервной копии префикса:
```
@@ -138,7 +165,7 @@
Восстановление префикса не требует подключение к интернету и происходит в автоматическом режиме:
- Распаковка префикса.
- Восстановление версии WINE.
- Восстановление ярлыков (.desktop-файdлов).
- Восстановление ярлыков (.desktop-файлов).
После завершения восстановления приложение будет доступно для запуска через меню или рабочий стол.
@@ -150,7 +177,6 @@ WineHelper предоставляет доступ к основным инст
winehelper winecfg # запуск wine конфигуратора для префикса
winehelper winereg # запуск редактора реестра для префикса
winehelper wineconsole # запуск терминала wine (cmd.exe)
winehelper winetricks # запуск графического интерфейса winetricks
winehelper winetricks [компонент] # автоматическая установка дополнительного компонента в префикс
```
После выполнения любой из вышеперечисленных команд отображается список существующих префиксов:
@@ -175,7 +201,7 @@ WineHelper предоставляет доступ к основным инст
```
Файл будет запущен в выбранном префиксе.
2. С помощью файлового менеджера WINE:'''
2. С помощью файлового менеджера WINE:
```
$ winehelper winefile
0 - Отмена
@@ -198,18 +224,35 @@ WineHelper предоставляет доступ к основным инст
install list список возможных установочных скриптов
install [скрипт] запустить скрипт установки программы
install [скрипт] --clear-pfx не использовать готовый префикс для установки ПО
install "путь/до/скрипта" запустить сторонний скрипт установки
install-dxvk [версия|none|list] установить, удалить или показать версии DXVK
install-vkd3d [версия|none|list] установить, удалить или показать версии VKD3D
change-wine [версия] изменить версию Wine для текущего префикса
installed список установленных программ
run [программа] запуск программы (отладка)
run [программа] запуск программы
debug [флаги] [программа] запуск программы в отладчике winedbg
Флаги:
--auto, -a автоматический backtrace
--gdb, -g режим gdb
--interactive, -i интерактивный режим
remove-all удалить WineHelper и все связанные данные
create-prefix создать префикс
remove-prefix [имя_префикса] удалить префикс и все связанные данные
backup-prefix [имя_префикса] создать резервную копию префикса
restore-prefix \"путь/до/whpack\" восстановить префикс из резервной копии
clear-winetricks-cache очистить кэш Winetricks
winecfg запуск wine конфигуратора для префикса
winereg запуск редактора реестра для префикса
winefile запуск файлового менеджера wine
wineconsole запуск терминала wine (cmd.exe)
control запуск панели управления wine
uninstaller запуск удаления программ wine
winetricks [компонент] автоматическая установка дополнительного компонента в префикс
killall остановить все процессы Wine
run-in-prefix <префикс> <файл> запустить файл в указанном префиксе
Параметры:
--help показать эту справку и выйти
@@ -239,7 +282,7 @@ WineHelper предоставляет доступ к основным инст
<p><em>Вкладка "Ручная установка"</em></p>
</div>
Так же на вкладке **Автоматическая установка** есть чекбокс с тестовыми версиями скриптов установки которые еще не прошли полную проверку на зависимости и совместимость, но уже можно попробовать в работе.
Также на вкладке **Автоматическая установка** есть чекбокс с тестовыми версиями скриптов установки которые еще не прошли полную проверку на зависимости и совместимость, но уже можно попробовать в работе.
<div align="center">
<img src="image/handbook/auto_install_test.png">
@@ -324,9 +367,9 @@ WineHelper предоставляет доступ к основным инст
#### Создание нового префикса
Нажав кнопку **«Создать новый префикс»**, вы откроете диалог, где можно задать:
* **Имя префикса**.
* **Имя нового префикса**.
* **Разрядность** (32-bit или 64-bit).
* **Наполнение** (чистый префикс или с рекомендуемыми библиотеками).
* **Шаблон префикса** (чистый префикс или с рекомендуемыми библиотеками).
* **Версию Wine** из доступного списка.
<div align="center">
@@ -334,22 +377,45 @@ WineHelper предоставляет доступ к основным инст
<p><em>Диалог создания нового префикса</em></p>
</div>
#### Установка своего приложения
Для установки своего приложения (не из списка готовых скриптов) выполните следующие шаги:
**Этап 1: Создание префикса**
1. Вкладка **«Менеджер префиксов»**
2. Нажмите **«Создать новый префикс»**
3. Задайте имя префикса
4. Выберите **wine-wow64** версию (рекомендуется)
5. Выберите разрядность **64-bit**
> [!NOTE]
> **Всегда сначала пробуйте wine-wow64**, это упрощает настройку и избавляет от 32-битных зависимостей.
**Этап 2: Установка приложения**
1. Выберите созданный префикс из выпадающего списка
2. Нажмите кнопку **«Запустить файл в префиксе»**, выберите файл для установки
3. Нажмите кнопку **«Создать ярлык для приложения в префиксе»**, выберите установленный файл в префиксе
#### Управление существующим префиксом
Выбрав префикс из выпадающего списка, вы получаете доступ к панели управления, которая позволяет:
* **Управлять компонентами**:
* **Менеджер компонентов (Winetricks)**: Удобный интерфейс для установки и переустановки библиотек, шрифтов и настроек.
* **Запускать стандартные утилиты Wine**:
* `Редактор настроек (winecfg)`
* `Редактор реестра (regedit)`
* `Удаление программ (uninstaller)`
* `Командная строка (cmd)`
* `Файловый менеджер (winefile)`
* **Управлять компонентами**:
* **Менеджер компонентов (Winetricks)**: Удобный интерфейс для установки и переустановки библиотек, шрифтов и настроек.
* **Управление Wine**: Смена версии Wine для выбранного префикса. Диалог выбора позволяет как выбрать уже установленную версию, так и скачать новую из списков, сгруппированных по архитектуре.
* `Панель управления (control)`
* **Управлять версиями Wine**:
* **Управление версией Wine**: Смена версии Wine для выбранного префикса. Диалог выбора позволяет как выбрать уже установленную версию, так и скачать новую из списков, сгруппированных по архитектуре.
* **Управлять дополнительными настройками**:
* **Управление DXVK/VKD3D**: Установка или удаление конкретных версий DXVK и vkd3d-proton.
* **Ассоциации файлов**: Настройка открытия определенных типов файлов (например, `.pdf`, `.docx`) нативными приложениями Linux, чтобы избежать их открытия внутри Wine.
* **Включать/выключать ESync и FSync**.
* **Включать/выключать ESync и FSync**: Включение/выключение методов оптимизации синхронизации потоков в Windows-приложениях при запуске через Wine.
* **Включать/выключать CPCSP_PROXY**: Поддержка КриптоПро CSP (электронная подпись). Включайте только для приложений, требующих ЭП.
* **Устанавливать приложения**: Установить любой `.exe` или `.msi` файл напрямую в выбранный префикс.
* **Создавать ярлыки**: Создать ярлык для любого исполняемого файла внутри префикса.
* **Удалять префикс** или **создавать из него шаблон**.
+20 -6
View File
@@ -4,8 +4,8 @@ _winehelper_completions() {
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine clear-winetricks-cache"
wine_cmd="winecfg winereg winefile wineconsole winetricks desktop regedit explorer cmd run"
opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all killall remove-prefix backup-prefix restore-prefix create-prefix change-wine clear-winetricks-cache gui data-path version help --changelog changelog create-base-pfx init-prefix run-in-prefix debug"
wine_cmd="winecfg winereg winefile wineconsole winetricks desktop regedit explorer cmd run uninstaller control"
case "${prev}" in
winehelper)
@@ -17,12 +17,12 @@ _winehelper_completions() {
return 0
;;
install|-i)
local scripts="$(ls -1 /usr/share/winehelper/autoinstall) $(ls -1 /usr/share/winehelper/manualinstall)"
COMPREPLY=( $(compgen -W "list ${scripts}" -- "${cur}") )
local scripts="$(ls -1 /usr/share/winehelper/autoinstall 2>/dev/null) $(ls -1 /usr/share/winehelper/manualinstall 2>/dev/null) $(ls -1 /usr/share/winehelper/testinstall 2>/dev/null)"
COMPREPLY=( $(compgen -W "list --clear-pfx ${scripts}" -- "${cur}") )
return 0
;;
run|installed)
local installed=$(ls -1 ~/.local/share/winehelper/ | grep ".desktop" | sed 's/.desktop//')
run|installed|debug)
local installed=$(ls -1 ~/.local/share/winehelper/ 2>/dev/null | grep ".desktop" | sed 's/.desktop//')
COMPREPLY=( $(compgen -W "${installed}" -- "${cur}") )
return 0
;;
@@ -31,7 +31,17 @@ _winehelper_completions() {
COMPREPLY=( $(compgen -W "${prefixes}" -- "${cur}") )
return 0
;;
run-in-prefix)
local prefixes=$(ls -1 ~/.local/share/winehelper/prefixes 2>/dev/null)
COMPREPLY=( $(compgen -W "${prefixes}" -- "${cur}") )
return 0
;;
restore-prefix)
COMPREPLY=( $(compgen -f -X '!*.whpack' -- "${cur}") )
return 0
;;
data-path)
COMPREPLY=( $(compgen -d -- "${cur}") )
return 0
;;
install-dxvk|install-vkd3d)
@@ -49,6 +59,10 @@ _winehelper_completions() {
return 0
;;
*)
if [[ "${COMP_WORDS[COMP_CWORD-2]}" == "run-in-prefix" ]] ; then
COMPREPLY=( $(compgen -f -- "${cur}") )
return 0
fi
;;
esac
}
+34 -16
View File
@@ -5,7 +5,9 @@ _winehelper() {
opts=(
'--help[Вывести справку]'
'help[Вывести справку]'
'--version[Показать информацию о пакете и его версии]'
'version[Показать информацию о пакете и его версии]'
'--debug[Режим отладки]'
'install[Запустить скрипт установки программы]'
'install-dxvk[Установить/удалить DXVK]'
@@ -14,14 +16,21 @@ _winehelper() {
'-r[Запуск программы (отладка)]'
'-i[Запустить скрипт установки программы]'
'remove-all[Удалить WineHelper и все связанные данные]'
'--clear-pfx[Очистить префикс \[имя_префикса\]]'
'killall[Убить все процессы]'
'create-prefix[Создать новый префикс]'
'remove-prefix[Удалить префикс и все связанные данные]'
'backup-prefix[Создать резерную копию префикса]'
'restore-prefix[восстановить префикс из резервной копии "путь/до/whpack"]'
'backup-prefix[Создать резервную копию префикса]'
'restore-prefix[Восстановить префикс из резервной копии "путь/до/whpack"]'
'change-wine[Изменить версию Wine для префикса]'
'clear-winetricks-cache[Очистить кэш Winetricks]'
'gui[Запустить графический интерфейс]'
'data-path[Изменить рабочий каталог WineHelper]'
'create-base-pfx[Создать базовый шаблонный префикс]'
'init-prefix[Инициализировать префикс]'
'run-in-prefix[Запустить файл в указанном префиксе]'
'debug[Запуск программы в отладчике]'
'--changelog[Показать историю изменений]'
'changelog[Показать историю изменений]'
)
wine_cmd=(
@@ -34,6 +43,8 @@ _winehelper() {
regedit
explorer
cmd
uninstaller
control
'run[Запуск программы (отладка)]'
)
@@ -47,6 +58,11 @@ _winehelper() {
_values 'winehelper options' "${opts[@]}" "${wine_cmd[@]}"
;;
args)
if [[ "$words[2]" == "run-in-prefix" ]] && [[ ${#words[@]} -gt 3 ]] ; then
_files
return
fi
case $words[2] in
--debug)
_values 'wine commands' "${wine_cmd[@]}"
@@ -54,16 +70,19 @@ _winehelper() {
install|-i)
_get_list_for_install
;;
run|installed)
run|installed|debug)
_get_installed_list
;;
remove-prefix|backup-prefix)
remove-prefix|backup-prefix|run-in-prefix)
_get_prefixes
;;
create-prefix)
create-prefix|init-prefix|create-base-pfx|gui|killall|clear-winetricks-cache|remove-all|version|--version|help|--help|changelog|--changelog)
;;
restore-prefix)
_files
_files -g '*.whpack'
;;
data-path)
_path_files -/
;;
install-dxvk)
_get_component_versions 'install-dxvk'
@@ -74,6 +93,8 @@ _winehelper() {
change-wine)
_get_wine_versions
;;
winecfg|winereg|winefile|wineconsole|winetricks|desktop|regedit|explorer|cmd|uninstaller|control)
;;
*)
_values 'winehelper options' "${opts[@]}" "${wine_cmd[@]}"
;;
@@ -117,8 +138,11 @@ _get_prefixes () {
}
_get_list_for_install () {
packages=(${(f)"$(winehelper install list 2>/dev/null |
local -a packages
packages=(--clear-pfx)
packages+=(${(f)"$(winehelper install list 2>/dev/null |
awk -F ' - ' '
/^[^ ]+ - \("/ {next}
/^[[:space:]]*$/ {next}
@@ -131,14 +155,8 @@ _get_list_for_install () {
if (name && desc) print name ":" desc
}
')"})
packages+=(
scadoffice:"SCAD Office"
t-flex-cad17-applications:"Приложения для T-FLEX CAD 17"
t-flex-cad17-resources:"Обучающие материалы T-FLEX CAD 17"
)
_describe 'packages' packages
_describe 'packages' packages
}
_get_installed_list () {
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Пакет программ для таможенного оформления. Включает программы Такса и ТамДок в комплектациях Эксперт, а также программу Заполнитель.
########################################################################
export PROG_URL="https://www.alta.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="alta"
export PROG_NAME="Альта-Эксперт"
export BASE_PFX="alta_pfx_x86_v01"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Таможенное оформление товаров
########################################################################
export PROG_URL="https://www.alta.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="alta"
export PROG_NAME="Альта-ГТД"
export PROG_ICON="altagtd"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Пакет программ для таможенного оформления. Включает программы Альта-ГТД, Такса и ТамДок в комплектациях Максимум, а также программу Заполнитель.
########################################################################
export PROG_URL="https://www.alta.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="alta"
export PROG_NAME="Альта-Максимум"
export BASE_PFX="alta_pfx_x86_v01"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Таможенное законодательство
########################################################################
export PROG_URL="https://www.alta.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="alta"
export PROG_NAME="Таможенные документы"
export PROG_ICON="altatamdoc"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Расчет контракта
########################################################################
export PROG_URL="https://www.alta.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="alta"
export PROG_NAME="Такса"
export PROG_ICON="altatax"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Автоматизация импорта данных
########################################################################
export PROG_URL="https://www.alta.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="alta"
export PROG_NAME="Заполнитель"
export PROG_ICON="altazap"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Система “A'PROPOS-Z - Графит ТМ” для проектирования этапов механообработки, синтеза, расчета и верефикация операционных размерных текстур. Графическое моделирование технологии иформирование карт эскизов.
########################################################################
export PROG_URL="https://www.tezis.pro"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="apropos-z"
export PROG_NAME="A'PROPOS-Z - Графит ТМ"
export PROG_ICON="apropos-z"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ АТТЕСТАТ” для документов об основном общем, среднем общем образовании.
########################################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank-4"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ АТТЕСТАТ"
export PROG_ICON="armkt"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ ДПП” для заполнения бланков документов о повышении квалификации и профессиональной переподготовке.
########################################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ ДПП"
export PROG_ICON="armkt"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ НШ” для заполнения бланков документов об окончании начальной школы.
########################################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank-1"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ НШ"
export PROG_ICON="armkt"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ МЕД” для заполнения бланков документов о послевузовском профессиональном образовании и сертификатов специалиста.
######################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank-3"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ МЕД"
export PROG_ICON="armkt"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ ПРОФЕССИЯ” для заполнения бланков документов профессионального обучения.
########################################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank-5"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ ПРОФЕССИЯ"
export PROG_ICON="armkt"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ СПО” для заполнения бланков документов о среднем профессиональном образовании.
########################################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank-2"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ СПО"
export PROG_ICON="armkt"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа “АРМ КТ ПРОФ ВУЗ” для заполнения бланков документов о высшем образовании.
########################################################################
export PROG_URL="https://armregistr.ru/programmnoe-obespechenie/licenziya-na-programmnoe-obespechenie-dlya-zapolneniya-blank-6"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="arm-kt"
export PROG_NAME="АРМ КТ ПРОФ ВУЗ"
export PROG_ICON="armkt"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://www.ctm.ru"
export PROG_NAME="СТМ-Финансы"
export PROG_ICON="ctmfinance"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://www.ctm.ru"
export PROG_NAME="СТМ-Журналы"
export PROG_ICON="ctmjournals"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://www.ctm.ru"
export PROG_NAME="Монитор ЭД"
export PROG_ICON="ctmmonitor"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://www.ctm.ru"
export PROG_NAME="СТМ-Отчет"
export PROG_ICON="ctmreport"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+6 -4
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://www.ctm.ru"
export PROG_NAME="СТМ-Сервис"
export PROG_ICON="ctmservice"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
@@ -18,7 +18,7 @@ get_and_set_reg_file --add 'Software\CTM\CTMSETUP' 'SkipKBCheck' 'REG_DWORD' "1"
AUTOINSTALL_EXE="${WH_TMP_DIR}/setup_cs.exe"
AUTOINSTALL_UNPACK="${WH_TMP_DIR}/setup_cs"
AUTOINSTALL_SETUP="${WH_TMP_DIR}/setup_cs/setup.exe"
AUTOINSTALL_SETUP="${WH_TMP_DIR}/setup_cs/Setup.exe"
if try_download "https://files.ctm.ru/CSERVICE/SFX/setup_cs.exe" "${AUTOINSTALL_EXE}" ; then
unpack "${AUTOINSTALL_EXE}" "${AUTOINSTALL_UNPACK}"
@@ -27,8 +27,10 @@ if try_download "https://files.ctm.ru/CSERVICE/SFX/setup_cs.exe" "${AUTOINSTALL_
wine_run_install "${AUTOINSTALL_SETUP}" /cd /targetdir="C:\\\\Program Files\\\\CTM\\\\CSERVICE" /auto /hide
try_remove_dir "$AUTOINSTALL_UNPACK"
WIN_FILE_EXEC="$DRIVE_C/Program Files/CTM/CSERVICE/ctmservc.exe"
create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON"
WIN_FILE_EXEC="$DRIVE_C/Program Files/CTM/CSERVICE/CService32.exe"
WIN_FAKE_EXEC="$DRIVE_C/Program Files/CTM/CSERVICE/ctm-service.exe"
try_force_link_file "$WIN_FILE_EXEC" "$WIN_FAKE_EXEC"
create_desktop "$PROG_NAME" "$WIN_FAKE_EXEC" "$PROG_ICON"
if [[ "$USE_CTMBAR" == "1" ]] ; then
if [[ -f "$DRIVE_C/Program Files/CTM/COMMON/CTMBAR.EXE" ]]
+5 -3
View File
@@ -2,7 +2,7 @@
# info_ru: Сервис обновления ПО: "R-Атлас", "R-Инфо" и "R-Тариф".
########################################################################
export PROG_URL="https://daobit.ru"
export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="daobit"
export PROG_NAME="Сервис обновления ПО"
export PROG_ICON="daobitcservice"
@@ -13,7 +13,7 @@ export INSTALL_DLL="dotnet7 dotnetdesktop7 arial renderer=gdi"
AUTOINSTALL_EXE="${WH_TMP_DIR}/setup_cs.exe"
AUTOINSTALL_UNPACK="${WH_TMP_DIR}/setup_cs"
AUTOINSTALL_SETUP="${WH_TMP_DIR}/setup_cs/SETUP.EXE"
AUTOINSTALL_SETUP="${WH_TMP_DIR}/setup_cs/Setup.exe"
prepair_wine
if try_download "https://files.daobit.ru/CSERVICE/SFX/setup_cs.exe" "${AUTOINSTALL_EXE}" ; then
@@ -25,7 +25,9 @@ if try_download "https://files.daobit.ru/CSERVICE/SFX/setup_cs.exe" "${AUTOINSTA
wine_run_install "${AUTOINSTALL_SETUP}" /cd /targetdir="C:\\\\Program Files\\\\DAO\\\\CSERVICE" /auto /hide
WIN_FILE_EXEC="$DRIVE_C/Program Files/DAO/CSERVICE/CService32.exe"
create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON"
WIN_FAKE_EXEC="$DRIVE_C/Program Files/DAO/CSERVICE/daobit-service.exe"
try_force_link_file "$WIN_FILE_EXEC" "$WIN_FAKE_EXEC"
create_desktop "$PROG_NAME" "$WIN_FAKE_EXEC" "$PROG_ICON"
try_remove_dir "$AUTOINSTALL_UNPACK"
try_remove_file "$AUTOINSTALL_EXE"
fi
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Построение маршрутов железнодорожных грузоперевозок
########################################################################
export PROG_URL="https://daobit.ru"
export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="daobit"
export PROG_NAME="R-Атлас"
export PROG_ICON="daobitratlas"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Специализированная информация для организации железнодорожных перевозок
########################################################################
export PROG_URL="https://daobit.ru"
export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="daobit"
export PROG_NAME="R-Инфо"
export PROG_ICON="daobitrinfo"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Расчёт размера провозной платы и дополнительных сборов за грузовые перевозки по железной дороге
########################################################################
export PROG_URL="https://daobit.ru"
export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="daobit"
export PROG_NAME="R-Тариф"
export PROG_ICON="daobitrtariff"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://www.keepsoft.ru"
export PROG_NAME="Конструктор тестов"
export AUTOINSTALL_EXE="${WH_TMP_DIR}/simulator4.exe"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="keepsoft_similator4"
export BASE_PFX="defpfx_x86_v01"
export WINEARCH="win32"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: “КСАМУ” - Комплексная система автоматизации медицинского учреждения.
########################################################################
export PROG_URL="https://docs.medicine-it.ru/"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="ksamu"
export PROG_NAME="КСАМУ"
export PROG_ICON="ksamu"
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD Учебная Версия 17"
export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 17"
export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -5,13 +5,12 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="Приложения для T-FLEX CAD 17"
export PROG_ICON="tflexcad17"
export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
check_prefix_var
if [[ ! -f "$WINEPREFIX/drive_c/Program Files/T-FLEX CAD 17/Program/TFlexCad.exe" ]]
+2 -3
View File
@@ -5,13 +5,12 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="Ресурсы для T-FLEX CAD 17"
export PROG_ICON="tflexcad17"
export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
check_prefix_var
if [[ ! -f "$WINEPREFIX/drive_c/Program Files/T-FLEX CAD 17/Program/TFlexCad.exe" ]]
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 18"
export PROG_ICON="tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex18"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -5,13 +5,12 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="Приложения для T-FLEX CAD 18"
export PROG_ICON="tflexcad18"
export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WINEPREFIX="tflex18"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
check_prefix_var
if [[ ! -f "$WINEPREFIX/drive_c/Program Files/T-FLEX CAD 18/Program/TFlexCad.exe" ]]
+2 -3
View File
@@ -5,13 +5,12 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="Ресурсы для T-FLEX CAD 18"
export PROG_ICON="tflexcad18"
export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WINEPREFIX="tflex18"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
check_prefix_var
if [[ ! -f "$WINEPREFIX/drive_c/Program Files/T-FLEX CAD 18/Program/TFlexCad.exe" ]]
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 2D+ 17"
export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 2D+ 18"
export PROG_ICON="tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex18"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX DOCs 17"
export PROG_ICON="tflexdoc17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=gdi"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX Viewer 17"
export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+2 -3
View File
@@ -4,14 +4,13 @@
export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX Viewer 18"
export PROG_ICON="tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex18"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
# используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://ctm.ru"
export PROG_NAME="ВЭД-Алфавит"
export PROG_ICON="vedalf"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://ctm.ru"
export PROG_NAME="ВЭД-Контроль"
export PROG_ICON="vedcontrol"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://ctm.ru"
export PROG_NAME="ВЭД-Декларант"
export PROG_ICON="veddcl"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://ctm.ru"
export PROG_NAME="ВЭД-Инфо"
export PROG_ICON="vedinfo"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://ctm.ru"
export PROG_NAME="ВЭД-Платежи"
export PROG_ICON="vedpayments"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -4,7 +4,7 @@
export PROG_URL="https://ctm.ru"
export PROG_NAME="ВЭД-Склад"
export PROG_ICON="vedsts"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ved_ctm"
export BASE_PFX="ved_ctm_pfx_x86_v05"
export WINEARCH="win32"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Компоненты сервисов поддержки T-FLEX 17 и 18
########################################################################
export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export WH_WINE_USE="wine-11.0-alt-tflex-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export PROG_VERSION=""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Автоматизация установки МИС Витакарта (AIS LPU Client).
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="ais-lpu-client"
export PROG_NAME="AIS LPU Client"
export PROG_ICON="ais_lpu_client"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 KiB

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 208 KiB

+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Специализированное программное обеспечение «Автономная станция прослушивания» предназначено для загрузки и прослушивания электронных материалов итогового собеседования.
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="desktopaudiostation"
export PROG_NAME="АС Прослушивания"
export PROG_ICON="desktopaudiostation"
+4 -5
View File
@@ -2,16 +2,15 @@
# info_ru: Установщик "ЕМИАС" - Единая медицинская информационно-аналитическая система
########################################################################
export PROG_URL="https://emias.info/"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-11.0-alt-tkg-wow64"
export WINEPREFIX="emias"
export PROG_NAME="КИС ЕМИАС"
export BASE_PFX="emias_pfx_x64_v01"
export BASE_PFX="none"
export WINEARCH="win64"
export INSTALL_DLL="crypt32"
export WH_WINDOWS_VER="7"
export WH_MAIN_DECORATED="0"
export WH_USE_CPCSP_PROXY="1"
export STAGING_SHARED_MEMORY="1"
export WINE_LARGE_ADDRESS_AWARE="1"
export CPCSP_PROXY_WOW64_VER="0.7.7-alt1.1-em-wow64"
if [[ -f "$2" ]] \
&& [[ $(basename "$2") =~ (kis\.exe|kis_z\.exe) ]]
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Специализированное программное обеспечение «Автономная станция записи» предназначено для записи ответов участников итогового собеседования.
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="isrecordingstation"
export PROG_NAME="АС Записи"
export PROG_ICON="isrecordingstation"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Установщик программного комплекса NetTest (демо-версия)
########################################################################
export PROG_URL="https://www.kpolyakov.spb.ru/prog/nettest/nettget.htm"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-amd64"
export WINEPREFIX="nettest"
export PROG_NAME="NetTest"
export BASE_PFX="none"
+4 -3
View File
@@ -2,15 +2,16 @@
# info_ru: "КИС Олимп" - программно-аналитический комплекс, состоящий из самостоятельных подключаемых модулей.
########################################################################
export PROG_URL="https://olimp.best/"
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="olimp"
export PROG_NAME="КИС Олимп"
export BASE_PFX="olimp_pfx_x86_v01"
export BASE_PFX="olimp_pfx_x86_v04"
export WINEARCH="win32"
export WH_WINDOWS_VER="7"
export INSTALL_DLL="jet40 dotnet45 corefonts lucida opensymbol tahoma cjkfonts mdac28 msxml4 native_oleaut32 vcrun2005"
export INSTALL_DLL="jet40 dotnet45 corefonts lucida opensymbol tahoma cjkfonts mdac28 msxml4 native_oleaut32 vcrun2005 ie8 itss"
export WINEDLLOVERRIDES="d2d1=n"
export WH_MAIN_DECORATED="0"
export FREETYPE_PROPERTIES="truetype:interpreter-version=35"
if [[ -f "$2" ]] \
&& [[ $(basename "$2") =~ (Loader\.exe) ]]
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Это мощный, современный инструмент быстрой и качественной разработки АСУТП
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="scada-krug-2000"
export PROG_NAME="SCADA КРУГ 2000"
export PROG_ICON="krugtaskmanager"
+1 -1
View File
@@ -7,7 +7,7 @@ export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=vulkan"
+1 -1
View File
@@ -7,7 +7,7 @@ export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex18"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
+1 -1
View File
@@ -7,7 +7,7 @@ export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex17"
export WINEPREFIX="tflex"
export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=gdi"
+21 -23
View File
@@ -1,24 +1,22 @@
##### WINE WOW64 #####
e9a8b79dfe12cad1304dca573d73aefe109e3d69b6fff739c8dbb8b2d3c271c6 wine-10.12.1-alt1-wow64.tar.xz
a862761c432f8619caf8100589678a1cbb523787259120ccd4388089d81e3b17 wine-10.18.1-tflex-alt2-wow64.tar.xz
349c707148a23e667970309248bbbf97b4e2a0db59c548e73d9fe9c3f585872c wine-10.18.1-alt1-wow64.tar.xz
90676579fc97b0bdd0cc265b5c728683f8ce8d8998b020ac39d7c26ebf8783d9 wine-11.0-alt-tkg-wow64.tar.xz
f8763bc54a4e1f1407cec8401e9ccb166b7d1aad064dd8875143717f19796bb8 wine-11.0-alt-tflex-wow64.tar.xz
d86724bd1b3a7a798f221a6a84430d37a3f531014756b7de49c0d8444d748bd7 wine-10.9-alt-tflex-wow64.tar.xz
df5509e1f04424d41d734a255acd3695ac1167b73e52189b97b8acc9084f7fa6 wine-10.0-alt-scadoffice-wow64.tar.xz
714687110724f4772d4028fb340ac1c8f9a32f0454c76822c967af9ef06844eb wine-10.0-alt-tkg-wow64.tar.xz
4826028ddd49cc6ec2760be8dbb8ff2353a58323a87c846a8667e41e90851ea1 wine-9.0-alt-tkg-wow64.tar.xz
##### WINE AMD64 #####
009c95bfe2df3f9264c9c5092f3e30ea7a168dd7869046058a718a70739602d4 wine_wh_tflex_10-9_amd64.tar.xz
71d6fdfd23d7988471d345c68e81699b8af931352b03dd216424b398f63c7b12 wine_x_tkg_10-0_amd64.tar.xz
e0a84bb4908c3927954d7eef6b8ac7212e442b8c107d000c6890fec340f96183 wine-9.0.14-alt1-amd64.tar.xz
f1bf1261550ca2928cefacdb724926d3d6d103433d0ff6882ee9783a50d8f4e4 wine-8.8-staging-amd64.tar.xz
61bec1230b37b8fcc69fd45f848b44fd88cc41fcdd5dc3080336d7da63660f40 wine-7.16.1-alt1-amd64.tar.xz
fd209c95a3aa507002374417365b3d1119dbe3a0a6d223034171221a2b187b66 wine-9.0-cx-amd64.tar.xz
7a735f1e00173d8d3e3727aab927c4eb86aca018f39a4e8dfc1936909b8b9654 wine-11.0-alt-tkg-amd64.tar.xz
2f3aa24fcb52a12bac35a77bf088aa8308e2e0ac3bf89f9b3f9e8e3c7090bbe8 wine-10.0-alt-tkg-amd64.tar.xz
4251e75b410268fca9dabc168f838a56f5f02b970c6d4250763da8e791e8880d wine-9.0-alt-tkg-amd64.tar.xz
##### WINE I586 #####
3571c40a787f0386e0160b5d471b1bf11fa2a235b497156cd38198b90bcb4a9f wine_x_tkg_10-0_i586.tar.xz
fb7fdfde96de10a1b3b051bdf2727b6a7c1768b878483726454dd6726e9e0193 wine-9.0.14-alt1-i586-spravkibk.tar.xz
6f86d2220b65b709bf88c6f829a4998de3b929cc2091cd1333a51c32e1491b79 wine-9.0.9-alt1-i586.tar.xz
6fea17fd131f57c2ebf7ca4c60d3c5a9e819afe16e5d0b77ecb750da99ae0e38 wine-7.16.1-alt1-i586.tar.xz
b082dc92c0ed96366353b8a9f62b126276d2476be85d2b37d47a886771a808b6 wine-11.0-alt-tkg-i586.tar.xz
d63ae109e2495d3817172146107d9ddfd0b63a0f76b4d575279ae6b642522795 wine-10.0-alt-tkg-i586.tar.xz
9a3160ae815b2dd008f67bf230b4e440c6b341d770b7c2a4b1a2c50283c7a895 wine-9.0-alt-tkg-i586.tar.xz
##### DXVK #####
d1a86ca53ab7e156e1252d3cf7eed3c66fe0651699cfc9c4ba152024261d8258 dxvk-1.10.1-967.tar.xz
98411effbc1b3611b11c4ca3af2ad29400b08e1c8c380791d6351600a06fb3c7 dxvk-1.10.3-28.tar.xz
061568b51ce99d285ef2d0f1f31aab65b3e6fd34747073859c5a719bec2a7afd dxvk-1.6.1.tar.xz
37ed4a8cd4c2bff3abbf830e6d602c2e0a971eda7c69b3f45834539bc84b1431 dxvk-2.0-116.tar.xz
@@ -114,9 +112,9 @@ b3f56f58b5b764aba564c8b8c69eb12425467d57bf2a6457edff08842af03573 vkd3d-proton-1
edf16d2b37bc77d121d5d81b06b60d3f694e0060c6606e729ceab30de3d27466 vkd3d-proton-sarek-2.6.0.tar.xz
##### CPCSP_PROXY #####
3153088ff28d6af415c3504a421e5382554dbb305f38d5a87dd84df90d680421 wine-cpcsp_proxy-0.6.1-alt1.tar.xz
fbe72bfe3c2c307363782ce2d37589e142b44111f269657b0e516a6b2d6ab8a9 wine-cpcsp_proxy-0.7.3-alt5-wow64.tar.xz
5a0c582f662ac501865f569124c153b43cded72eb98a001eaa7ebd5b2168f1a2 wine-cpcsp_proxy-0.7.7-alt1.1-em-wow64.tar.xz
6f43427148c6f424cd49a406328669e4ec4f21df7bc86f1a6aad2b5c16b50e39 wine-cpcsp_proxy-0.7.7-alt1-wow64.tar.xz
3153088ff28d6af415c3504a421e5382554dbb305f38d5a87dd84df90d680421 wine-cpcsp_proxy-0.6.1-alt1.tar.xz
##### FONTS #####
405bfe3b7c7f80034837c05656535053305727ee4bf1d993521b67b71d08ebc6 extra_fonts_v01.tar.xz
@@ -183,10 +181,6 @@ dfb44ce5e5af7dba1686932c63d6b05e5dd6919a21c78130a7d1d0271b93958e audiorecstatio
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks arial dotnet7 dotnetdesktop7 renderer=gdi
8c6312f2e4e846a98ca4a87fc90ee1917eb28d4caaddde040fb4d2dd05f8c0fe scadaoffice_pfx_x64_v05.tar.xz
# create with wine_x_tkg_10-0_amd64 (universal user: xuser)
# winetricks dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6 dotnet20
ef7e8f1ba785d48e4ea287feed5b79bd630d423e59efadb43da9653adefef218 ais-lpu-client_pfx_x86_v01.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks vcrun2005 vcrun2008 dotnet20sp2 dotnet40 mfc42 7zip
@@ -216,11 +210,15 @@ d16c300b5451e4fad6eeebeca0949367a7bdf1cb1878fc51f0f9dee33744d3a7 emias_pfx_x64_
# create with wine-10.18.1-alt1-wow64 (universal user: xuser)
# winetricks crypt32
66a31bf72aac7354956c0ce8ddb9a2858b291bb9c8b94229b0820b0119ced97f olimp_pfx_x86_v01.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks jet40 dotnet45 corefonts lucida opensymbol tahoma cjkfonts mdac28 msxml4 native_oleaut32 vcrun2005
49cfb047297c958c7005afa0c4ced371e867b33aca33ad7572ecf7dc7b64552a olimp_pfx_x86_v04.tar.xz
# create with wine-10.18.1-alt2-i586
# winetricks jet40 dotnet45 corefonts lucida opensymbol tahoma cjkfonts mdac28 msxml4 native_oleaut32 vcrun2005 ie8 itss
# + psqlodbc_x86.msi installed from script
4fc8ba95190d7d2cd05f60f29fe6af801f99bf046ab75bccd82bf48a600d5fc4 scadoffice_pfx_x64_v06.tar.xz
# create with wine-10.18.1-alt1-wow64 (universal user: xuser)
# winetricks msxml6 gdiplus vcrun6sp6 vcrun2005 ucrtbase2019 vcrun2019 d3dx9 d3dx11_43 d3dx11_42 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 dotnet40 dotnet48 riched20 riched30 msls31 richtx32
##### ADDONS #####
# addons with ODBC, SSH, *.reg
0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb scadoffice_addons_v02.tar.xz
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа «Декларация» позволяет автоматически формировать налоговые декларации по форме 3-НДФЛ. В процессе заполнения Вами данных программа автоматически проверяет их корректность, что уменьшает вероятность появления ошибки.
########################################################################
export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="declaration"
export PROG_NAME="Декларация"
export PROG_ICON="declarac-2"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Программное обеспечение для 3D-графики, предназначенное для проектирования освещения. (Версия 4.4.0.2)
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="dialux"
export PROG_NAME="DIALux"
export PROG_ICON="dialux"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Удобная программа для создания двухмерных схем и чертежей. Основной акцент сделан на проектировании систем тепло-, водо- и газоснабжения, водоочистки, автоматизированных систем управления технологическими процессами (АСУТП), а также планов эвакуации при пожаре и авариях.
########################################################################
export PROG_URL="https://easymnemo.com"
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="easymnemo"
export PROG_NAME="Easymnemo"
export PROG_ICON="easymnemo"
+98 -26
View File
@@ -2,46 +2,118 @@
# info_ru: Программа автоматизации процесса подготовки юридическими и физическими лицами документов для представления в налоговые органы в электронной форме и на бумажном носителе.
########################################################################
export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="nalog"
export PROG_NAME="Налогоплательщик ЮЛ"
export PROG_ICON="npul"
export BASE_PFX="nalog_pfx_x64_v01"
export BASE_PFX="none"
export WINEARCH="win64"
export WH_WINDOWS_VER="10"
export WH_XDG_OPEN="doc"
export INSTALL_DLL="msxml4 msxml6 corefonts wsh57 gdiplus"
export INSTALL_DLL="msxml4 msxml6 corefonts wsh57 gdiplus vb6run"
try_get_page "https://data.nalog.ru/rn77/program/5961229/"
VER_MSI=$(read_page | grep -oP 'NalogUL\d+\.msi' | tail -n 1 | grep -oP '\d+')
VER_MSI_URL="${VER_MSI:0:1}.${VER_MSI:1}" # 492 → 4.92
VER_EXE=$(read_page | grep -oP 'NalogUL\d+\.exe' | tail -n 1 | grep -oP '\d+')
VER_EXE_URL="${VER_EXE:0:1}.${VER_EXE:1:2}.${VER_EXE:3}" # 4924 → 4.92.4
HTML_CONTENT=$(read_page)
AUTOINSTALL_MSI="${WH_TMP_DIR}/NalogUL${VER_MSI}.msi"
AUTOINSTALL_EXE="${WH_TMP_DIR}/NalogUL${VER_EXE}.exe"
# Извлекаем все версии одним проходом (и 3, и 4 цифры, и MSI, и EXE)
declare -A VERSIONS
while IFS= read -r match; do
if [[ -n "$match" ]]; then
ver=$(echo "$match" | grep -oP '\d+')
ext="${match##*.}"
digits="${#ver}"
VERSIONS["${digits}_${ext}"]="$ver"
fi
done < <(echo "$HTML_CONTENT" | grep -oP 'NalogUL\d{3,4}\.(msi|exe)')
prepair_wine
if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_URL}/NalogUL${VER_MSI}.msi" "${AUTOINSTALL_MSI}" ; then
wine_run_install "${AUTOINSTALL_MSI}" /quiet INSTALLDIR="c:\npul"
try_remove_file "${AUTOINSTALL_MSI}"
PRINT_INSTALLER="$(find "$DRIVE_C/npul/INPUTDOC" -name "Печать НД с PDF417*.msi")"
wine_run_install "${PRINT_INSTALLER}" "/q"
# Процедуры конвертации, индексация данных. По завершении процедур программа сама закроется. Признаком успешного завершения будет отсутствие в папке с программой файла setupmarker.ini. Если не принять процедуру, .exe файл обновления не установиться.
wine_run_install "$DRIVE_C/npul/INPUTDOC/inputdoc.exe" go.ini
#TODO: Сделать запуск процедуры в тихом режиме.
# Версия программы (3 цифры, приоритет MSI)
if [[ -n "${VERSIONS[3_msi]}" ]]; then
PROG_VER="${VERSIONS[3_msi]}"
PROG_EXT="msi"
elif [[ -n "${VERSIONS[3_exe]}" ]]; then
PROG_VER="${VERSIONS[3_exe]}"
PROG_EXT="exe"
else
print_error "Не найдена установочная версия программы"
exit 1
fi
if [[ -n "$VER_EXE" ]] \
&& try_download "https://data.nalog.ru/files/nalul/${VER_EXE_URL}/NalogUL${VER_EXE}.exe" "${AUTOINSTALL_EXE}"
then
wine_run_install "${AUTOINSTALL_EXE}" "/SILENT"
try_remove_file "${AUTOINSTALL_EXE}"
# Версия обновления (4 цифры, приоритет EXE)
if [[ -n "${VERSIONS[4_exe]}" ]]; then
UPDATE_VER="${VERSIONS[4_exe]}"
UPDATE_EXT="exe"
elif [[ -n "${VERSIONS[4_msi]}" ]]; then
UPDATE_VER="${VERSIONS[4_msi]}"
UPDATE_EXT="msi"
else
UPDATE_VER=""
UPDATE_EXT=""
fi
PRINT_INSTALLER="$(find "$DRIVE_C/npul/INPUTDOC" -name "Печать НД с PDF417*.msi" | tail -n 1)"
# Формируем URL пути
PROG_URL_PATH="${PROG_VER:0:1}.${PROG_VER:1}"
AUTOINSTALL_PROG="${WH_TMP_DIR}/NalogUL${PROG_VER}.${PROG_EXT}"
if [[ -n "$UPDATE_VER" ]]; then
UPDATE_URL_PATH="${UPDATE_VER:0:1}.${UPDATE_VER:1:2}.${UPDATE_VER:3}"
AUTOINSTALL_UPDATE="${WH_TMP_DIR}/NalogUL${UPDATE_VER}.${UPDATE_EXT}"
fi
prepair_wine
# Устанавливаем основную программу
if [[ "$PROG_EXT" == "msi" ]]; then
if try_download "https://data.nalog.ru/files/nalul/${PROG_URL_PATH}/NalogUL${PROG_VER}.msi" "${AUTOINSTALL_PROG}"; then
wine_run_install "${AUTOINSTALL_PROG}" /quiet /norestart INSTALLDIR="c:\npul"
try_remove_file "${AUTOINSTALL_PROG}"
else
print_error "Не удалось скачать установочный файл MSI"
exit 1
fi
else
if try_download "https://data.nalog.ru/files/nalul/${PROG_URL_PATH}/NalogUL${PROG_VER}.exe" "${AUTOINSTALL_PROG}"; then
wine_run_install "${AUTOINSTALL_PROG}" /VERYSILENT /NORESTART /DIR="c:\npul"
try_remove_file "${AUTOINSTALL_PROG}"
else
print_error "Не удалось скачать установочный файл EXE"
exit 1
fi
fi
# Устанавливаем печать PDF417
PRINT_INSTALLER="$(find "$DRIVE_C/npul/INPUTDOC" -name "Печать НД с PDF417*.msi" | tail -n 1)"
if [[ -n "$PRINT_INSTALLER" ]]; then
wine_run_install "${PRINT_INSTALLER}" "/q"
fi
# Процедуры конвертации, индексация данных
wine_run_install "$DRIVE_C/npul/INPUTDOC/inputdoc.exe" go.ini
# Устанавливаем обновление (если есть)
if [[ -n "$UPDATE_VER" ]]; then
if [[ "$UPDATE_EXT" == "msi" ]]; then
if try_download "https://data.nalog.ru/files/nalul/${UPDATE_URL_PATH}/NalogUL${UPDATE_VER}.msi" "${AUTOINSTALL_UPDATE}"; then
wine_run_install "${AUTOINSTALL_UPDATE}" /quiet /norestart
try_remove_file "${AUTOINSTALL_UPDATE}"
# После обновления может появиться новая версия печати
PRINT_INSTALLER="$(find "$DRIVE_C/npul/INPUTDOC" -name "Печать НД с PDF417*.msi" | tail -n 1)"
if [[ -n "$PRINT_INSTALLER" ]]; then
wine_run_install "${PRINT_INSTALLER}" /quiet /norestart
fi
fi
else
if try_download "https://data.nalog.ru/files/nalul/${UPDATE_URL_PATH}/NalogUL${UPDATE_VER}.exe" "${AUTOINSTALL_UPDATE}"; then
wine_run_install "${AUTOINSTALL_UPDATE}" /VERYSILENT /NORESTART
try_remove_file "${AUTOINSTALL_UPDATE}"
# После обновления может появиться новая версия печати
PRINT_INSTALLER="$(find "$DRIVE_C/npul/INPUTDOC" -name "Печать НД с PDF417*.msi" | tail -n 1)"
if [[ -n "$PRINT_INSTALLER" ]]; then
wine_run_install "${PRINT_INSTALLER}" /quiet /norestart
fi
fi
fi
else
print_info "Дополнительных обновлений не требуется."
fi
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Подготовка документов для государственной регистрации (ППДГР)
########################################################################
export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="ppdgr2"
export PROG_NAME="ППДГР-2"
export PROG_ICON="ppdgr"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Цифровая платформа для обучения и оценки специалистов нефтегазовой отрасли.
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export PROG_NAME="РТСИМ.Карьера"
export WINEPREFIX="rtsim"
export PROG_ICON="rtsim"
+3 -3
View File
@@ -2,12 +2,12 @@
# info_ru: SCAD Office — это программный комплекс для расчёта строительных конструкций.
########################################################################
export PROG_URL="https://scadoffice.ru"
export WH_WINE_USE="wine-8.8-staging-amd64"
export WH_WINE_USE="wine-10.0-alt-scadoffice-wow64"
export WINEPREFIX="scadoffice"
export PROG_NAME="SCAD Office"
export PROG_ICON="scadoffice"
export BASE_PFX="none"
export WH_WINDOWS_VER="10"
export BASE_PFX="scadoffice_pfx_x64_v06"
export WH_WINDOWS_VER="7"
export WINEARCH="win64"
export INSTALL_DLL="dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6" #dotnet20
export WH_XDG_OPEN="rtf"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Справочник кодов обозначения налоговых органов для целей учета налогоплательщиков
########################################################################
export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="soun"
export PROG_NAME="СОУН"
export PROG_ICON="soun"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Программный комплекс для энергетики.
########################################################################
export WH_WINE_USE="wine-9.0.14-alt1-amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-amd64"
export WINEPREFIX="swmanmodus"
export BASE_PFX="none"
export WH_WINDOWS_VER="10"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Программный комплекс СуперОкна для фабрик по изготовлению окон и дверей.
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="swnd"
export PROG_NAME="СуперОкна 8"
export PROG_ICON="swnd"
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Бесплатная версия программы СуперОкна для небольших предприятий.
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-i586"
export WINEPREFIX="swnd"
export PROG_NAME="СуперОкна 8 бесплатная"
export PROG_ICON="swnd"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: Программа проверки файлов на соответствие форматам представления в электронном виде налоговых деклараций, бухгалтерской отчетности.
########################################################################
export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WH_WINE_USE="wine-10.0-alt-tkg-wow64"
export WINEPREFIX="nalog"
export PROG_NAME="Тестер"
export PROG_ICON="tester"
+1 -1
View File
@@ -2,7 +2,7 @@
# info_ru: ZuluGIS 2021 Инженерные расчёты (Полный) 64-бит. Включает ZuluGIS, пакеты расчетов ZuluThermo, ZuluHydro, ZuluDrain, ZuluGaz, ZuluSteam, библиотеки ZuluXTools и ZuluNetTools. Дополнительно в состав пакета входит Microsoft SQL Server Express LocalDB 2012.
########################################################################
export PROG_URL="https://www.politerm.com"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WH_WINE_USE="wine-10.0-alt-tkg-amd64"
export PROG_NAME="ZuluGIS 2021"
export WINEPREFIX="zulugis"
export PROG_ICON="zulugis"
+374 -143
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
SCRIPT_NAME="$(basename "$0")"
##### CHECK ROOT #####
if [[ $(id -u) -eq 0 ]] ; then
@@ -6,49 +7,6 @@ if [[ $(id -u) -eq 0 ]] ; then
exit 1
fi
##### DEFAULT PATH #####
export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH \
LICENSE_FILE AGREEMENT THIRD_PARTY_FILE WH_ICON_TRAY GENERAL WH_WINETRICKS
SCRIPT_NAME="$(basename "$0")"
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
# переменные для установленного WineHelper в систему
WH_VERSION="$(rpm -q winehelper | awk -F'-' '{print $2}')"
USER_WORK_PATH="$HOME/.local/share/$SCRIPT_NAME"
RUN_SCRIPT="/usr/bin/$SCRIPT_NAME"
DATA_PATH="/usr/share/$SCRIPT_NAME"
WH_ICON_PATH="/usr/share/icons/hicolor/scalable/apps/winehelper.svg"
WH_ICON_TRAY="/usr/share/icons/hicolor/symbolic/apps/winehelper-symbolic.svg"
CHANGELOG_FILE="/usr/share/doc/winehelper-$WH_VERSION/CHANGELOG"
LICENSE_FILE="/usr/share/doc/winehelper-$WH_VERSION/LICENSE"
AGREEMENT="/usr/share/doc/winehelper-$WH_VERSION/LICENSE_AGREEMENT"
THIRD_PARTY_FILE="/usr/share/doc/winehelper-$WH_VERSION/THIRD-PARTY"
GENERAL="/usr/share/doc/winehelper-$WH_VERSION/GENERAL"
WH_WINETRICKS="/usr/bin/winetricks"
else
# переменные для тестового запуска WineHelper из репозитория
USER_WORK_PATH="$HOME/test-$SCRIPT_NAME"
RUN_SCRIPT="$(realpath "$0")"
DATA_PATH="$(dirname "$RUN_SCRIPT")"
CHANGELOG_FILE="$DATA_PATH/CHANGELOG"
WH_ICON_PATH="$DATA_PATH/image/gui/winehelper-devel.svg"
WH_ICON_TRAY="$DATA_PATH/image/gui/winehelper-symbolic.svg"
LICENSE_FILE="$DATA_PATH/LICENSE"
AGREEMENT="$DATA_PATH/LICENSE_AGREEMENT"
THIRD_PARTY_FILE="$DATA_PATH/THIRD-PARTY"
GENERAL="$DATA_PATH/GENERAL"
WH_WINETRICKS="/usr/bin/winetricks"
WH_DEVEL="1"
# минимальная проверка синтаксиса скриптов
for self_check_script in "$RUN_SCRIPT" \
"$DATA_PATH/dependencies.sh" "$DATA_PATH/autoinstall"/* \
"$DATA_PATH/manualinstall"/* "$DATA_PATH/testinstall"/* \
"$DATA_PATH/database"/*
do /usr/bin/env bash -n "$self_check_script" || exit 1
done
fi
##### MESSAGES FUNCTIONS #####
if [[ $WH_USE_GUI != "1" ]] ; then
print_error () { printf "\E[31m%s Ошибка: $* %s\e[0m\n" ;}
@@ -65,7 +23,7 @@ fi
print_var () { for vp in $@ ; do echo "${vp}=${!vp}" ; done ;}
fatal () {
print_error "$@ Аварийное завершение работы WineHelper!"
[[ -n "$@" ]] && print_error "$@"
[[ -n "$WINESERVER" ]] && "$WINESERVER" -w
exit 1
}
@@ -80,15 +38,129 @@ print_confirmation () {
return 0
}
##### CHECK NOEXEC FOR /HOME #####
if mount -l | grep -E "[[:space:]]/home[[:space:]]" | grep -q "noexec" ; then
# export WH_DIST_DIR="/opt/winehelper/dist"
# print_warning "/home примонтирован в /etc/fstab с аргументом noexec.\nИспользуем каталог $WH_DIST_DIR"
fatal "/home примонтирован в /etc/fstab с аргументом noexec.\nЗапуск портативной версии wine невозможен из домашнего каталога."
##### DEFAULT PATH #####
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
# переменные для установленного WineHelper в систему
USER_WORK_PATH="$HOME/.local/share/$SCRIPT_NAME"
WH_VERSION="$(rpm -q winehelper | awk -F'-' '{print $2}')"
RUN_SCRIPT="/usr/bin/$SCRIPT_NAME"
DATA_PATH="/usr/share/$SCRIPT_NAME"
WH_ICON_PATH="/usr/share/icons/hicolor/scalable/apps/winehelper.svg"
WH_ICON_TRAY="/usr/share/icons/hicolor/symbolic/apps/winehelper-symbolic.svg"
CHANGELOG_FILE="/usr/share/doc/winehelper-$WH_VERSION/CHANGELOG"
LICENSE_FILE="/usr/share/doc/winehelper-$WH_VERSION/LICENSE"
AGREEMENT="/usr/share/doc/winehelper-$WH_VERSION/LICENSE_AGREEMENT"
THIRD_PARTY_FILE="/usr/share/doc/winehelper-$WH_VERSION/THIRD-PARTY"
GENERAL="/usr/share/doc/winehelper-$WH_VERSION/GENERAL"
WH_CONFIG="$HOME/.config/winehelper.conf"
unset CHANGE_WORK_PATH
if [[ "$1" == "data-path" ]] ; then
USER_WORK_PATH="$2"
CHANGE_WORK_PATH="1"
echo "export USER_WORK_PATH=\"$USER_WORK_PATH\"" > "$WH_CONFIG"
fi
if [[ -f "$WH_CONFIG" ]] ; then
source "$WH_CONFIG"
fi
check_path_rw () {
local check_path="$1"
[[ -z "$check_path" ]] && return 1
if [[ ! -d "$check_path" ]] ; then
mkdir -p "$check_path" || return 1
fi
if [[ -r "$check_path" ]] \
&& [[ -w "$check_path" ]]
then
return 0
fi
return 1
}
# проверка noexec для home и путей до рабочего каталога
if mount -l | grep -E "[[:space:]]/home[[:space:]]" | grep -q "noexec" ; then
WH_NOEXEC_HOME="1"
if [[ "$USER_WORK_PATH" =~ "$HOME" ]] ; then
if [[ $1 == "gui" ]] ; then
/usr/bin/env python3 -m winehelperqt.dialogs.noexec_warning &
fi
fatal \
"/home примонтирован в /etc/fstab с аргументом noexec.
Запуск портативной версии wine невозможен из домашнего каталога!
1 - вы можете либо снять флаг noexec в /etc/fstab:
su -
apt-get install nano
nano /etc/fstab
# тут удаляем флаг noexec напротив /home
# ctrl+o = сохранить изменения, ctrl+x = выход
# можно использовать любой редактор, nano - как пример
# обновляем загрузчик
update-grub
exit
# после перезагрузки, можно приступать к работе с WineHelper
2 - либо изменить рабочий каталог WineHelper
(вне /home и с доступом на чтение-запись для пользователя $USER)
с помощью команды: $SCRIPT_NAME data-path /путь/к/каталогу
"
fi
else
WH_NOEXEC_HOME="0"
fi
if check_path_rw "$USER_WORK_PATH" ; then
print_info "Используется рабочий каталог: $USER_WORK_PATH"
else
fatal \
"Нет доступа на чтение-запись в каталог: $USER_WORK_PATH
Вы можете изменить рабочий каталог для WineHelper с помощью команды:
$SCRIPT_NAME data-path /путь/к/каталогу"
fi
if [[ "$CHANGE_WORK_PATH" == "1" ]] ; then
print_info "Рабочий каталог изменен на: $USER_WORK_PATH"
exit 0
fi
else
export WH_DIST_DIR="$USER_WORK_PATH/dist"
# переменные для тестового запуска WineHelper из репозитория
USER_WORK_PATH="$HOME/test-$SCRIPT_NAME"
RUN_SCRIPT="$(realpath "$0")"
DATA_PATH="$(dirname "$RUN_SCRIPT")"
CHANGELOG_FILE="$DATA_PATH/CHANGELOG"
WH_ICON_PATH="$DATA_PATH/image/gui/winehelper-devel.svg"
WH_ICON_TRAY="$DATA_PATH/image/gui/winehelper-symbolic.svg"
LICENSE_FILE="$DATA_PATH/LICENSE"
AGREEMENT="$DATA_PATH/LICENSE_AGREEMENT"
THIRD_PARTY_FILE="$DATA_PATH/THIRD-PARTY"
GENERAL="$DATA_PATH/GENERAL"
WH_DEVEL="1"
# минимальная проверка синтаксиса скриптов
for self_check_script in "$RUN_SCRIPT" \
"$DATA_PATH/dependencies.sh" "$DATA_PATH/autoinstall"/* \
"$DATA_PATH/manualinstall"/* "$DATA_PATH/testinstall"/* \
"$DATA_PATH/database"/*
do /usr/bin/env bash -n "$self_check_script" || exit 1
done
fi
WH_WINETRICKS="/usr/bin/winetricks"
WH_DIST_DIR="$USER_WORK_PATH/dist"
WH_TMP_DIR="$USER_WORK_PATH/tmp"
export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH \
LICENSE_FILE AGREEMENT THIRD_PARTY_FILE WH_ICON_TRAY GENERAL WH_WINETRICKS \
WH_TMP_DIR WH_DIST_DIR WH_NOEXEC_HOME WH_CONFIG
[[ ! -d "$WH_TMP_DIR" ]] && mkdir -p "$WH_TMP_DIR"
if [[ $1 == "gui" ]] ; then
export WH_USE_GUI="1"
/usr/bin/env python3 "$DATA_PATH/winehelper_gui.py" &
@@ -121,7 +193,6 @@ fi
##### DEFAULT VARIABLES #####
WH_VULKAN_LIBDIR="$USER_WORK_PATH/vulkan"
WH_PREFIXES_DIR="$USER_WORK_PATH/prefixes"
WH_TMP_DIR="$USER_WORK_PATH/tmp"
WH_IMAGE_PATH="$DATA_PATH/image"
WH_DB_DIR="$DATA_PATH/database"
@@ -146,7 +217,7 @@ check_variables WINEFSYNC "0"
check_variables WINEUSERNAME "xuser"
check_variables WINEARCH "win64" # or "win32"
check_variables WH_WINE_USE "wine-10.18.1-alt1-wow64" # or system
check_variables WH_WINE_USE "wine-11.0-alt-tkg-wow64" # or system
check_variables WH_USE_CPCSP_PROXY "0"
check_variables CPCSP_PROXY_X86_64_VER "0.6.1-alt1"
@@ -646,6 +717,8 @@ create_desktop () {
# Создаем .desktop файл
create_new_dir "$WH_MENU_DIR"
local startup_wm_class
startup_wm_class="$(basename "$exe_file" | sed 's/ //g')"
{
echo "[Desktop Entry]"
echo "Name=$name_desktop"
@@ -653,9 +726,10 @@ create_desktop () {
echo "Type=Application"
echo "Categories=WineHelper;"
echo "StartupNotify=true"
echo "Terminal=false"
echo "Path=$DATA_PATH"
echo "Icon=$icon_file"
echo "StartupWMClass=$(basename "$exe_file")"
echo "StartupWMClass=${startup_wm_class}"
} > "$USER_WORK_PATH/$desktop_filename.desktop"
chmod +x "$USER_WORK_PATH/$desktop_filename.desktop"
@@ -717,7 +791,9 @@ EOF
# Обновляем кэш desktop-файлов
update-desktop-database "$HOME/.local/share/applications"
if [[ "$desktop_filename_arg" != "nocopy" ]] ; then
if [[ "$desktop_filename_arg" != "nocopy" ]] \
&& [[ "$WH_NOEXEC_HOME" != "1" ]]
then
desktop_path="$(xdg-user-dir DESKTOP)"
print_info "В меню и на рабочем столе создан ярлык: $desktop_filename.desktop"
cp -f "$USER_WORK_PATH/$desktop_filename.desktop" "$desktop_path"
@@ -725,22 +801,36 @@ EOF
print_info "В меню создан ярлык: $desktop_filename.desktop"
fi
if [[ -n "$INSTALL_SCRIPT_NAME" ]] \
&& [[ -f "$exe_file" ]]
then
{
echo '#!/usr/bin/env bash'
echo "# cmd_name: $INSTALL_SCRIPT_NAME"
} > "$exe_file".whdb
if [[ -f "$exe_file" ]] ; then
if [[ -n "$INSTALL_SCRIPT_NAME" ]] && [[ -f "$INSTALL_SCRIPT" ]] ; then
{
echo '#!/usr/bin/env bash'
echo "# cmd_name: $INSTALL_SCRIPT_NAME"
} > "$exe_file".whdb
grep -e "info_" -e "#####" -e "PROG_URL=" -e "WINEPREFIX=" -e "INSTALL_DLL=" \
-e "PROG_NAME=" -e "PROG_ICON=" -e "var_" -e "WH_MAIN_DECORATED" \
-e "WH_VIRTUAL_DESKTOP" -e "WINE_TOP_WINDOW" -e "WH_FONT_SMOOTHING "\
-e "WH_FONT_MSS_REPLACE" -e "FREETYPE_PROPERTIES" -e "WINE_D3D_CONFIG" \
-e "WH_USE_MESA_GL_OVERRIDE" \
"$INSTALL_SCRIPT" | awk '{$1=$1;print}' >> "$exe_file".whdb
grep -e "info_" -e "#####" -e "PROG_URL=" \
-e "WINEPREFIX=" -e "INSTALL_DLL=" \
-e "PROG_NAME=" -e "PROG_ICON=" -e "var_" \
-e "WINEDLLOVERRIDES" -e "WH_MAIN_DECORATED" \
-e "WH_VIRTUAL_DESKTOP" -e "WH_FONT_SMOOTHING" \
-e "WH_FONT_MSS_REPLACE" -e "FREETYPE_PROPERTIES" \
-e "WINE_D3D_CONFIG" -e "WH_USE_MESA_GL_OVERRIDE" \
"$INSTALL_SCRIPT" | awk '{$1=$1;print}' >> "$exe_file".whdb
print_info "Создан файл настроек для $exe_file"
print_info "Создан файл настроек для $exe_file"
elif [[ ! -f "$exe_file".whdb ]] ; then
# Создаем минимальный .whdb файл при ручном создании ярлыка
local prefix_name
prefix_name="$(basename "$WINEPREFIX")"
cat > "$exe_file".whdb <<EOF
#!/usr/bin/env bash
# info_ru: $name_desktop
########################################################################
export PROG_NAME="$name_desktop"
export WINEPREFIX="$prefix_name"
EOF
print_info "Создан минимальный файл настроек для $exe_file"
fi
fi
}
@@ -781,6 +871,8 @@ check_installed_programs () {
elif [[ "$desktop_file" =~ ${2}.desktop ]] ; then
export EXE_PATH
return 0
elif [[ -f "$2" ]] ; then
return 0
fi
;;
*)
@@ -902,6 +994,13 @@ init_wine_ver () {
try_remove_dir "$WINEDIR/files"
fi
if [[ ! -d "$WINEDIR/lib64/wine" ]] \
&& [[ -d "$WINEDIR/lib/wine/x86_64-unix" ]]
then
create_new_dir "$WINEDIR/lib64/"
try_force_link_dir "$WINEDIR/lib/wine/" "$WINEDIR/lib64/"
fi
if [[ ! -f "$WINEDIR/version" ]] ; then
echo "$WH_WINE_USE" > "$WINEDIR/version"
fi
@@ -913,9 +1012,49 @@ init_wine_ver () {
check_deps_i586
fi
if [[ $WH_USE_CPCSP_PROXY == "1" ]] ; then
check_variables "UPDATE_CPCSP_PROXY" "0"
local cpcsp_proxy_ver
if [[ $WH_WINE_WOW64 == "1" ]]
then cpcsp_proxy_ver="$CPCSP_PROXY_WOW64_VER"
else cpcsp_proxy_ver="$CPCSP_PROXY_X86_64_VER"
fi
if [[ ! -f "$WINEDIR/cpcsp_proxy.ver" ]] \
|| ! grep -q "$cpcsp_proxy_ver" "$WINEDIR/cpcsp_proxy.ver"
then
export UPDATE_CPCSP_PROXY="1"
local cpcsp_proxy_name="wine-cpcsp_proxy-$cpcsp_proxy_ver"
local cpcsp_proxy_url="$CLOUD_URL/$cpcsp_proxy_name.tar.xz"
try_download cloud "$cpcsp_proxy_url" "$WH_TMP_DIR/$cpcsp_proxy_name.tar.xz" check256sum
unpack "$WH_TMP_DIR/$cpcsp_proxy_name.tar.xz" "$WH_TMP_DIR"
if [[ $WH_WINE_WOW64 == "1" ]] ; then
for dir_name in x86_64-unix i386-windows x86_64-windows ; do
if [[ -f "$WINEDIR/lib64/wine/$dir_name/cpcsp_proxy.dll" ]] ; then
try_remove_file "$WINEDIR/lib64/wine/$dir_name/cpcsp_proxy.dll"
fi
cp -f "$WH_TMP_DIR/$cpcsp_proxy_name/$dir_name"/* "$WINEDIR/lib64/wine/$dir_name/"
done
else
for dir_name in i386-unix i386-windows ; do
cp -f "$WH_TMP_DIR/$cpcsp_proxy_name/$dir_name"/* "$WINEDIR/lib/wine/$dir_name/"
done
if [[ -d "$WINEDIR/lib64" ]] ; then
for dir_name in x86_64-unix x86_64-windows ; do
cp -f "$WH_TMP_DIR/$cpcsp_proxy_name/$dir_name"/* "$WINEDIR/lib64/wine/$dir_name/"
done
fi
fi
try_remove_dir "$WH_TMP_DIR/$cpcsp_proxy_name"
echo "$cpcsp_proxy_ver" > "$WINEDIR/cpcsp_proxy.ver"
fi
fi
export WINE="$WINEDIR/bin/wine"
export WINELOADER="$WINEDIR/bin/wine"
export WINESERVER="$WINEDIR/bin/wineserver"
export WINEDATADIR="$WINEDIR/share/wine"
if [[ -n "${PATH}" ]]
then export PATH="$WINEDIR/bin:${PATH}"
@@ -925,13 +1064,6 @@ init_wine_ver () {
var_ld_library_path_update "$WINEDIR/lib"
export WINEDLLPATH="$WINEDIR/lib/wine"
if [[ ! -d "$WINEDIR/lib64/wine" ]] \
&& [[ -d "$WINEDIR/lib/wine/x86_64-unix" ]]
then
create_new_dir "$WINEDIR/lib64/"
try_force_link_dir "$WINEDIR/lib/wine/" "$WINEDIR/lib64/"
fi
if [[ -d "$WINEDIR/lib64" ]] \
&& [[ ! -L "$WINEDIR/lib64/wine" ]]
then
@@ -945,34 +1077,6 @@ init_wine_ver () {
export GST_PLUGIN_SYSTEM_PATH_1_0+=":$WINEDIR/lib64/gstreamer-1.0"
fi
fi
if [[ $WH_USE_CPCSP_PROXY == "1" ]] ; then
local cpcsp_proxy_ver
if [[ $WH_WINE_WOW64 == "1" ]]
then cpcsp_proxy_ver="$CPCSP_PROXY_WOW64_VER"
else cpcsp_proxy_ver="$CPCSP_PROXY_X86_64_VER"
fi
if [[ ! -f "$WINEDIR/cpcsp_proxy.ver" ]] \
|| ! grep -q "$cpcsp_proxy_ver" "$WINEDIR/cpcsp_proxy.ver"
then
CPCSP_PROXY_NAME="wine-cpcsp_proxy-$cpcsp_proxy_ver"
CPCSP_PROXY_URL="$CLOUD_URL/$CPCSP_PROXY_NAME.tar.xz"
try_download cloud "$CPCSP_PROXY_URL" "$WH_TMP_DIR/$CPCSP_PROXY_NAME.tar.xz" check256sum
unpack "$WH_TMP_DIR/$CPCSP_PROXY_NAME.tar.xz" "$WH_TMP_DIR"
if [[ $WH_WINE_WOW64 == "1" ]] ; then
cp -fr "$WH_TMP_DIR/$CPCSP_PROXY_NAME/"* "$WINEDIR/lib64/wine/"
else
cp -fr "$WH_TMP_DIR/$CPCSP_PROXY_NAME/"i386-* "$WINEDIR/lib/wine/"
if [[ -d "$WINEDIR/lib64" ]] ; then
cp -fr "$WH_TMP_DIR/$CPCSP_PROXY_NAME/"x86_64-* "$WINEDIR/lib64/wine/"
fi
fi
try_remove_dir "$WH_TMP_DIR/$CPCSP_PROXY_NAME"
echo "$cpcsp_proxy_ver" > "$WINEDIR/cpcsp_proxy.ver"
fi
fi
else
# use system WINE
if [[ ! -f "/usr/bin/wine" ]] ; then
@@ -1150,7 +1254,12 @@ check_prefix_var () {
fi
export PREFIX_NAME="$(basename "$WINEPREFIX")"
print_info "Выбран префикс: $PREFIX_NAME"
# Выводим сообщение только при смене префикса, чтобы избежать дублирования
if [[ "$PREFIX_NAME" != "${WH_LAST_PREFIX_NAME:-}" ]] ; then
print_info "Выбран префикс: $PREFIX_NAME"
export WH_LAST_PREFIX_NAME="$PREFIX_NAME"
fi
return 0
}
@@ -1220,16 +1329,18 @@ init_wineprefix () {
wait_wineserver
fi
local winver
if [[ "${WH_WINDOWS_VER,,}" == "xp64" ]]
then winver="xp 64"
else winver="$WH_WINDOWS_VER"
fi
if [[ -f "$WINEPREFIX/system.reg" ]] \
&& ! grep -iq "Microsoft Windows $WH_WINDOWS_VER" "$WINEPREFIX/system.reg"
&& ! grep -iq "Microsoft Windows ${winver}\"" "$WINEPREFIX/system.reg"
then
if [[ $(echo "$WH_WINDOWS_VER" | sed 's/.*/\L&/') == "xp" ]] \
&& [[ "$WINEARCH" != "win32" ]]
then export WH_WINDOWS_VER="xp64"
fi
"$WINELOADER" winecfg -v $(echo "win${WH_WINDOWS_VER}" | sed 's/.*/\L&/')
[[ "$winver" == "xp 64" ]] && winver="xp64"
"$WINELOADER" winecfg -v $(echo "win${winver}" | sed 's/.*/\L&/')
wait_wineserver
print_info "Windows версия изменена на win${WH_WINDOWS_VER}"
print_info "Windows версия изменена на win${winver}"
fi
if [[ $WH_USE_MESA_GL_OVERRIDE == "1" ]] \
@@ -1307,11 +1418,13 @@ init_wineprefix () {
# добавление ассоциаций файлов для запуска нативного приложения из wine
# пример переменной: WH_XDG_OPEN="txt doc pdf"
check_variables WH_XDG_OPEN "0"
check_variables WH_XDG_OPEN "default"
local WRAPPER="${WH_TMP_DIR}/wh-xdg-open.sh"
local XDG_OPEN_REG="Software\Classes\xdg-open\shell\open\command"
if [[ $WH_XDG_OPEN != "0" ]] ; then
if [[ $WH_XDG_OPEN == "default" ]] ; then
: # пропускаем изменения в реестре
elif [[ $WH_XDG_OPEN != "0" ]] ; then
# проверяем на наличие запрещённых расширений
local forbidden_extensions="cpl dll exe lnk msi"
for ext in $WH_XDG_OPEN; do
@@ -1351,16 +1464,19 @@ init_wineprefix () {
# настраиваем префикс для работы с cpcsp_proxy
if [[ $WH_USE_CPCSP_PROXY == "1" ]] ; then
if ! grep -q "cpcsp_proxy.dll" "$WINEPREFIX/system.reg" \
|| [[ $REBOOT_PFX == "1" ]]
if [[ $WH_FORCE_UPDATE_CERT == "1" ]] \
|| [[ $UPDATE_CPCSP_PROXY == "1" ]] \
|| [[ $REBOOT_PFX == "1" ]] \
|| ! grep -q "cpcsp_proxy.dll" "$WINEPREFIX/system.reg"
then
print_info "Запускаем настройку cpcsp_proxy..."
CPCSP_PROXY_OK="0"
try_copy_wine_dll_to_pfx_64 "cpcsp_proxy.dll"
try_copy_wine_dll_to_pfx_32 "cpcsp_proxy.dll"
if [[ $WH_WINE_WOW64 == "1" ]] ; then
print_info "Запускаем настройку cpcsp_proxy версии $CPCSP_PROXY_WOW64_VER"
print_info "Запускаем регистрацию 64-битного cpcsp_proxy.dll..."
env WINEDEBUG="fixme-all" "$WINE" "C:\\windows\\system32\\regsvr32.exe" \
/s /n /i cpcsp_proxy.dll 2>&1 | tee "$WINEPREFIX/cpcsp_setup.log"
@@ -1371,6 +1487,8 @@ init_wineprefix () {
/s /n /i cpcsp_proxy.dll 2>&1 | tee -a "$WINEPREFIX/cpcsp_setup.log"
wait_wineserver
else
print_info "Запускаем настройку cpcsp_proxy версии $CPCSP_PROXY_X86_64_VER"
try_copy_wine_dll_to_pfx_64 "cpcsp_proxy_setup.exe"
try_copy_wine_dll_to_pfx_32 "cpcsp_proxy_setup.exe"
@@ -1388,8 +1506,14 @@ init_wineprefix () {
done
fi
if grep -q "failed to load /opt/cprocsp/" "$WINEPREFIX/cpcsp_setup.log" ; then
print_error "Проверьте правильность установки КриптоПро в системе.\n Инструкция: https://www.altlinux.org/CryptoPro"
if [[ ! -d "/opt/cprocsp/" ]] \
|| grep -q "failed to load /opt/cprocsp/" "$WINEPREFIX/cpcsp_setup.log"
then
print_error "Проверьте правильность установки КриптоПро в системе!
Официальный сайт КриптоПро: https://cryptopro.ru/products/csp
Инструкция установки КриптоПро в систему: https://www.altlinux.org/CryptoPro
"
else
CPCSP_PROXY_OK="1"
fi
@@ -1397,7 +1521,7 @@ init_wineprefix () {
if [[ $CPCSP_PROXY_OK == "1" ]]
then print_info "Настройка cpcsp_proxy успешно завершена."
else fatal "Ошибка во время настройки cpcsp_proxy."
else fatal
fi
fi
fi
@@ -1423,8 +1547,8 @@ init_wineprefix () {
fi
for var in WH_WINE_USE BASE_PFX WINEARCH WH_WINDOWS_VER WINEESYNC WINEFSYNC \
STAGING_SHARED_MEMORY WINE_LARGE_ADDRESS_AWARE WH_USE_SHADER_CACHE WH_USE_WINE_DXGI \
WINE_CPU_TOPOLOGY DXVK_VER VKD3D_VER WH_XDG_OPEN WH_USE_CPCSP_PROXY WH_USE_EXTRA_FONTS \
WINEUSERNAME
WINE_CPU_TOPOLOGY DXVK_VER VKD3D_VER WH_XDG_OPEN WH_USE_EXTRA_FONTS \
WINEUSERNAME WH_USE_CPCSP_PROXY CPCSP_PROXY_X86_64_VER CPCSP_PROXY_WOW64_VER
do
update_last_conf_var "$var" "${!var}"
done
@@ -1533,7 +1657,13 @@ prepair_wine () {
init_dxvk "$DXVK_VER"
init_vkd3d "$VKD3D_VER"
[[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud"
if [[ "$MANGOHUD" == 1 ]] ; then
if command -v mangohud &>/dev/null ; then
MANGOHUD_RUN="mangohud"
else
print_error "mangohud не найден в системе"
fi
fi
}
wine_regfile () {
@@ -1553,12 +1683,12 @@ wine_regfile () {
wine_run () {
local wh_add_args win_file_exec win_file_path win_file_name
if [[ $1 =~ (winecfg|regedit|winefile|wineconsole|control) ]] ; then
if [[ $1 =~ (winecfg|regedit|winefile|wineconsole|control|uninstaller) ]] ; then
win_file_exec="$1"
win_file_name="$win_file_exec"
win_file_path="$DRIVE_C"
wh_add_args=""
elif [[ $1 =~ \.dll$ ]] ; then
elif [[ "${1,,}" =~ \.(dll|ocx)$ ]] ; then
wine_regfile regsvr32 /s "$@"
return 0
elif [[ -f "$1" ]] ; then
@@ -1604,6 +1734,32 @@ wine_run () {
echo -e "\n##### Лог WINE #####" | tee -a "$log_file"
$MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" 2>&1 | tee -a "$log_file"
# Проверка размера лога и создание архива при превышении порога
local MAX_LOG_SIZE_MB=10
local MAX_LOG_SIZE_BYTES=$((MAX_LOG_SIZE_MB * 1048576))
local log_size_bytes log_size_mb
log_size_bytes=$(stat -c%s "$log_file" 2>/dev/null || echo 0)
log_size_mb=$((log_size_bytes / 1048576))
if (( log_size_bytes > MAX_LOG_SIZE_BYTES )); then
local timestamp archive_name archive_path
timestamp=$(date +"%d.%m.%Y-%H.%M")
archive_name="log_${PREFIX_NAME}_${win_file_name%.*}_${timestamp}.tar.xz"
archive_path="$log_dir/$archive_name"
print_warning "Файл лога больше ${MAX_LOG_SIZE_MB}Мб (размер: ${log_size_mb}Мб)."
print_warning "Создаем сжатый архив: $archive_name"
tar -cJf "$archive_path" -C "$log_dir" "$(basename "$log_file")"
if [[ -f "$archive_path" ]]; then
print_ok "Архив успешно создан: $archive_path"
rm -f "$log_file"
else
print_error "Не удалось создать архив: $archive_path"
fi
fi
else
$MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@"
fi
@@ -1612,9 +1768,47 @@ wine_run () {
cd "$DRIVE_C"
}
wine_debug_run () {
local winedbg_args win_file_exec win_file_path win_file_name wh_add_args
winedbg_args="$1"
[[ "$winedbg_args" == "--interactive" ]] && winedbg_args=""
shift
if [[ -f "$1" ]]; then
win_file_exec="$(readlink -f "$1")"
win_file_path="$(dirname "$win_file_exec")"
win_file_name="$(basename "$win_file_exec")"
else
fatal "Файл не найден: $1"
fi
shift
cd "$win_file_path"
local log_dir log_file
log_dir="$HOME/winehelper_backup_log"
log_file="$log_dir/winedbg_${PREFIX_NAME}_${win_file_name%.*}.log"
create_new_dir "$log_dir"
date > "$log_file"
echo -e "\n##### Основные переменные #####" | tee -a "$log_file"
env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" -e "LD_" \
| grep -v "ICON" | sort | tee -a "$log_file"
echo -e "\n##### WineHelper Debug Mode: winedbg $winedbg_args #####" | tee -a "$log_file"
print_info "Запуск отладчика (режим: $winedbg_args)"
print_warning "Лог отладки будет сохранен по пути: $log_file"
"$WINELOADER" winedbg $winedbg_args "$win_file_exec" "$@" 2>&1 | tee -a "$log_file"
wait_wineserver
cd "$DRIVE_C"
}
wine_run_install () {
print_info "Запускаем установку: $1."
case "$WH_INSTALL_MODE" in
"another") print_warning "Используется скрипт сторонний установки!" ;;
"manual") print_warning "Рекомендуется не менять пути для установки приложения!" ;;
"test") print_warning "Установка приложения из списка экспериментальных скриптов." ;;
esac
@@ -1643,6 +1837,9 @@ run_autoinstall () {
elif [[ -f "$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then
INSTALL_SCRIPT="$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME"
WH_INSTALL_MODE="test"
elif [[ -f "$1" ]] ; then
INSTALL_SCRIPT="$1"
WH_INSTALL_MODE="another"
else
INSTALL_SCRIPT="0"
fi
@@ -1994,8 +2191,8 @@ create_prefix() {
prefix_name=${prefix_name:-default}
if [[ ! "$prefix_name" =~ ^[a-zA-Z0-9_.-]+$ ]] ; then
fatal "Имя префикса может содержать только латинские буквы, цифры, точки, дефисы и подчеркивания"
if [[ ! "$prefix_name" =~ ^[a-zA-Z0-9_-]+$ ]] ; then
fatal "Имя префикса может содержать только латинские буквы, цифры, дефисы и подчеркивания"
fi
if [[ -d "$WH_PREFIXES_DIR/$prefix_name" ]] ; then
@@ -2082,7 +2279,7 @@ remove_winehelper () {
# Удаление desktop-файлов
for desktop_file in "$(xdg-user-dir DESKTOP)"/*.desktop; do
if grep -q "Exec=env \"$RUN_SCRIPT\"" "$desktop_file"; then
if [[ -f "$desktop_file" ]] && grep -q "Exec=env \"$RUN_SCRIPT\"" "$desktop_file"; then
try_remove_file "$desktop_file"
fi
done
@@ -2170,9 +2367,9 @@ backup_prefix() {
local backup_base_dir backup_archive_name backup_dest_path temp_backup_dir temp_prefix_dir temp_users_dir
backup_base_dir="$HOME/winehelper_backup_log"
create_new_dir "$backup_base_dir"
backup_archive_name="backup_${PREFIX_NAME}_$(date +%d.%m.%Y-%H.%M.%S).whpack"
backup_archive_name="backup_${PREFIX_NAME}_$(date +%d.%m.%Y-%H.%M).whpack"
backup_dest_path="$backup_base_dir/$backup_archive_name"
temp_backup_dir="$WH_TMP_DIR/backup_${PREFIX_NAME}_$(date +%d.%m.%Y-%H.%M.%S)"
temp_backup_dir="$WH_TMP_DIR/backup_${PREFIX_NAME}_$(date +%d.%m.%Y-%H.%M)"
temp_prefix_dir="$temp_backup_dir/prefixes/$PREFIX_NAME"
temp_users_dir="$temp_prefix_dir/drive_c/users"
@@ -2205,13 +2402,11 @@ backup_prefix() {
return 1
fi
if [[ -n "$WH_WINE_USE" ]] \
&& [[ $WH_WINE_USE != system* ]] \
&& [[ -d "$WH_DIST_DIR/$WH_WINE_USE" ]]
then
if [[ $WH_WINE_USE != system* ]] ; then
init_wine_ver
print_info "Копирование используемой версии WINE: $WH_WINE_USE"
if cp -a "$WH_DIST_DIR/$WH_WINE_USE" "$temp_backup_dir/dist/"
if cp -aL "$WH_DIST_DIR/$WH_WINE_USE" "$temp_backup_dir/dist/"
then print_ok "WINE скопирован."
else fatal "Не удалось скопировать WINE."
fi
@@ -2221,7 +2416,7 @@ backup_prefix() {
echo "$PREFIX_NAME" > "$temp_backup_dir/prefix_name.whmeta"
print_info "Создание squashfs архива..."
if mksquashfs "$temp_backup_dir" "$backup_dest_path" -comp zstd ; then
if mksquashfs "$temp_backup_dir" "$backup_dest_path" -comp xz ; then
print_ok "Архив префикса $PREFIX_NAME успешно создан по пути:\n$backup_dest_path"
else
print_error "Не удалось создать архив префикса $PREFIX_NAME."
@@ -2285,7 +2480,7 @@ restore_prefix() {
if [[ -d "$WH_PREFIXES_DIR/$prefix_name" ]] ; then
try_remove_dir "$temp_extract_dir"
fatal "Префикс $prefix_name уже существует!\n Удалите его, если действительно желаете восстановить префикс заново.\n Команда для удаления: $SCRIPT_NAME remove-prefix $prefix_name"
fatal "Префикс $prefix_name уже существует!\n Удалите его перед восстановлением префикса заново.\n Команда для удаления: $SCRIPT_NAME remove-prefix $prefix_name"
fi
if [[ -d "$temp_extract_dir/prefixes/$prefix_name" ]] ; then
@@ -2306,16 +2501,17 @@ restore_prefix() {
try_remove_dir "$temp_extract_dir"
fatal "Не удалось восстановить префикс $prefix_name."
else
print_ok "Префикс $prefix_name восстановлен."
export WINEPREFIX="$WH_PREFIXES_DIR/$prefix_name"
if [[ -f "$WINEPREFIX/last.conf" ]] ; then
source "$WINEPREFIX/last.conf"
export REBOOT_PFX="1"
prepair_wine
if [[ -f "$WINEPREFIX/restore_pfx.sh" ]] ; then
source "$WINEPREFIX/restore_pfx.sh"
try_copy_file "$WINEPREFIX/restore_pfx.sh" "$WH_TMP_DIR/restore_${prefix_name}_pfx.sh"
source "$WH_TMP_DIR/restore_${prefix_name}_pfx.sh"
fi
fi
print_ok "Префикс $prefix_name восстановлен."
if [[ -f "$WH_PREFIXES_DIR/$prefix_name/desktop.list" ]] ; then
print_info "Восстановление ярлыков для префикса $prefix_name..."
@@ -2342,6 +2538,7 @@ restore_prefix() {
fi
try_remove_dir "$temp_extract_dir"
try_remove_file "$WH_TMP_DIR/restore_${prefix_name}_pfx.sh"
print_ok "Полное восстановление префикса $prefix_name завершено."
return 0
}
@@ -2528,7 +2725,6 @@ run_install_vkd3d() {
run_change_wine_version() {
local new_version="$1"
check_prefix_var
init_database
if [[ -z "$new_version" ]]; then
@@ -2575,13 +2771,19 @@ wh_info () {
install list список возможных установочных скриптов
install [скрипт] запустить скрипт установки программы
install [скрипт] --clear-pfx не использовать готовый префикс для установки ПО
install \"путь/до/скрипта\" запустить сторонний скрипт установки
install-dxvk [версия|none|list] установить, удалить или показать версии DXVK
install-vkd3d [версия|none|list] установить, удалить или показать версии VKD3D
change-wine [версия] изменить версию Wine для текущего префикса
installed список установленных программ
run [программа] запуск программы (отладка)
run [программа] запуск программы
debug [флаги] [программа] запуск программы в отладчике winedbg
Флаги:
--auto, -a автоматический backtrace
--gdb, -g режим gdb
--interactive, -i интерактивный режим
remove-all удалить WineHelper и все связанные данные
create-prefix создать префикс
remove-prefix [имя_префикса] удалить префикс и все связанные данные
@@ -2589,6 +2791,16 @@ wh_info () {
restore-prefix \"путь/до/whpack\" восстановить префикс из резервной копии
clear-winetricks-cache очистить кэш Winetricks
winecfg запуск wine конфигуратора для префикса
winereg запуск редактора реестра для префикса
winefile запуск файлового менеджера wine
wineconsole запуск терминала wine (cmd.exe)
control запуск панели управления wine
uninstaller запуск удаления программ wine
winetricks [компонент] автоматическая установка дополнительного компонента в префикс
killall остановить все процессы Wine
run-in-prefix <префикс> <файл> запустить файл в указанном префиксе
Параметры:
--help показать эту справку и выйти
--version показать информацию о пакете и его версии
@@ -2605,9 +2817,8 @@ create_new_dir "$WH_PREFIXES_DIR"
create_new_dir "$WH_VULKAN_LIBDIR"
if [[ $WH_DEVEL != "1" ]] \
&& [[ -d "$HOME/.local/share/$SCRIPT_NAME" ]] \
&& [[ ! -L "$HOME/.winehelper" ]]
then try_force_link_dir "$HOME/.local/share/$SCRIPT_NAME" "$HOME/.winehelper"
then try_force_link_dir "$USER_WORK_PATH" "$HOME/.winehelper"
fi
if [[ -n "$1" ]] ; then
@@ -2627,6 +2838,7 @@ case "$arg1" in
winefile|explorer) prepair_wine ; wine_run "winefile" ;;
wineconsole|cmd) prepair_wine ; wine_run "wineconsole" ;;
control) prepair_wine ; wine_run "control" ;;
uninstaller) prepair_wine ; wine_run "uninstaller" ;;
winetricks) prepair_wine ; "$WH_WINETRICKS" -q "$@" ;;
desktop) create_desktop "$@" ; exit 0 ;;
install|-i) run_autoinstall "$@" ;;
@@ -2651,6 +2863,22 @@ case "$arg1" in
wine_run "$WIN_FILE_EXEC" "$@"
fi
;;
debug)
case "$1" in
--gdb|-g) debug_flag="--gdb" ;;
--interactive|-i) debug_flag="--interactive" ;;
--auto|-a) debug_flag="--auto" ;;
*) fatal "Неизвестный флаг отладки!" ;;
esac
shift
if check_installed_programs check_only "$1" ; then
WIN_FILE_EXEC="$(readlink -f "$EXE_PATH")"
shift
prepair_wine
wine_debug_run $debug_flag "$WIN_FILE_EXEC" "$@"
fi
;;
*)
if [[ -f "$arg1" ]] ; then
WIN_FILE_EXEC="$(readlink -f "$arg1")"
@@ -2665,6 +2893,9 @@ case "$arg1" in
else
wine_run "$WIN_FILE_EXEC" "$@"
fi
elif [[ "${arg1,,}" =~ \.dll ]] ; then
prepair_wine
wine_run "$arg1"
else
print_error "Команды $arg1 не существует."
wh_info
+1321 -3230
View File
File diff suppressed because it is too large. Load diff
+72
View File
@@ -0,0 +1,72 @@
"""
GUI пакет для winehelper.
Модульная структура:
- dialogs: Диалоги (выбор версий, настройки и т.д.)
- widgets: Кастомные виджеты
- services: Бизнес-логика (кэширование, установка и т.д.)
- parsers: Парсеры (sha256sum.list, winetricks output)
- utils: Утилиты (обработчики логов и т.д.)
"""
# Parsers
from winehelperqt.parsers.sha256_parser import Sha256Parser
from winehelperqt.parsers.winetricks_parser import WinetricksOutputParser
from winehelperqt.parsers.script_parser import ScriptParser
# Utils
from winehelperqt.utils.log_handler import LogProgressHandler, MultiLogHandler
from winehelperqt.utils.cache_service import CacheService, FileCacheService
# Services
from winehelperqt.services.winetricks_service import WinetricksCacheService
from winehelperqt.services.winetricks_service import WinetricksLogReader
from winehelperqt.services.prefix_manager import PrefixManager
from winehelperqt.services.process_handler import ProcessHandler
from winehelperqt.services.process_handler import CommandRunner
from winehelperqt.services.desktop_file_manager import DesktopFileManager
from winehelperqt.services.script_manager import ScriptManager
from winehelperqt.services.script_manager import ScriptInfo
from winehelperqt.services.installation_manager import InstallationManager
from winehelperqt.services.app_launcher import AppLauncher
from winehelperqt.services.settings_manager import SettingsManager
# Widgets
from winehelperqt.widgets.icon_manager import IconManager
# Dialogs
from winehelperqt.dialogs.winetricks_manager import WinetricksManagerDialog
from winehelperqt.dialogs.noexec_warning import NoExecWarningDialog
__all__ = [
# Parsers
'Sha256Parser',
'WinetricksOutputParser',
'ScriptParser',
# Utils
'LogProgressHandler',
'MultiLogHandler',
'CacheService',
'FileCacheService',
# Services
'WinetricksCacheService',
'WinetricksLogReader',
'PrefixManager',
'ProcessHandler',
'CommandRunner',
'DesktopFileManager',
'ScriptManager',
'ScriptInfo',
'InstallationManager',
'AppLauncher',
'SettingsManager',
# Widgets
'IconManager',
# Dialogs
'WinetricksManagerDialog',
'NoExecWarningDialog',
]
+32
View File
@@ -0,0 +1,32 @@
"""
Диалоги для winehelper GUI.
"""
from winehelperqt.dialogs.base_version_dialog import (
BaseVersionSelectionDialog,
WineVersionSelectionDialogBase,
ComponentVersionSelectionDialogBase,
)
from winehelperqt.dialogs.winetricks_manager import WinetricksManagerDialog
from winehelperqt.dialogs.wine_version import WineVersionSelectionDialog
from winehelperqt.dialogs.component_version import ComponentVersionSelectionDialog
from winehelperqt.dialogs.create_prefix import CreatePrefixDialog
from winehelperqt.dialogs.file_associations import FileAssociationsDialog
from winehelperqt.dialogs.settings import AdditionalSettingsDialog, AppAdditionalSettingsDialog
from winehelperqt.dialogs.noexec_warning import NoExecWarningDialog
__all__ = [
# Base classes
'BaseVersionSelectionDialog',
'WineVersionSelectionDialogBase',
'ComponentVersionSelectionDialogBase',
# Dialogs
'WinetricksManagerDialog',
'WineVersionSelectionDialog',
'ComponentVersionSelectionDialog',
'CreatePrefixDialog',
'FileAssociationsDialog',
'AdditionalSettingsDialog',
'AppAdditionalSettingsDialog',
'NoExecWarningDialog',
]
+313
View File
@@ -0,0 +1,313 @@
"""
Базовые классы для диалогов выбора версий.
Устраняет дублирование кода между WineVersionSelectionDialog и ComponentVersionSelectionDialog.
"""
import os
import re
import shutil
import subprocess
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QScrollArea,
QTabWidget, QLineEdit, QPushButton, QLabel, QWidget, QMessageBox
)
from PyQt5.QtCore import Qt, pyqtSignal
from winehelperqt.parsers.sha256_parser import Sha256Parser
from winehelperqt.utils.environment import EnvironmentConfig
from winehelperqt.utils.grid_utils import GridUtils
class BaseVersionSelectionDialog(QDialog):
"""
Базовый класс для диалогов выбора версий.
Предоставляет общую функциональность:
- Поле поиска с фильтрацией
- Сетка кнопок с версиями
- Базовая логика выбора версии
"""
NUM_COLUMNS = 3
version_selected = pyqtSignal(str)
def __init__(self, title, parent=None, min_width=600, min_height=400):
"""
Инициализирует базовый диалог выбора версий.
"""
super().__init__(parent)
self.setWindowTitle(title)
self.setMinimumSize(min_width, min_height)
self.setModal(True)
self.selected_version = None
self.buttons = []
self.search_edit = None
self.main_layout = None
self._setup_ui()
def _get_sha256_path(self):
"""Возвращает путь к файлу sha256sum.list."""
data_path = EnvironmentConfig.DATA_PATH
if data_path:
return os.path.join(data_path, "sha256sum.list")
# Фолбэк: явно разрешаем путь из расположения пакета
return os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', 'sha256sum.list')
)
def _setup_ui(self):
"""Создает базовый UI диалога."""
self.main_layout = QVBoxLayout(self)
self.search_edit = QLineEdit()
self.search_edit.setPlaceholderText("Поиск версии...")
self.search_edit.textChanged.connect(self.filter_versions)
self.main_layout.addWidget(self.search_edit)
self._create_version_container()
def _create_version_container(self):
"""Создает контейнер для отображения версий."""
raise NotImplementedError("Подкласс должен реализовать _create_version_container")
def load_versions(self):
"""Загружает список версий."""
raise NotImplementedError("Подкласс должен реализовать load_versions")
def filter_versions(self):
"""Фильтрует версии по тексту поиска."""
grid_layout = getattr(self, 'grid_layout', None)
GridUtils.filter_buttons(
self.buttons, self.search_edit.text(), grid_layout, self.NUM_COLUMNS
)
def on_version_selected(self, version_name):
"""Обрабатывает выбор версии."""
self.selected_version = version_name
self.version_selected.emit(version_name)
self.accept()
def get_selected_version(self):
"""Возвращает выбранную версию."""
return self.selected_version
@staticmethod
def create_grid_buttons(
grid_layout,
versions_list,
on_click_callback,
start_row=0,
num_columns=3,
is_download_tab=False,
version_filter=None
):
"""Создает сетку кнопок для версий."""
buttons = []
row, col = start_row, 0
for version_data in versions_list:
if isinstance(version_data, tuple):
display_name, value_name = version_data
else:
display_name = value_name = version_data
btn = QPushButton(display_name)
btn.clicked.connect(lambda checked, vn=value_name: on_click_callback(vn))
if version_filter and not is_download_tab:
should_disable = version_filter(value_name)
if should_disable:
btn.setEnabled(False)
btn.setToolTip("Эта версия несовместима с выбранной архитектурой.")
grid_layout.addWidget(btn, row, col)
buttons.append(btn)
col += 1
if col >= num_columns:
col = 0
row += 1
return buttons
class WineVersionSelectionDialogBase(BaseVersionSelectionDialog):
"""
Базовый класс для диалога выбора версии Wine.
"""
def __init__(self, architecture, parent=None):
"""
Инициализирует диалог выбора версии Wine.
"""
self.architecture = architecture
self.wine_versions_data = {}
self.system_wine_display_name = "Системная версия"
self.selected_display_text = None
super().__init__(
title=f"Выбор версии Wine для {architecture} префикса",
parent=parent,
min_width=900,
min_height=500
)
def _create_version_container(self):
"""Создает контейнер с вкладками для версий Wine."""
self.main_tabs = QTabWidget()
self.main_layout.addWidget(self.main_tabs)
self.load_versions()
def load_versions(self):
"""Загружает и отображает версии Wine."""
self.main_tabs.clear()
loading_widget = QWidget()
loading_layout = QVBoxLayout(loading_widget)
status_label = QLabel("Загрузка, пожалуйста, подождите...")
status_label.setAlignment(Qt.AlignCenter)
loading_layout.addWidget(status_label)
self.main_tabs.addTab(loading_widget, "Загрузка...")
self.main_tabs.setEnabled(False)
self._parse_sha256_list()
self.populate_ui()
self.main_tabs.setEnabled(True)
def _parse_sha256_list(self):
"""Парсит sha256sum.list для получения списка версий Wine."""
sha256_path = self._get_sha256_path()
self.wine_versions_data = Sha256Parser.parse_wine_versions(sha256_path)
if not self.wine_versions_data:
QMessageBox.warning(
self,
"Ошибка",
f"Файл с версиями не найден или пуст:\n{sha256_path}"
)
def _get_installed_versions(self):
"""Возвращает список локально установленных версий Wine."""
dist_path = EnvironmentConfig.WH_DIST_DIR
if not dist_path:
return []
return Sha256Parser.get_installed_versions(dist_path)
def _get_system_wine_version(self):
"""Получает версию системного Wine."""
if shutil.which('wine'):
try:
result = subprocess.run(
['wine', '--version'],
capture_output=True,
text=True,
check=True,
encoding='utf-8'
)
return result.stdout.strip()
except (FileNotFoundError, subprocess.CalledProcessError) as e:
print(f"Не удалось получить версию системного wine: {e}")
return "Системная версия"
def _is_version_compatible(self, version_name):
"""Проверяет совместимость версии с выбранной архитектурой."""
is_win64_prefix = self.architecture == "win64"
is_win32_prefix = self.architecture == "win32"
re_32bit_version = re.compile(r'i[3-6]86|i586')
if is_win64_prefix and re_32bit_version.search(version_name):
return False
if is_win32_prefix:
if version_name == "system" or 'wow64' in version_name:
return False
return True
def populate_ui(self):
"""Заполняет UI версиями Wine."""
raise NotImplementedError("Подкласс должен реализовать populate_ui")
class ComponentVersionSelectionDialogBase(BaseVersionSelectionDialog):
"""
Базовый класс для диалога выбора версии компонента (DXVK, VKD3D).
"""
def __init__(
self,
component_group,
title,
parent=None,
add_extra_options=True
):
"""
Инициализирует диалог выбора версии компонента.
"""
self.component_group = component_group
self.versions_data = []
self.add_extra_options = add_extra_options
super().__init__(
title=title,
parent=parent,
min_width=700,
min_height=400
)
def _create_version_container(self):
"""Создает контейнер для версий компонента."""
self.scroll_area = QScrollArea()
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.main_layout.addWidget(self.scroll_area)
scroll_content = QWidget()
self.scroll_area.setWidget(scroll_content)
self.grid_layout = QGridLayout(scroll_content)
self.grid_layout.setAlignment(Qt.AlignTop)
self.load_versions(start_row=0)
if self.add_extra_options:
self._create_action_buttons()
def _create_action_buttons(self):
"""Создает кнопки действий (Удалить, Отмена)."""
button_layout = QHBoxLayout()
uninstall_btn = QPushButton("Удалить из префикса")
uninstall_btn.setToolTip("Удаляет текущую установленную версию компонента из префикса.")
uninstall_btn.clicked.connect(lambda: self.on_version_selected("none"))
button_layout.addWidget(uninstall_btn)
button_layout.addStretch(1)
cancel_button = QPushButton("Отмена")
cancel_button.clicked.connect(self.reject)
button_layout.addWidget(cancel_button)
self.main_layout.addLayout(button_layout)
def load_versions(self, start_row=0):
"""Загружает и отображает версии компонента."""
self._parse_sha256_list()
self.populate_ui(start_row)
def _parse_sha256_list(self):
"""Парсит sha256sum.list для получения списка версий компонента."""
sha256_path = self._get_sha256_path()
self.versions_data = Sha256Parser.parse_component_versions(
sha256_path,
self.component_group
)
def populate_ui(self, start_row):
"""Заполняет UI версиями компонента."""
raise NotImplementedError("Подкласс должен реализовать populate_ui")
+55
View File
@@ -0,0 +1,55 @@
"""
Диалог для выбора версии компонента (DXVK, VKD3D).
"""
from functools import partial
from winehelperqt.dialogs.base_version_dialog import ComponentVersionSelectionDialogBase
from winehelperqt.dialogs.wine_version import VersionButtonWidget
from winehelperqt.utils.version_utils import sort_versions
class ComponentVersionSelectionDialog(ComponentVersionSelectionDialogBase):
"""Диалог для выбора версии компонента (DXVK, VKD3D)."""
def __init__(self, component_group, title, parent=None, add_extra_options=True, installed_version=None):
"""
Инициализирует диалог выбора версии компонента.
Args:
component_group: Группа компонента (dxvk, vkd3d)
title: Заголовок диалога
parent: Родительский виджет
add_extra_options: Добавлять ли кнопки действий
installed_version: Текущая установленная версия компонента в префиксе
"""
self.installed_version = installed_version
super().__init__(
component_group=component_group,
title=title,
parent=parent,
add_extra_options=add_extra_options
)
def populate_ui(self, start_row):
"""Заполняет UI кнопками версий."""
versions = sort_versions(self.versions_data, reverse=True)
row, col = start_row, 0
for version_name in versions:
is_installed = version_name == self.installed_version
btn = VersionButtonWidget(
version_name, version_name,
is_installed=is_installed, show_icon=True
)
btn.clicked.connect(partial(self.on_version_selected, version_name))
self.grid_layout.addWidget(btn, row, col)
self.buttons.append(btn)
col += 1
if col >= self.NUM_COLUMNS:
col = 0
row += 1
def on_version_selected(self, version_name):
"""Обрабатывает выбор версии."""
self.selected_version = version_name
self.accept()
+204
View File
@@ -0,0 +1,204 @@
"""
Диалог для создания нового префикса.
"""
import os
import re
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout, QPushButton,
QLabel, QLineEdit, QRadioButton, QComboBox, QMessageBox, QWidget
)
from PyQt5.QtGui import QFont
from winehelperqt.parsers.sha256_parser import Sha256Parser
from winehelperqt.dialogs.wine_version import WineVersionSelectionDialog
from winehelperqt.utils.environment import EnvironmentConfig
class CreatePrefixDialog(QDialog):
"""Диалог для создания нового префикса."""
PREFIX_NAME_PATTERN = r'^[a-zA-Z0-9_-]+$'
PREFIX_NAME_CHARS = r'[^a-zA-Z0-9_-]'
def __init__(self, parent=None):
super().__init__(parent)
self.parent_gui = parent
self.setWindowTitle("Создание нового префикса")
self.setMinimumSize(680, 250)
self.setModal(True)
self.prefix_name = None
self.wine_arch = None
self.base_pfx = None
self.prepared_prefixes = {}
self.selected_wine_version_value = None
self.selected_wine_version_display = None
layout = QVBoxLayout(self)
form_layout = QFormLayout()
form_layout.setSpacing(10)
name_input_widget = QWidget()
name_input_layout = QVBoxLayout(name_input_widget)
name_input_layout.setContentsMargins(0, 0, 0, 0)
name_input_layout.setSpacing(2)
self.prefix_name_edit = QLineEdit()
self.prefix_name_edit.setPlaceholderText("Например: my_prefix")
name_input_layout.addWidget(self.prefix_name_edit)
self.name_warning_label = QLabel(
"Имя может содержать только латинские буквы, цифры, тире и знаки подчеркивания."
)
self.name_warning_label.setStyleSheet("color: red;")
self.name_warning_label.setVisible(False)
name_input_layout.addWidget(self.name_warning_label)
form_layout.addRow("<b>Имя нового префикса:</b>", name_input_widget)
arch_widget = QWidget()
arch_layout = QHBoxLayout(arch_widget)
arch_layout.setContentsMargins(0, 0, 0, 0)
self.arch_win32_radio = QRadioButton("32-bit")
self.arch_win64_radio = QRadioButton("64-bit")
self.arch_win64_radio.setChecked(True)
arch_layout.addWidget(self.arch_win32_radio)
arch_layout.addWidget(self.arch_win64_radio)
form_layout.addRow("<b>Разрядность:</b>", arch_widget)
self.prefix_template_selector = QComboBox()
self.prefix_template_selector.setToolTip("Выберите шаблон для создания префикса.")
form_layout.addRow("<b>Шаблон префикса:</b>", self.prefix_template_selector)
self.wine_version_edit = QLineEdit()
self.wine_version_edit.setReadOnly(True)
self.wine_version_edit.setPlaceholderText("Версия не выбрана")
select_version_button = QPushButton("Выбрать версию...")
select_version_button.clicked.connect(self.open_wine_version_dialog)
version_layout = QHBoxLayout()
version_layout.addWidget(self.wine_version_edit)
version_layout.addWidget(select_version_button)
form_layout.addRow("<b>Версия Wine:</b>", version_layout)
layout.addLayout(form_layout)
button_layout = QHBoxLayout()
self.create_button = QPushButton("Создать")
self.create_button.setFont(QFont('Arial', 11, QFont.Bold))
self.create_button.setStyleSheet("background-color: #0078d7; color: white;")
self.create_button.setEnabled(False)
self.create_button.clicked.connect(self.accept_creation)
cancel_button = QPushButton("Отмена")
cancel_button.clicked.connect(self.reject)
button_layout.addStretch()
button_layout.addWidget(self.create_button)
button_layout.addWidget(cancel_button)
layout.addLayout(button_layout)
self.arch_win32_radio.toggled.connect(self.on_architecture_changed)
self.prefix_name_edit.textChanged.connect(self.validate_prefix_name)
self.wine_version_edit.textChanged.connect(self.update_create_button_state)
self._load_prepared_prefixes()
self.on_architecture_changed()
def _load_prepared_prefixes(self):
"""Загружает и парсит шаблоны префиксов из sha256sum.list."""
self.prepared_prefixes = {'win32': [], 'win64': []}
data_path = EnvironmentConfig.DATA_PATH
if not data_path:
QMessageBox.warning(self, "Ошибка", "Переменная окружения DATA_PATH не установлена.")
return
sha256_file = os.path.join(data_path, "sha256sum.list")
if not os.path.exists(sha256_file):
QMessageBox.warning(self, "Ошибка", f"Файл с описаниями префиксов не найден: {sha256_file}")
return
prepared = Sha256Parser.parse_prepared_prefixes(sha256_file)
self.prepared_prefixes = prepared
def open_wine_version_dialog(self):
"""Открывает диалог выбора версии Wine."""
architecture = "win32" if self.arch_win32_radio.isChecked() else "win64"
dialog = WineVersionSelectionDialog(architecture, self)
if dialog.exec_() == QDialog.Accepted and dialog.selected_version:
self.wine_version_edit.setText(dialog.selected_display_text)
self.selected_wine_version_value = dialog.selected_version
def on_architecture_changed(self):
"""Обновляет список шаблонов и сбрасывает выбор версии Wine."""
self.wine_version_edit.clear()
self.selected_wine_version_value = None
self.prefix_template_selector.blockSignals(True)
self.prefix_template_selector.clear()
architecture = "win32" if self.arch_win32_radio.isChecked() else "win64"
templates = self.prepared_prefixes.get(architecture, [])
for value, description in templates:
display_name = "Чистый префикс" if value == "none" else value
self.prefix_template_selector.addItem(display_name, userData={'value': value, 'tooltip': description})
self.prefix_template_selector.blockSignals(False)
self.prefix_template_selector.currentIndexChanged.connect(
lambda i: self.prefix_template_selector.setToolTip(
self.prefix_template_selector.itemData(i)['tooltip']
)
)
self.prefix_template_selector.setToolTip(self.prefix_template_selector.itemData(0)['tooltip'])
def validate_prefix_name(self, text):
"""Проверяет имя префикса в реальном времени."""
if re.match(self.PREFIX_NAME_PATTERN, text):
self.name_warning_label.setVisible(False)
else:
cleaned_text = re.sub(self.PREFIX_NAME_CHARS, '', text)
self.prefix_name_edit.blockSignals(True)
self.prefix_name_edit.setText(cleaned_text)
self.prefix_name_edit.blockSignals(False)
self.name_warning_label.setVisible(True)
self.update_create_button_state()
def update_create_button_state(self):
"""Включает или выключает кнопку 'Создать'."""
name_ok = bool(self.prefix_name_edit.text().strip())
version_ok = bool(self.wine_version_edit.text().strip())
self.create_button.setEnabled(
name_ok and version_ok and not self.name_warning_label.isVisible()
)
def accept_creation(self):
"""Валидирует данные, сохраняет их и закрывает диалог с успехом."""
prefix_name = self.prefix_name_edit.text().strip()
if not prefix_name:
QMessageBox.warning(self, "Ошибка", "Имя префикса не может быть пустым.")
return
if not re.match(self.PREFIX_NAME_PATTERN, prefix_name):
QMessageBox.warning(
self, "Ошибка",
"Имя префикса может содержать только латинские буквы, цифры, дефисы и знаки подчеркивания."
)
return
prefix_path = os.path.join(EnvironmentConfig.USER_WORK_PATH, "prefixes", prefix_name)
if os.path.exists(prefix_path):
QMessageBox.warning(self, "Ошибка", f"Префикс с именем '{prefix_name}' уже существует.")
return
self.prefix_name = prefix_name
self.wine_arch = "win32" if self.arch_win32_radio.isChecked() else "win64"
current_index = self.prefix_template_selector.currentIndex()
self.base_pfx = self.prefix_template_selector.itemData(current_index)['value']
self.selected_wine_version_display = self.wine_version_edit.text()
self.accept()
+75
View File
@@ -0,0 +1,75 @@
"""
Диалог для управления ассоциациями файлов (WH_XDG_OPEN).
"""
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QLineEdit, QLabel, QDialogButtonBox, QMessageBox
)
from PyQt5.QtCore import Qt
class FileAssociationsDialog(QDialog):
"""Диалог для управления ассоциациями файлов."""
def __init__(self, current_associations, parent=None):
super().__init__(parent)
self.setWindowTitle("Настройка ассоциаций файлов")
self.setMinimumWidth(450)
self.setModal(True)
self.new_associations = current_associations
layout = QVBoxLayout(self)
layout.setSpacing(10)
info_label = QLabel(
"Укажите расширения файлов, которые должны открываться нативными<br>"
"приложениями Linux. Чтобы удалить все ассоциации, очистите поле.<br><br>"
"<b>Пример:</b> <code>pdf docx txt</code>"
)
info_label.setWordWrap(True)
info_label.setTextFormat(Qt.RichText)
layout.addWidget(info_label)
self.associations_edit = QLineEdit()
if current_associations != "0":
self.associations_edit.setText(current_associations)
self.associations_edit.setPlaceholderText("Введите расширения через пробел...")
layout.addWidget(self.associations_edit)
forbidden_label = QLabel(
"<small><b>Запрещено использовать:</b> cpl, dll, exe, lnk, msi</small>"
)
forbidden_label.setTextFormat(Qt.RichText)
layout.addWidget(forbidden_label)
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.validate_and_accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
def validate_and_accept(self):
"""Проверяет введенные данные перед закрытием."""
forbidden_extensions = {"cpl", "dll", "exe", "lnk", "msi"}
input_text = self.associations_edit.text().lower().strip()
entered_extensions = {
ext.strip() for ext in input_text.split() if ext.strip()
}
found_forbidden = entered_extensions.intersection(forbidden_extensions)
if found_forbidden:
msg_box = QMessageBox(self)
msg_box.setIcon(QMessageBox.Warning)
msg_box.setWindowTitle("Недопустимые расширения")
msg_box.setTextFormat(Qt.RichText)
msg_box.setText(
"Следующие расширения запрещены и не могут быть использованы:<br><br>"
f"<b>{', '.join(sorted(list(found_forbidden)))}</b>"
)
msg_box.exec_()
return
self.new_associations = " ".join(sorted(list(entered_extensions)))
self.accept()
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""
Модуль вывода предупреждения о noexec для /home.
Выводит информационное окно с инструкциями по устранению проблемы,
когда /home примонтирован с флагом noexec и запуск Wine невозможен.
"""
import getpass
import sys
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QTextBrowser,
QVBoxLayout,
)
class NoExecWarningDialog(QDialog):
"""Диалог предупреждения о флаге noexec для /home."""
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("WineHelper — Предупреждение!")
self.setMinimumSize(600, 620)
self.setModal(True)
layout = QVBoxLayout(self)
layout.setSpacing(12)
self.info_browser = QTextBrowser()
self.info_browser.setOpenExternalLinks(True)
self.info_browser.setStyleSheet("""
QTextBrowser {
background-color: #1e1e1e;
color: #e4e4e4;
border: none;
}
""")
self.info_browser.setHtml(self._build_html_content())
layout.addWidget(self.info_browser)
def _build_html_content(self) -> str:
"""Формирует HTML-содержимое окна с подстановкой имени пользователя."""
username = getpass.getuser()
body_style = (
"font-family: 'Segoe UI', 'Noto Sans', sans-serif; "
"font-size: 14px; color: #e4e4e4; line-height: 1.55;"
)
warning_style = (
"background-color: #3d351f; border-left: 4px solid #ffcc00; "
"padding: 12px 14px; margin: 0;"
)
warning_text_style = "color: #ffd700; font-weight: bold; text-align: center; margin: 0 0 6px 0;"
card_style = "padding: 14px; margin: 0;"
title_style = "font-size: 15px; font-weight: bold; color: #ffffff; margin: 0 0 10px 0;"
paragraph_style = "margin: 0 0 10px 0;"
pre_style = (
"color: #7ee787; font-family: 'JetBrains Mono', 'Consolas', 'Courier New', monospace; "
"font-size: 13px; padding: 4px 0; margin: 0 0 12px 0;"
)
return f"""
<html>
<body style="{body_style}">
<p style="text-align: center; font-size: 20px; font-weight: bold; color: #ffd700; margin: 0 0 8px 0;">
Предупреждение!
</p>
<div style="{warning_style}">
<p style="{warning_text_style} margin-bottom: 0;">
⚠️ /home примонтирован в /etc/fstab с аргументом noexec.<br>
Запуск портативной версии wine невозможен из домашнего каталога!
Используйте один из двух вариантов решения проблемы.
</p>
</div>
<div style="line-height: 18px; font-size: 1px;">&nbsp;</div>
<div style="{card_style}">
<p style="{title_style}">1. Снять флаг noexec в /etc/fstab</p>
<pre style="{pre_style}">$ su -
# apt-get install nano
# nano /etc/fstab</pre>
<p style="{paragraph_style}">
Удаляем флаг <b>noexec</b> напротив <b>/home</b>.<br>
<b>Ctrl+O</b> — сохранить изменения,<br>
<b>Ctrl+X</b> — выход.<br>
Можно использовать любой редактор; nano приведён как пример.
</p>
<p style="{title_style} margin-top: 14px;">Обновляем загрузчик:</p>
<pre style="{pre_style}"># update-grub
# exit</pre>
<p style="{paragraph_style} margin-bottom: 0;">После перезагрузки можно приступать к работе с WineHelper.</p>
</div>
<div style="line-height: 18px; font-size: 1px;">&nbsp;</div>
<div style="{card_style}">
<p style="{title_style}">2. Или изменить рабочий каталог для WineHelper</p>
<p style="{paragraph_style}">
Каталог должен находиться <b>вне /home</b> и иметь права на чтение-запись
для пользователя <b>{username}</b>.
</p>
<p style="{paragraph_style}">Используйте команду:</p>
<pre style="{pre_style} margin-bottom: 0;">$ winehelper data-path /путь/к/каталогу</pre>
</div>
</body>
</html>
"""
def main() -> int:
"""Точка входа для автономного запуска модуля."""
app = QApplication(sys.argv)
dialog = NoExecWarningDialog()
dialog.show()
return app.exec_()
if __name__ == "__main__":
sys.exit(main())
+369
View File
@@ -0,0 +1,369 @@
"""
Диалоги для дополнительных настроек префикса и приложений.
"""
import os
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QPushButton,
QLabel, QCheckBox, QComboBox, QMessageBox, QSizePolicy
)
from PyQt5.QtCore import Qt
from winehelperqt.utils.export_utils import ExportUtils
class AdditionalSettingsDialog(QDialog):
"""Диалог для дополнительных настроек префикса (ESync, FSync, DXVK, VKD3D)."""
def __init__(self, prefix_name, parent=None):
super().__init__(parent)
self.parent_gui = parent
self.prefix_name = prefix_name
self.setWindowTitle("Дополнительные настройки")
self.setMinimumWidth(400)
self.setModal(True)
layout = QVBoxLayout(self)
grid_layout = QGridLayout()
grid_layout.setSpacing(10)
# ESync/FSync
self.esync_button = QPushButton("ESync")
self.esync_button.setCheckable(True)
self.esync_button.setMinimumHeight(32)
self.esync_button.setToolTip("Включить/выключить Eventfd-based synchronization.")
self.esync_button.clicked.connect(
lambda checked: self._toggle_sync_option("WINEESYNC", checked, self.esync_button)
)
self.esync_button.toggled.connect(
lambda checked, btn=self.esync_button: self._update_button_text(btn, "ESync", checked)
)
self.esync_button.setStyleSheet(
"QPushButton:checked { background-color: #4CAF50; color: white; font-weight: bold; }"
)
grid_layout.addWidget(self.esync_button, 0, 0)
self.fsync_button = QPushButton("FSync")
self.fsync_button.setMinimumHeight(32)
self.fsync_button.setCheckable(True)
self.fsync_button.setToolTip("Включить/выключить Futex-based synchronization.")
self.fsync_button.clicked.connect(
lambda checked: self._toggle_sync_option("WINEFSYNC", checked, self.fsync_button)
)
self.fsync_button.toggled.connect(
lambda checked, btn=self.fsync_button: self._update_button_text(btn, "FSync", checked)
)
self.fsync_button.setStyleSheet(
"QPushButton:checked { background-color: #4CAF50; color: white; font-weight: bold; }"
)
grid_layout.addWidget(self.fsync_button, 0, 1)
self.esync_button.setFocusPolicy(Qt.NoFocus)
self.fsync_button.setFocusPolicy(Qt.NoFocus)
# DXVK/VKD3D
self.dxvk_manage_button = QPushButton("Управление DXVK")
self.dxvk_manage_button.setMinimumHeight(32)
self.dxvk_manage_button.clicked.connect(
lambda: self._open_component_manager('dxvk')
)
self.dxvk_manage_button.setToolTip("Установка или удаление определенной версии DXVK в префиксе.")
grid_layout.addWidget(self.dxvk_manage_button, 1, 0)
self.vkd3d_manage_button = QPushButton("Управление VKD3D")
self.vkd3d_manage_button.setMinimumHeight(32)
self.vkd3d_manage_button.clicked.connect(
lambda: self._open_component_manager('vkd3d-proton')
)
self.vkd3d_manage_button.setToolTip("Установка или удаление определенной версии vkd3d-proton в префиксе.")
grid_layout.addWidget(self.vkd3d_manage_button, 1, 1)
self.dxvk_manage_button.setFocusPolicy(Qt.NoFocus)
self.vkd3d_manage_button.setFocusPolicy(Qt.NoFocus)
# Ассоциации файлов
self.file_associations_button = QPushButton("Ассоциации файлов")
self.file_associations_button.setMinimumHeight(32)
self.file_associations_button.clicked.connect(self.parent_gui.open_file_associations_manager)
self.file_associations_button.setToolTip(
"Настройка открытия определенных типов файлов с помощью нативных приложений Linux."
)
grid_layout.addWidget(self.file_associations_button, 2, 0)
self.file_associations_button.setFocusPolicy(Qt.NoFocus)
# CPCSP_PROXY
self.cpcsp_proxy_button = QPushButton("CPCSP_PROXY")
self.cpcsp_proxy_button.setMinimumHeight(32)
self.cpcsp_proxy_button.setCheckable(True)
self.cpcsp_proxy_button.setToolTip("Включить/выключить использование CPCSP_PROXY.")
self.cpcsp_proxy_button.clicked.connect(
lambda checked: self._toggle_cpcsp_proxy(checked, self.cpcsp_proxy_button)
)
self.cpcsp_proxy_button.toggled.connect(
lambda checked, btn=self.cpcsp_proxy_button: self._update_button_text(btn, "CPCSP_PROXY", checked)
)
self.cpcsp_proxy_button.setStyleSheet(
"QPushButton:checked { background-color: #4CAF50; color: white; font-weight: bold; }"
)
grid_layout.addWidget(self.cpcsp_proxy_button, 2, 1)
self.cpcsp_proxy_button.setFocusPolicy(Qt.NoFocus)
layout.addLayout(grid_layout)
self.close_button = QPushButton("Закрыть")
self.close_button.setMinimumHeight(32)
self.close_button.clicked.connect(self.accept)
self.close_button.setFocusPolicy(Qt.NoFocus)
layout.addWidget(self.close_button, alignment=Qt.AlignRight)
self.update_button_states()
def _toggle_sync_option(self, option_name, is_checked, button):
"""Обновляет опцию синхронизации."""
self.parent_gui.update_sync_option(option_name, is_checked)
def _toggle_cpcsp_proxy(self, is_checked, button):
"""Обновляет опцию CPCSP_PROXY и запускает установку при включении."""
if is_checked:
# Сначала сохраняем WH_USE_CPCSP_PROXY="1" в last.conf,
# чтобы winehelper init-prefix прочитал его при запуске
self.parent_gui.update_sync_option("WH_USE_CPCSP_PROXY", True)
def on_install_finished(success):
if not success:
# При ошибке откатываем значение в last.conf и сбрасываем кнопку
self.parent_gui.update_sync_option("WH_USE_CPCSP_PROXY", False)
button.blockSignals(True)
button.setChecked(False)
self._update_button_text(button, "CPCSP_PROXY", False)
button.blockSignals(False)
self.parent_gui.run_cpcsp_proxy_install(self.prefix_name, on_install_finished)
else:
self.parent_gui.update_sync_option("WH_USE_CPCSP_PROXY", False)
def _update_button_text(self, button, base_text, is_checked):
"""Обновляет текст кнопки, добавляя или убирая галочку."""
if is_checked:
button.setText(f"✓ {base_text}")
else:
button.setText(base_text)
def _open_component_manager(self, component_name):
"""Открывает менеджер компонентов."""
self.parent_gui.open_component_version_manager(component_name)
def update_button_states(self):
"""Обновляет состояние кнопок на основе данных из last.conf."""
esync_enabled = self.parent_gui._get_prefix_component_version(
self.prefix_name, "WINEESYNC"
) == "1"
fsync_enabled = self.parent_gui._get_prefix_component_version(
self.prefix_name, "WINEFSYNC"
) == "1"
cpcsp_proxy_enabled = self.parent_gui._get_prefix_component_version(
self.prefix_name, "WH_USE_CPCSP_PROXY"
) == "1"
self.esync_button.blockSignals(True)
self.fsync_button.blockSignals(True)
self.cpcsp_proxy_button.blockSignals(True)
self.esync_button.setChecked(esync_enabled)
self.fsync_button.setChecked(fsync_enabled)
self.cpcsp_proxy_button.setChecked(cpcsp_proxy_enabled)
self._update_button_text(self.esync_button, "ESync", esync_enabled)
self._update_button_text(self.fsync_button, "FSync", fsync_enabled)
self._update_button_text(self.cpcsp_proxy_button, "CPCSP_PROXY", cpcsp_proxy_enabled)
self.esync_button.blockSignals(False)
self.fsync_button.blockSignals(False)
self.cpcsp_proxy_button.blockSignals(False)
class AppAdditionalSettingsDialog(QDialog):
"""Диалог для дополнительных настроек приложения из .whdb файла."""
def __init__(self, exe_path, parent=None):
super().__init__(parent)
self.parent_gui = parent
self.exe_path = os.path.abspath(exe_path)
self.whdb_path = self.exe_path + '.whdb'
self.settings = {
'WH_MAIN_DECORATED': 'default',
'WH_VIRTUAL_DESKTOP': 'default',
'WH_FONT_SMOOTHING': '0',
'WH_FONT_MSS_REPLACE': '0',
'WINE_D3D_CONFIG': ''
}
self.setWindowTitle("Дополнительные настройки приложения")
self.setMinimumSize(380, 200)
self.setModal(True)
layout = QVBoxLayout(self)
checkboxes_layout = QHBoxLayout()
checkboxes_layout.setSpacing(20)
left_column = QVBoxLayout()
left_column.setSpacing(10)
self.wh_main_decorated_checkbox = QCheckBox("MAIN_DECORATED")
self.wh_main_decorated_checkbox.setToolTip("Управляет декорациями окон главного приложения")
left_column.addWidget(self.wh_main_decorated_checkbox)
self.wh_font_smoothing_checkbox = QCheckBox("FONT_SMOOTHING")
self.wh_font_smoothing_checkbox.setToolTip("Сглаживание шрифтов")
left_column.addWidget(self.wh_font_smoothing_checkbox)
right_column = QVBoxLayout()
right_column.setSpacing(10)
self.wh_virtual_desktop_checkbox = QCheckBox("VIRTUAL_DESKTOP")
self.wh_virtual_desktop_checkbox.setToolTip("Виртуальный рабочий стол для приложения")
right_column.addWidget(self.wh_virtual_desktop_checkbox)
self.wh_font_mss_replace_checkbox = QCheckBox("FONT_MSS_REPLACE")
self.wh_font_mss_replace_checkbox.setToolTip("Замена шрифтов MSS")
right_column.addWidget(self.wh_font_mss_replace_checkbox)
checkboxes_layout.addLayout(left_column)
checkboxes_layout.addLayout(right_column)
layout.addLayout(checkboxes_layout)
layout.addSpacing(15)
d3d_layout = QHBoxLayout()
d3d_label = QLabel("WINE_D3D_CONFIG:")
d3d_layout.addWidget(d3d_label)
self.wine_d3d_config_combo = QComboBox()
self.wine_d3d_config_combo.setMinimumWidth(250)
self.wine_d3d_config_combo.setSizePolicy(
QSizePolicy.Preferred, QSizePolicy.Preferred
)
self.wine_d3d_config_combo.addItem("Не задано", "")
self.wine_d3d_config_combo.addItem("renderer=vulkan", "renderer=vulkan")
self.wine_d3d_config_combo.addItem("renderer=gdi", "renderer=gdi")
self.wine_d3d_config_combo.addItem("renderer=gl", "renderer=gl")
self.wine_d3d_config_combo.setToolTip("Выберите режим рендеринга Direct3D")
d3d_layout.addWidget(self.wine_d3d_config_combo, stretch=1)
d3d_layout.addStretch()
layout.addLayout(d3d_layout)
layout.addSpacing(20)
button_layout = QHBoxLayout()
button_layout.addStretch()
self.save_button = QPushButton("Сохранить")
self.save_button.setMinimumHeight(32)
self.save_button.clicked.connect(self._save_settings)
self.save_button.setFocusPolicy(Qt.NoFocus)
button_layout.addWidget(self.save_button)
self.close_button = QPushButton("Закрыть")
self.close_button.setMinimumHeight(32)
self.close_button.clicked.connect(self.accept)
self.close_button.setFocusPolicy(Qt.NoFocus)
button_layout.addWidget(self.close_button)
layout.addLayout(button_layout)
self._load_settings()
def _load_settings(self):
"""Загружает настройки из .whdb файла."""
if not os.path.exists(self.whdb_path):
self._update_ui_from_settings()
return
try:
with open(self.whdb_path, 'r', encoding='utf-8') as f:
content = f.read()
for line in content.split('\n'):
var_name, var_value = self._parse_export_line(line)
if var_name and var_name in self.settings:
self.settings[var_name] = var_value
self._update_ui_from_settings()
except Exception as e:
QMessageBox.warning(
self, "Ошибка",
f"Не удалось прочитать файл настроек:\n{self.whdb_path}\n\nОшибка: {e}"
)
self._update_ui_from_settings()
def _update_ui_from_settings(self):
"""Обновляет элементы управления на основе загруженных настроек."""
self.wh_main_decorated_checkbox.setChecked(
self.settings.get('WH_MAIN_DECORATED') == '1'
)
wh_virtual_desktop = self.settings.get('WH_VIRTUAL_DESKTOP', '')
self.wh_virtual_desktop_checkbox.setChecked(
wh_virtual_desktop == '1' or wh_virtual_desktop.lower() not in ('0', 'default', '')
)
self.wh_font_smoothing_checkbox.setChecked(
self.settings.get('WH_FONT_SMOOTHING') == '1'
)
self.wh_font_mss_replace_checkbox.setChecked(
self.settings.get('WH_FONT_MSS_REPLACE') == '1'
)
d3d_value = self.settings.get('WINE_D3D_CONFIG', '')
index = self.wine_d3d_config_combo.findData(d3d_value)
if index >= 0:
self.wine_d3d_config_combo.setCurrentIndex(index)
else:
self.wine_d3d_config_combo.setCurrentIndex(0)
def _save_settings(self):
"""Сохраняет настройки в .whdb файл."""
try:
existing_lines = []
if os.path.exists(self.whdb_path):
with open(self.whdb_path, 'r', encoding='utf-8') as f:
existing_lines = f.readlines()
settings_values = {
var_name: self._get_setting_value(var_name)
for var_name in self.settings
}
new_lines = ExportUtils.update_lines(existing_lines, settings_values)
with open(self.whdb_path, 'w', encoding='utf-8') as f:
f.writelines(new_lines)
self.accept()
except Exception as e:
QMessageBox.critical(self, "Ошибка", f"Не удалось сохранить настройки:\n{e}")
def _get_setting_value(self, var_name):
"""Возвращает текущее значение переменной из UI."""
if var_name == 'WINE_D3D_CONFIG':
return self.wine_d3d_config_combo.currentData()
if var_name == 'WH_MAIN_DECORATED':
return '1' if self.wh_main_decorated_checkbox.isChecked() else 'default'
if var_name == 'WH_VIRTUAL_DESKTOP':
return '1' if self.wh_virtual_desktop_checkbox.isChecked() else 'default'
if var_name == 'WH_FONT_SMOOTHING':
return '1' if self.wh_font_smoothing_checkbox.isChecked() else '0'
if var_name == 'WH_FONT_MSS_REPLACE':
return '1' if self.wh_font_mss_replace_checkbox.isChecked() else '0'
return ''
@staticmethod
def _parse_export_line(line):
"""Парсит строку export VAR=value, игнорируя комментарии и секции."""
return ExportUtils.parse_line(line)
@staticmethod
def _format_export_line(var_name, value):
"""Форматирует строку export VAR=value с экранированием."""
return ExportUtils.format_line(var_name, value)
+331
View File
@@ -0,0 +1,331 @@
"""
Диалог для выбора версии Wine с группировкой.
"""
import re
from functools import partial
from PyQt5.QtWidgets import (
QGridLayout, QScrollArea, QTabWidget, QPushButton, QLabel, QWidget, QVBoxLayout,
QHBoxLayout
)
from PyQt5.QtCore import Qt
from winehelperqt.dialogs.base_version_dialog import WineVersionSelectionDialogBase
from winehelperqt.utils.version_utils import sort_versions
from winehelperqt.utils.grid_utils import GridUtils
class VersionButtonWidget(QPushButton):
"""Кастомная кнопка версии с текстом слева и галочкой справа."""
def __init__(self, display_name, value_name, is_installed=False, show_icon=True, parent=None):
super().__init__(parent)
self.value_name = value_name
self.display_name = display_name
self.is_installed = is_installed
self.show_icon = show_icon
self.setMinimumHeight(40)
self.setCursor(Qt.PointingHandCursor)
# Создаем внутренний layout для размещения текста и галочки
self._setup_layout()
self._apply_style()
def _setup_layout(self):
"""Настраивает внутренний layout кнопки с текстом слева и галочкой справа."""
# Создаем контейнер для содержимого кнопки
container = QWidget(self)
layout = QHBoxLayout(container)
layout.setContentsMargins(12, 0, 12, 0)
layout.setSpacing(0)
# Если show_icon=False (вкладка "Установленные версии Wine"), текст по центру
if not self.show_icon:
layout.addStretch(1)
# Метка с названием версии (по центру)
self.name_label = QLabel(self.display_name)
self.name_label.setStyleSheet("background: transparent;")
self.name_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.name_label)
layout.addStretch(1)
else:
# Метка с названием версии (слева)
self.name_label = QLabel(self.display_name)
self.name_label.setStyleSheet("background: transparent;")
layout.addWidget(self.name_label)
# Растягивающийся spacer (занимает всё доступное пространство между текстом и галочкой)
layout.addStretch(1)
# Метка со значком статуса (справа)
if self.is_installed:
self.check_label = QLabel("✓")
self.check_label.setStyleSheet(
"background: transparent; color: #7fff7f; font-weight: bold; font-size: 22px;"
)
layout.addWidget(self.check_label)
else:
self.check_label = QLabel("⭳")
self.check_label.setStyleSheet("background: transparent; color: #888888; font-size: 22px;")
layout.addWidget(self.check_label)
# Устанавливаем layout для контейнера
container.setLayout(layout)
# Устанавливаем layout кнопки (PyQt5 поддерживает это)
button_layout = QHBoxLayout(self)
button_layout.setContentsMargins(0, 0, 0, 0)
button_layout.setSpacing(0)
button_layout.addWidget(container)
self.setLayout(button_layout)
def _apply_style(self):
"""Применяет стили в зависимости от статуса установки."""
# Не применяем никаких стилей — используем стандартные цвета системы
if self.is_installed:
self.setToolTip("Эта версия уже скачана и установлена. Нажмите, чтобы выбрать её.")
def text(self):
"""Возвращает текст кнопки для фильтрации."""
return self.display_name
def setText(self, text):
"""Устанавливает текст метки названия версии."""
self.display_name = text
if hasattr(self, 'name_label'):
self.name_label.setText(text)
class WineVersionSelectionDialog(WineVersionSelectionDialogBase):
"""Диалог для выбора версии Wine с группировкой."""
def __init__(self, architecture, parent=None):
"""
Инициализирует диалог выбора версии Wine.
Args:
architecture: Архитектура префикса (win32/win64)
parent: Родительский виджет
"""
self.main_tabs = None
self.installed_grid_layout = None
self.installed_buttons = []
self.download_buttons = []
self._installed_version_names = set()
super().__init__(architecture=architecture, parent=parent)
def _create_version_container(self):
"""Создает контейнер с вкладками для версий Wine."""
self.main_tabs = QTabWidget()
self.main_layout.addWidget(self.main_tabs)
self.load_versions()
def populate_ui(self):
"""Заполняет UI версиями Wine."""
self.main_tabs.clear()
self._installed_version_names = set()
# Вкладка "Установленные версии Wine"
installed_tab = QWidget()
self.main_tabs.addTab(installed_tab, "Установленные версии Wine")
installed_layout = QVBoxLayout(installed_tab)
installed_scroll_area = QScrollArea()
installed_scroll_area.setWidgetResizable(True)
installed_scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
installed_layout.addWidget(installed_scroll_area)
installed_content = QWidget()
installed_scroll_area.setWidget(installed_content)
self.installed_grid_layout = QGridLayout(installed_content)
self.installed_grid_layout.setAlignment(Qt.AlignTop)
installed_versions_for_grid = []
# Системная версия
self.system_wine_display_name = self._get_system_wine_version()
installed_versions_for_grid.append((self.system_wine_display_name, "system"))
# Локально установленные версии
local_versions = self._get_installed_versions()
installed_versions_for_grid.extend(local_versions)
# Запоминаем имена установленных версий для пометки на вкладках загрузки
for version_data in installed_versions_for_grid:
if isinstance(version_data, tuple):
_, value_name = version_data
else:
value_name = version_data
self._installed_version_names.add(value_name)
self._create_grid_buttons_for_wine(
self.installed_grid_layout, installed_versions_for_grid, is_download_tab=False
)
# Вкладки с версиями для скачивания
if not self.wine_versions_data:
error_widget = QWidget()
error_layout = QVBoxLayout(error_widget)
error_label = QLabel("Список версий пуст или не удалось его загрузить.")
error_label.setAlignment(Qt.AlignCenter)
error_layout.addWidget(error_label)
self.main_tabs.addTab(error_widget, "Ошибка")
self.filter_versions()
return
# Фильтрация и сортировка групп в зависимости от архитектуры
is_win64 = self.architecture == "win64"
if is_win64:
allowed_groups_for_arch = {"WINE AMD64", "WINE WOW64"}
tab_order = ["WINE WOW64", "WINE AMD64"]
display_names = {
"WINE WOW64": "Загрузить wine-wow64",
"WINE AMD64": "Загрузить wine-amd64"
}
else:
allowed_groups_for_arch = {"WINE I586", "WINE AMD64"}
tab_order = ["WINE I586", "WINE AMD64"]
display_names = {
"WINE I586": "Загрузить wine-i586",
"WINE AMD64": "Загрузить wine-amd64"
}
available_keys = [
key for key in self.wine_versions_data.keys()
if key in allowed_groups_for_arch
]
group_keys = sorted(available_keys, key=lambda k: tab_order.index(k))
for key in group_keys:
versions = self.wine_versions_data.get(key, [])
if not versions:
continue
display_name = display_names.get(key, key)
self._create_version_tab_directly(display_name, sort_versions(versions, reverse=True))
self.filter_versions()
def _create_version_tab_directly(self, title, versions_list):
"""Создает вкладку с сеткой кнопок и добавляет её напрямую в main_tabs."""
tab_page = QWidget()
tab_layout = QVBoxLayout(tab_page)
tab_layout.setContentsMargins(5, 5, 5, 5)
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
tab_layout.addWidget(scroll_area)
scroll_content = QWidget()
scroll_area.setWidget(scroll_content)
grid_layout = QGridLayout(scroll_content)
grid_layout.setAlignment(Qt.AlignTop)
self._create_grid_buttons_for_wine(grid_layout, versions_list, is_download_tab=True)
self.main_tabs.addTab(tab_page, title)
def _create_grid_buttons_for_wine(self, grid_layout, versions_list, is_download_tab=False):
"""Создает кнопки для версий в сетке."""
is_win64_prefix = self.architecture == "win64"
is_win32_prefix = self.architecture == "win32"
re_32bit_version = re.compile(r'i[3-6]86|i586')
row, col = 0, 0
for version_data in versions_list:
if isinstance(version_data, tuple):
display_name, value_name = version_data
else:
display_name = value_name = version_data
# Определяем, установлена ли версия
# На вкладке установленных все версии установлены по определению
if is_download_tab:
is_installed = value_name in self._installed_version_names
else:
is_installed = True
# Создаем кастомную кнопку
# На вкладке "Установленные версии Wine" значки не показываем
show_icon = is_download_tab
btn = VersionButtonWidget(display_name, value_name, is_installed=is_installed, show_icon=show_icon)
btn.clicked.connect(partial(self.on_version_selected, value_name, display_name))
# Подсказка для неустановленных версий на вкладках загрузки
if is_download_tab and not is_installed:
btn.setToolTip("Эта версия доступна для загрузки. Нажмите, чтобы скачать и выбрать её.")
if value_name == "system":
btn.setText(f"{display_name} (Системный)")
btn.setToolTip("Системная версия Wine, установленная в вашей ОС.")
# Отключение 32-битных версий для 64-битного префикса
if not is_download_tab and is_win64_prefix:
if re_32bit_version.search(value_name):
btn.setEnabled(False)
btn.setToolTip("Эта 32-битная версия Wine несовместима с 64-битным префиксом.")
# Отключение 64-битных версий для 32-битного префикса
if not is_download_tab and is_win32_prefix:
if value_name == "system" or 'wow64' in value_name:
btn.setEnabled(False)
btn.setToolTip("Эта 64-битная версия Wine несовместима с 32-битным префиксом.")
grid_layout.addWidget(btn, row, col)
# Сохраняем для фильтрации
if is_download_tab:
self.download_buttons.append(btn)
else:
self.installed_buttons.append(btn)
col += 1
if col >= self.NUM_COLUMNS:
col = 0
row += 1
def filter_versions(self):
"""Фильтрует видимость кнопок версий на основе текста поиска."""
search_text = self.search_edit.text()
# Фильтр для вкладки "Установленные"
if hasattr(self, 'installed_grid_layout'):
GridUtils.filter_buttons(
self.installed_buttons, search_text,
self.installed_grid_layout, self.NUM_COLUMNS
)
# Фильтр для вкладок с версиями (теперь напрямую в main_tabs)
# Пропускаем первую вкладку "Установленные" (индекс 0)
for i in range(1, self.main_tabs.count()):
tab_widget = self.main_tabs.widget(i)
grid_layout, buttons = self._get_grid_layout_and_buttons(tab_widget)
if grid_layout:
visible = GridUtils.filter_buttons(
buttons, search_text, grid_layout, self.NUM_COLUMNS
)
self.main_tabs.setTabEnabled(i, bool(visible))
def _get_grid_layout_and_buttons(self, tab_widget):
"""Возвращает QGridLayout и список кнопок из вкладки."""
scroll_area = tab_widget.findChild(QScrollArea)
if not scroll_area:
return None, []
scroll_content = scroll_area.widget()
if not scroll_content:
return None, []
grid_layout = scroll_content.layout()
if not isinstance(grid_layout, QGridLayout):
return None, []
buttons = []
for j in range(grid_layout.count()):
item = grid_layout.itemAt(j)
if item and item.widget():
buttons.append(item.widget())
return grid_layout, buttons
def on_version_selected(self, version_name, display_name=None):
"""Обрабатывает выбор версии Wine."""
self.selected_version = version_name
self.selected_display_text = display_name or version_name
self.accept()
+579
View File
@@ -0,0 +1,579 @@
"""
Диалог для управления компонентами Winetricks.
"""
import os
import shlex
from functools import partial
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QTabWidget,
QTextEdit, QListWidget, QListWidgetItem, QMessageBox, QLineEdit, QWidget
)
from PyQt5.QtCore import Qt, QProcess, QTimer, QProcessEnvironment, pyqtSignal
from PyQt5.QtGui import QTextCursor, QTextCharFormat, QFont
from winehelperqt.parsers.winetricks_parser import WinetricksOutputParser
from winehelperqt.services.winetricks_service import WinetricksLogReader, WinetricksCacheService
from winehelperqt.utils.environment import EnvironmentConfig
from winehelperqt.utils.dialog_utils import DialogUtils
class NoAutoScrollListWidget(QListWidget):
"""QListWidget с отключённой автопрокруткой к текущему элементу."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._scroll_enabled = False # Флаг для ручной прокрутки
def scrollTo(self, index, hint=QListWidget.EnsureVisible):
"""Переопределяем, чтобы игнорировать автоматическую прокрутку."""
if self._scroll_enabled:
super().scrollTo(index, hint)
def enable_scroll(self):
"""Включает прокрутку для ручного управления."""
self._scroll_enabled = True
def disable_scroll(self):
"""Отключает прокрутку."""
self._scroll_enabled = False
class WinetricksManagerDialog(QDialog):
"""Диалог для управления компонентами Winetricks."""
INFO_TEXT = (
"Компоненты можно только установить либо переустановить.\n"
"Удаление компонентов не реализовано в Winetricks.\n"
"Для установки нового компонента: Поставьте галочку и нажмите «Применить».\n"
"Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»."
)
installation_complete = pyqtSignal()
def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None, winehelper_path=None):
super().__init__(parent)
self.prefix_path = prefix_path
self.winetricks_path = winetricks_path
self.wine_executable = wine_executable or 'wine'
self.winehelper_path = winehelper_path or 'winehelper'
self.initial_states = {}
self.apply_process = None
self.installation_finished = False
self.user_cancelled = False
self.processes = {}
self.category_statuses = {}
self.previous_tab_widget = None
self.cache_service = WinetricksCacheService()
self.is_reloading_after_cache_clear = False
self.cache_clear_process = None
self._install_queue = []
self.setWindowTitle(f"Менеджер компонентов для префикса: {os.path.basename(prefix_path)}")
self.setMinimumSize(800, 500)
main_layout = QVBoxLayout(self)
self.tabs = QTabWidget()
main_layout.addWidget(self.tabs)
self.categories = {
"Библиотеки": "dlls",
"Шрифты": "fonts",
"Настройки": "settings"
}
self.list_widgets = {}
self.search_edits = {}
for display_name, internal_name in self.categories.items():
list_widget, search_edit = self._create_category_tab(display_name)
self.list_widgets[internal_name] = list_widget
self.search_edits[internal_name] = search_edit
self.log_output = QTextEdit()
self.log_output.setReadOnly(True)
self.log_output.setFont(QFont('DejaVu Sans Mono', 10))
self.log_output.setMaximumHeight(150)
self.log_output.setText(self.INFO_TEXT)
main_layout.addWidget(self.log_output)
button_layout = QHBoxLayout()
self.clear_cache_button = QPushButton("Очистить кеш")
self.clear_cache_button.setStyleSheet("background-color: red; color: white;")
self.clear_cache_button.clicked.connect(self.clear_winetricks_cache)
button_layout.addWidget(self.clear_cache_button)
button_layout.addStretch(1)
self.apply_button = QPushButton("Применить")
self.apply_button.setEnabled(False)
self.apply_button.clicked.connect(self.apply_changes)
button_layout.addWidget(self.apply_button)
self.reinstall_button = QPushButton("Переустановить")
self.reinstall_button.setEnabled(False)
self.reinstall_button.clicked.connect(self.reinstall_selected)
button_layout.addWidget(self.reinstall_button)
self.close_button = QPushButton("Закрыть")
self.close_button.clicked.connect(self.close)
button_layout.addWidget(self.close_button)
main_layout.addLayout(button_layout)
self.tabs.currentChanged.connect(self.on_tab_switched)
self.load_all_categories()
self.previous_tab_widget = self.tabs.currentWidget()
def on_tab_switched(self, index):
"""Обрабатывает переключение вкладок."""
if self.previous_tab_widget:
previous_index = self.tabs.indexOf(self.previous_tab_widget)
if previous_index >= 0:
category = list(self.categories.values())[previous_index]
search_edit = self.search_edits.get(category)
if search_edit:
search_edit.clear()
if self.installation_finished:
self.log_output.setText(self.INFO_TEXT)
self.installation_finished = False
self._update_ui_state()
self.previous_tab_widget = self.tabs.widget(index)
def _create_category_tab(self, title):
"""Создает вкладку с поиском и списком."""
tab = QWidget()
layout = QVBoxLayout(tab)
search_edit = QLineEdit()
search_edit.setPlaceholderText("Поиск...")
layout.addWidget(search_edit)
list_widget = NoAutoScrollListWidget()
list_widget.setAutoScroll(False) # Отключаем автопрокрутку
list_widget.itemChanged.connect(self._on_item_changed)
list_widget.currentItemChanged.connect(self._update_ui_state)
layout.addWidget(list_widget)
search_edit.textChanged.connect(lambda text, lw=list_widget: self.filter_list(text, lw))
self.tabs.addTab(tab, title)
return list_widget, search_edit
def filter_list(self, text, list_widget):
"""Фильтрует элементы в списке."""
# Блокируем все сигналы виджета, чтобы избежать автопрокрутки
# и лишних вызовов _update_ui_state при скрытии элементов
list_widget.blockSignals(True)
list_widget.disable_scroll() # Отключаем прокрутку
for i in range(list_widget.count()):
item = list_widget.item(i)
item.setHidden(text.lower() not in item.text().lower())
# Включаем прокрутку и прокручиваем к первому видимому элементу
list_widget.enable_scroll()
for i in range(list_widget.count()):
item = list_widget.item(i)
if not item.isHidden():
list_widget.scrollToItem(item, QListWidget.PositionAtTop)
break
list_widget.blockSignals(False)
# Обновляем состояние кнопок после фильтрации
self._update_ui_state()
def load_all_categories(self):
"""Запускает загрузку всех категорий."""
self.loading_count = len(self.categories)
for internal_name in self.categories.values():
self._start_load_process(internal_name)
def _start_load_process(self, category):
"""Запускает QProcess для получения списка компонентов, используя кэш."""
cached_output = self.cache_service.get_cached_data(category, self.winetricks_path)
if cached_output is not None:
QTimer.singleShot(0, lambda: self._on_load_finished(
category, 0, QProcess.NormalExit, from_cache=cached_output
))
return
process = QProcess(self)
self.processes[category] = process
process.setProcessChannelMode(QProcess.MergedChannels)
env = QProcessEnvironment.systemEnvironment()
env.insert("WINEPREFIX", self.prefix_path)
process.setProcessEnvironment(env)
process.finished.connect(partial(self._on_load_finished, category))
process.start(self.winehelper_path, ["winetricks", category, "list"])
def _parse_winetricks_log(self):
"""Читает winetricks.log и возвращает множество установленных компонентов."""
log_reader = WinetricksLogReader(self.prefix_path)
return log_reader.get_installed_verbs()
def _parse_winetricks_list_output(self, output, installed_verbs, list_widget, category):
"""Парсит вывод 'winetricks list' и заполняет QListWidget."""
parser = WinetricksOutputParser()
items, found_items = parser.parse_list_output(output, installed_verbs, category)
for item_data in items:
item = QListWidgetItem(item_data.item_text)
item.setData(Qt.UserRole, item_data.name)
item.setFont(QFont("DejaVu Sans Mono", 10))
item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
item.setCheckState(Qt.Checked if item_data.is_installed else Qt.Unchecked)
list_widget.addItem(item)
self.initial_states[item_data.name] = item_data.is_installed
return found_items
def _on_load_finished(self, category, exit_code, exit_status, from_cache=None):
"""Обрабатывает завершение загрузки списка компонентов."""
if from_cache is not None:
output = from_cache
process = None
else:
process = self.processes[category]
output = process.readAllStandardOutput().data().decode('utf-8', 'ignore')
list_widget = self.list_widgets.get(category)
if list_widget is None:
return
category_display_name = next(
(k for k, v in self.categories.items() if v == category),
category
)
list_widget.clear()
if exit_code != 0 or exit_status != QProcess.NormalExit:
error_string = process.errorString() if process else "N/A"
self._log(f"--- Ошибка загрузки категории '{category_display_name}' (код: {exit_code}) ---", "red")
if exit_status == QProcess.CrashExit:
self._log("--- Процесс winetricks завершился аварийно. ---", "red")
if error_string != "Неизвестная ошибка":
self._log(f"--- Системная ошибка: {error_string} ---", "red")
self._log(output if output.strip() else "Winetricks не вернул вывод. Проверьте, что он работает корректно.")
self._log("--------------------------------------------------", "red")
else:
installed_verbs = self._parse_winetricks_log()
found_items = self._parse_winetricks_list_output(output, installed_verbs, list_widget, category)
if from_cache is None:
if not self.cache_service.save_to_cache(category, output, self.winetricks_path):
self._log(f"--- Не удалось сохранить кэш для '{category}' ---")
if not found_items and output.strip():
self._log(f"--- Не удалось распознать вывод для категории '{category}' ---")
self._log(output)
self._log("--------------------------------------------------")
has_errors = any(status == 'error' for status in self.category_statuses.values())
self.loading_count -= 1
if self.loading_count == 0:
self._update_ui_state()
if self.is_reloading_after_cache_clear:
if has_errors:
self._log("\n=== Ошибка при обновлении списков. Проверьте лог выше. ===", "red")
else:
self._log("\n=== Списки успешно обновлены ===")
self.is_reloading_after_cache_clear = False
def _on_item_changed(self, item):
"""Обрабатывает изменение состояния чекбокса."""
name = item.data(Qt.UserRole)
if name in self.initial_states and self.initial_states.get(name) is True:
if item.checkState() == Qt.Unchecked:
list_widget = item.listWidget()
if list_widget:
list_widget.blockSignals(True)
item.setCheckState(Qt.Checked)
if list_widget:
list_widget.blockSignals(False)
self._update_ui_state()
def _update_ui_state(self, *args):
"""Обновляет состояние кнопок 'Применить' и 'Переустановить'."""
has_changes = False
for list_widget in self.list_widgets.values():
for i in range(list_widget.count()):
item = list_widget.item(i)
name = item.data(Qt.UserRole)
if name in self.initial_states:
initial_state = self.initial_states[name]
current_state = item.checkState() == Qt.Checked
if current_state != initial_state:
has_changes = True
break
if has_changes:
break
self.apply_button.setEnabled(has_changes)
is_reinstallable = False
if not has_changes:
current_index = self.tabs.currentIndex()
if current_index >= 0:
category = list(self.categories.values())[current_index]
current_list_widget = self.list_widgets.get(category)
if current_list_widget:
current_item = current_list_widget.currentItem()
if current_item:
name = current_item.data(Qt.UserRole)
if self.initial_states.get(name, False):
is_reinstallable = True
self.reinstall_button.setEnabled(is_reinstallable)
def reinstall_selected(self):
"""Переустанавливает выбранный компонент."""
current_index = self.tabs.currentIndex()
if current_index < 0:
return
category = list(self.categories.values())[current_index]
current_list_widget = self.list_widgets.get(category)
if not current_list_widget:
return
current_item = current_list_widget.currentItem()
if not current_item:
return
name = current_item.data(Qt.UserRole)
if not name:
return
self.log_output.setText(self.INFO_TEXT)
self.apply_button.setEnabled(False)
self.reinstall_button.setEnabled(False)
self.close_button.setEnabled(False)
verbs_to_reinstall = [name]
self._start_install_process([], verbs_to_reinstall)
def apply_changes(self):
"""Применяет выбранные изменения."""
verbs_to_install = []
verbs_to_reinstall = []
for list_widget in self.list_widgets.values():
for i in range(list_widget.count()):
item = list_widget.item(i)
name = item.data(Qt.UserRole)
if name not in self.initial_states:
continue
initial_state = self.initial_states[name]
current_state = item.checkState() == Qt.Checked
if current_state != initial_state:
if initial_state:
verbs_to_reinstall.append(name)
else:
verbs_to_install.append(name)
if not verbs_to_install and not verbs_to_reinstall:
QMessageBox.information(self, "Нет изменений", "Не выбрано ни одного компонента для установки.")
return
self.log_output.setText(self.INFO_TEXT)
self.apply_button.setEnabled(False)
self.reinstall_button.setEnabled(False)
self.close_button.setEnabled(False)
self._start_install_process(verbs_to_install, verbs_to_reinstall)
def _start_install_process(self, verbs_to_install, verbs_to_reinstall=None):
"""Запускает процесс установки/переустановки winetricks.
Args:
verbs_to_install: Список компонентов для новой установки (без --force)
verbs_to_reinstall: Список компонентов для переустановки (с --force)
"""
if verbs_to_reinstall is None:
verbs_to_reinstall = []
# Устанавливает новые компоненты (без --force)
if verbs_to_install:
self._install_queue.append((verbs_to_install, False))
# Переустанавливает компоненты (с --force)
if verbs_to_reinstall:
self._install_queue.append((verbs_to_reinstall, True))
# Запускаем первую задачу, если сейчас ничего не выполняется
if not self.apply_process or self.apply_process.state() != QProcess.Running:
self._process_next_install_task()
def _process_next_install_task(self):
"""Берёт следующую задачу из очереди и запускает процесс."""
if not self._install_queue:
return
verbs, use_force = self._install_queue.pop(0)
if use_force:
self._log(f"Выполнение переустановки: winehelper winetricks --force {' '.join(verbs)}")
else:
self._log(f"Выполнение установки: winehelper winetricks {' '.join(verbs)}")
self._run_winetricks_process(verbs, use_force)
def _run_winetricks_process(self, verbs, use_force=False):
"""Запускает процесс winetricks с указанными компонентами.
Args:
verbs: Список компонентов для установки
use_force: Использовать ли флаг --force
"""
args = []
if use_force:
args.append("--force")
args.extend(verbs)
# Всегда создаём новый QProcess, чтобы избежать повторного вызова start()
# и дублирования обработчиков сигналов.
if self.apply_process:
try:
self.apply_process.readyReadStandardOutput.disconnect()
self.apply_process.finished.disconnect(self.on_apply_finished)
except TypeError:
pass
self.apply_process = QProcess(self)
self.apply_process.setProcessChannelMode(QProcess.MergedChannels)
env = QProcessEnvironment.systemEnvironment()
env.insert("WINEPREFIX", self.prefix_path)
self.apply_process.setProcessEnvironment(env)
self.apply_process.readyReadStandardOutput.connect(
lambda: self.log_output.append(
self.apply_process.readAllStandardOutput().data().decode('utf-8', 'ignore').strip()
)
)
self.apply_process.finished.connect(self.on_apply_finished)
self.apply_process.start(self.winehelper_path, ["winetricks"] + args)
def on_apply_finished(self, exit_code, exit_status):
"""Обрабатывает завершение применения изменений."""
if self.user_cancelled:
self._install_queue.clear()
self._log("\n=== Установка прервана пользователем. ===")
self.close()
return
if exit_code != 0 or exit_status != QProcess.NormalExit:
self._install_queue.clear()
self._log(f"\n=== Ошибка во время выполнения операций (код: {exit_code}). ===", "red")
self._show_message_box(
"Ошибка",
"Произошла ошибка во время выполнения операций.\nПодробности смотрите в логе.",
QMessageBox.Warning,
{"buttons": {"OK": QMessageBox.AcceptRole}}
)
self.log_output.setCurrentCharFormat(QTextCharFormat())
self.apply_button.setEnabled(True)
self.close_button.setEnabled(True)
return
if self._install_queue:
self._process_next_install_task()
return
self._log("\n=== Все операции успешно завершены ===")
self.apply_button.setEnabled(True)
self.reinstall_button.setEnabled(False)
self.close_button.setEnabled(True)
for search_edit in self.search_edits.values():
search_edit.clear()
self.initial_states.clear()
self.load_all_categories()
self.installation_complete.emit()
self.installation_finished = True
def clear_winetricks_cache(self):
"""Запускает очистку кэша Winetricks."""
if not DialogUtils.confirm(
self,
"Очистка кэша Winetricks",
"Вы собираетесь удалить все скачанные установщики и списки компонентов Winetricks.\n\n"
"Это действие может потребоваться, если у вас возникают проблемы "
"со скачиванием или установкой компонентов.\n\n"
"Продолжить?"
):
return
self.tabs.setEnabled(False)
self.clear_cache_button.setEnabled(False)
self.apply_button.setEnabled(False)
self.reinstall_button.setEnabled(False)
self.close_button.setEnabled(False)
self.log_output.clear()
self.cache_clear_process = QProcess(self)
self.cache_clear_process.setProcessChannelMode(QProcess.MergedChannels)
def handle_output():
output = self.cache_clear_process.readAll().data().decode('utf-8', 'ignore').strip()
if output:
self._log(output)
def handle_finish(exit_code, exit_status):
if exit_code == 0:
self.is_reloading_after_cache_clear = True
self.category_statuses.clear()
self.cache_service._ensure_cache_dir()
self._log("Обновление списков...")
self.initial_states.clear()
self.load_all_categories()
else:
self._log(f"\n=== Ошибка (код: {exit_code}) ===", "red")
self.tabs.setEnabled(True)
self.clear_cache_button.setEnabled(True)
self.close_button.setEnabled(True)
self._update_ui_state()
self.cache_clear_process.readyRead.connect(handle_output)
self.cache_clear_process.finished.connect(handle_finish)
if self.parent() and hasattr(self.parent(), 'winehelper_path'):
winehelper_path = self.parent().winehelper_path
else:
winehelper_path = EnvironmentConfig.RUN_SCRIPT
args = ["clear-winetricks-cache", "--force"]
self._log(f"Выполнение: {shlex.quote(winehelper_path)} {' '.join(args)}\n")
self.cache_clear_process.start(winehelper_path, args)
def closeEvent(self, event):
"""Обрабатывает закрытие окна."""
if self.apply_process and self.apply_process.state() == QProcess.Running:
if DialogUtils.confirm(
self,
'Подтверждение',
"Процесс установки еще не завершен. Вы уверены, что хотите прервать его?"
):
self.user_cancelled = True
self.log_output.append("\n=== Прерывание установки... Ожидание завершения процесса... ===")
self.apply_process.terminate()
event.ignore()
else:
event.accept()
def _log(self, message, color=None):
"""Добавляет сообщение в лог с возможностью указания цвета."""
if color:
self.log_output.append(f'<span style="color:{color};">{message}</span>')
self.log_output.setCurrentCharFormat(QTextCharFormat())
else:
self.log_output.append(message)
self.log_output.moveCursor(QTextCursor.End)
Loaded 100 of 125 files, more files were not shown because too many files have changed in this diff. Show more