Compare commits

...

54 Commits

Author SHA1 Message Date
Mikhail Tergoev
0475c7e058 added dialux to testinstall 2026-01-20 20:20:15 +03:00
Mikhail Tergoev
b146b01a82 fixed create and repair base pfx 2026-01-20 20:18:34 +03:00
Mikhail Tergoev
41232f2315 added skip check i586 dependencies if wine-wow64 2026-01-20 16:53:29 +03:00
Mikhail Tergoev
73696de876 dropped check dependencies from gui 2026-01-20 14:22:23 +03:00
Mikhail Tergoev
3cbdef4f00 disabled check dependencies if without terminal 2026-01-19 19:37:51 +03:00
Mikhail Tergoev
4b0fea887b added skip check dependencies if wine-wow64 in use 2026-01-19 18:47:49 +03:00
Mikhail Tergoev
4d77861863 ksamu: fixed pid variable 2026-01-16 14:15:20 +03:00
Mikhail Tergoev
2854f8751b ksamu: fixed open in background choose cert file 2026-01-16 13:31:33 +03:00
Mikhail Tergoev
53a09b13d7 dropped wine-10.18.1-alt2-wow64 2026-01-16 13:14:12 +03:00
Mikhail Tergoev
0df709380c updated dialux pfx to v2 2026-01-16 11:59:26 +03:00
Mikhail Tergoev
e49a267d4c added termination of background process if present 2026-01-16 00:31:41 +03:00
Mikhail Tergoev
9724b75fc2 WINEDEBUG=-all by default 2026-01-16 00:00:28 +03:00
Mikhail Tergoev
436e250932 added FREETYPE_PROPERTIES 2026-01-15 23:55:16 +03:00
Mikhail Tergoev
6160eef77b added dialux_pfx_x86_v01 2026-01-15 21:18:36 +03:00
Mikhail Tergoev
26a92bea4d updated variables for last.conf and .whdb 2026-01-15 19:12:26 +03:00
Mikhail Tergoev
de57b947bf ksamu: updated wine and added fix WINE_TOP_WINDOW 2026-01-15 19:02:45 +03:00
Mikhail Tergoev
e43678193a added wine-10.18.1-alt2-wow64 with WINE_TOP_WINDOW 2026-01-15 18:56:17 +03:00
Mikhail Tergoev
032c03fbb1 ved-control: updated url and file name 2026-01-15 18:53:10 +03:00
Mikhail Tergoev
8d82125e74 updated test script ksamu 2025-12-29 21:03:01 +03:00
Mikhail Tergoev
f067412a29 updated ksamu_pfx_x64 v02 2025-12-29 21:00:53 +03:00
Mikhail Tergoev
d9ffca88d1 fixed disable virtual desktop 2025-12-29 20:41:51 +03:00
Mikhail Tergoev
7d925bdd15 added WH_VIRTUAL_DESKTOP 2025-12-26 16:27:33 +03:00
Mikhail Tergoev
bcf53c361c updated ksamu (test without cades) 2025-12-23 14:34:53 +03:00
Mikhail Tergoev
5b38f2c10d added variables for enable/disable decorated 2025-12-23 14:31:44 +03:00
Mikhail Tergoev
aec21eda1e added wine-10.18.1-alt1-wow64 2025-12-23 12:18:07 +03:00
Mikhail Tergoev
f8ce14d725 added new default variables 2025-12-22 14:35:49 +03:00
Mikhail Tergoev
ce1fb05fc7 install win cades if WH_USE_CPCSP_CADES=1 2025-12-22 14:24:18 +03:00
Mikhail Tergoev
659b0b1f5b added more 32-bit dependencies 2025-12-19 12:42:01 +03:00
Mikhail Tergoev
3732f71b7b added version WH to log 2025-12-18 20:36:01 +03:00
Mikhail Tergoev
d4f2d367b5 Merge branch 'minergenon-devel' 2025-12-18 12:31:35 +03:00
Mikhail Tergoev
a75e6c4f83 added sorting for variables in log file 2025-12-18 12:31:14 +03:00
Sergey Palcheh
fd2759f52b horizontal scrollbar disabled:
- the Installed tab in the Wine version selection dialog
- download bookmarks (WINE AMD64, WINE WOW64, WINE I586)
- dialog for selecting the component version (DXVK/VKD3D)
- tabs of the main window: Automatic installation, Manual installation, Installed
2025-12-18 11:28:38 +06:00
Mikhail Tergoev
06f3cbaf68 dropped force WINE_D3D_CONFIG for wayland 2025-12-17 22:40:43 +03:00
Mikhail Tergoev
cf375cc5c4 updated CPCSP_PROXY_WOW64_VER to 0.7.7-alt1-wow64 2025-12-17 22:28:55 +03:00
Mikhail Tergoev
681d80f0d8 ppdgr2: temporary printing fix 2025-12-17 22:10:10 +03:00
Mikhail Tergoev
07ca88cb64 updated t-flex pfx v04 2025-12-16 15:50:51 +03:00
Mikhail Tergoev
0cf3425f14 init_wineprefix: forced use of various hacks is disabled 2025-12-16 14:10:56 +03:00
Mikhail Tergoev
e4f56c7164 moved winemenubuilder.exe,winebth.sys=d to prepair_wine 2025-12-07 13:48:21 +03:00
Mikhail Tergoev
fb0336b3ef fixed ppdgr2 script 2025-12-05 16:01:58 +03:00
Mikhail Tergoev
5095e73409 Merge branch 'minergenon-devel' 2025-12-05 15:53:32 +03:00
Mikhail Tergoev
bc6000018b returned prefix separation for nalog programs 2025-12-05 15:51:47 +03:00
Sergey Palcheh
e3adf19624 fixed the display of icons for t-flex* in the manual installation tab 2025-12-04 14:03:33 +06:00
Sergey Palcheh
dc7a996060 added ICONS_BUTTON_GUI variable for GUI 2025-12-04 13:59:54 +06:00
Sergey Palcheh
eca1905c62 added a default icon for files.exe without an icon 2025-12-04 12:49:03 +06:00
Sergey Palcheh
371b2b7484 the prefix name was added to the list immediately after it was restored 2025-12-04 09:55:38 +06:00
Mikhail Tergoev
1f4cb54f54 revert d3d* for winetricks 2025-12-03 17:33:20 +03:00
Mikhail Tergoev
af52bd74d0 Merge branch 'minergenon-devel' 2025-12-03 14:55:26 +03:00
Sergey Palcheh
ded62bd9ac the description of the prepared prefix has been corrected 2025-12-03 12:43:49 +06:00
Sergey Palcheh
15b6fdd216 added HiDPI support 2025-12-02 13:28:35 +06:00
Sergey Palcheh
33bba61891 the choice of the prefix template has been changed 2025-12-01 10:45:36 +06:00
Mikhail Tergoev
cbf0bdbf8a added check restore_pfx.sh after restor-prefix 2025-11-26 13:17:27 +03:00
Mikhail Tergoev
5953d4b122 Merge branch 'minergenon-devel' 2025-11-24 13:49:07 +03:00
Sergey Palcheh
e12b24ccbc updating the README to the current one 2025-11-20 14:57:18 +06:00
Sergey Palcheh
4d653cdd41 changed the installation of wine versions 2025-11-19 11:42:21 +06:00
40 changed files with 751 additions and 711 deletions

View File

@@ -239,6 +239,13 @@ WineHelper предоставляет доступ к основным инст
<p><em>Вкладка "Ручная установка"</em></p> <p><em>Вкладка "Ручная установка"</em></p>
</div> </div>
Так же на вкладке **Автоматическая установка** есть чекбокс с тестовыми версиями скриптов установки которые еще не прошли полную проверку на зависимости и совместимость, но уже можно попробовать в работе.
<div align="center">
<img src="image/handbook/auto_install_test.png">
<p><em>Тестовые версии скриптов установки</em></p>
</div>
Для поиска нужной программы введите название в поле поиска. Для поиска нужной программы введите название в поле поиска.
<div align="center"> <div align="center">
@@ -246,7 +253,7 @@ WineHelper предоставляет доступ к основным инст
<p><em>Поле поиска</em></p> <p><em>Поле поиска</em></p>
</div> </div>
При выборе программы из списка слева, в правой части окна отображается подробная информация о ней: описание, иконка и ссылка на официальный сайт. При выборе программы из списка слева, в правой части окна отображается подробная информация о ней: описание и ссылка на официальный сайт.
<div align="center"> <div align="center">
<img src="image/handbook/info.png"> <img src="image/handbook/info.png">
@@ -271,7 +278,7 @@ WineHelper предоставляет доступ к основным инст
<div align="center"> <div align="center">
<img src="image/handbook/log.png"> <img src="image/handbook/log.png">
<p><em>Окно установки с логом</em></м</em></p> <p><em>Окно установки с логом</em></p>
</div> </div>
После установки приложения и нажатия кнопки **Закрыть** в окне установки приложения, ярлык приложения появится в списке установленных приложений во вкладке **Установленные** а также в меню приложений и на рабочем столе если это разрешено в рабочем окружении. После установки приложения и нажатия кнопки **Закрыть** в окне установки приложения, ярлык приложения появится в списке установленных приложений во вкладке **Установленные** а также в меню приложений и на рабочем столе если это разрешено в рабочем окружении.
@@ -323,7 +330,7 @@ WineHelper предоставляет доступ к основным инст
* **Версию Wine/Proton** из доступного списка. * **Версию Wine/Proton** из доступного списка.
<div align="center"> <div align="center">
<img src="image/handbook/create_prefix.png"> <img src="image/handbook/prefix_create.png">
<p><em>Диалог создания нового префикса</em></p> <p><em>Диалог создания нового префикса</em></p>
</div> </div>
@@ -339,9 +346,9 @@ WineHelper предоставляет доступ к основным инст
* `Файловый менеджер (winefile)` * `Файловый менеджер (winefile)`
* **Управлять компонентами**: * **Управлять компонентами**:
* **Менеджер компонентов (Winetricks)**: Удобный интерфейс для установки и переустановки библиотек, шрифтов и настроек. * **Менеджер компонентов (Winetricks)**: Удобный интерфейс для установки и переустановки библиотек, шрифтов и настроек.
* **Управление Wine/Proton**: Смена версии Wine или Proton для выбранного префикса. * **Управление Wine/Proton**: Смена версии Wine или Proton для выбранного префикса. Диалог выбора позволяет как выбрать уже установленную версию, так и скачать новую из списков, сгруппированных по архитектуре.
* **Управление DXVK/VKD3D**: Установка или удаление конкретных версий DXVK и VKD3D. * **Управление DXVK/VKD3D**: Установка или удаление конкретных версий DXVK и vkd3d-proton.
* **Ассоциации файлов**: Настройка открытия определенных типов файлов (например, `.pdf`, `.docx`) нативными приложениями Linux. * **Ассоциации файлов**: Настройка открытия определенных типов файлов (например, `.pdf`, `.docx`) нативными приложениями Linux, чтобы избежать их открытия внутри Wine.
* **Включать/выключать ESync и FSync**. * **Включать/выключать ESync и FSync**.
* **Устанавливать приложения**: Установить любой `.exe` или `.msi` файл напрямую в выбранный префикс. * **Устанавливать приложения**: Установить любой `.exe` или `.msi` файл напрямую в выбранный префикс.
* **Создавать ярлыки**: Создать ярлык для любого исполняемого файла внутри префикса. * **Создавать ярлыки**: Создать ярлык для любого исполняемого файла внутри префикса.
@@ -349,10 +356,14 @@ WineHelper предоставляет доступ к основным инст
Справа отображается подробная информация о конфигурации выбранного префикса. Справа отображается подробная информация о конфигурации выбранного префикса.
В самом низу вкладки находится кнопка **«Удалить все данные WineHelper»**.
> [!CAUTION]
> Эта функция полностью и безвозвратно удаляет все префиксы, настройки, кэш и ярлыки, созданные WineHelper. Используйте с осторожностью! Программа запросит двойное подтверждение для предотвращения случайного удаления.
### Вкладка «Справка» ### Вкладка «Справка»
Содержит полезную информацию о проекте: Содержит полезную информацию о проекте:
* **Руководство**: Ссылка на официальную документацию. * **Общее**: Ссылка на официальную документацию.
* **Авторы**: Список разработчиков и участников проекта. * **Авторы**: Список разработчиков и участников проекта.
* **Лицензия**: Текст лицензии WineHelper и информация о сторонних компонентах. * **Лицензия**: Текст лицензии WineHelper и информация о сторонних компонентах.
* **История изменений**: Changelog пакета. * **История изменений**: Changelog пакета.

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD Учебная Версия 17" export PROG_NAME="T-FLEX CAD Учебная Версия 17"
export PROG_ICON="tflexcad17" export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 17" export PROG_NAME="T-FLEX CAD 17"
export PROG_ICON="tflexcad17" export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -6,7 +6,7 @@ export PROG_NAME="Приложения для T-FLEX CAD 17"
export PROG_ICON="tflexcad17" export PROG_ICON="tflexcad17"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"

View File

@@ -6,7 +6,7 @@ export PROG_NAME="Ресурсы для T-FLEX CAD 17"
export PROG_ICON="tflexcad17" export PROG_ICON="tflexcad17"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 18" export PROG_NAME="T-FLEX CAD 18"
export PROG_ICON="tflexcad18" export PROG_ICON="tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -6,7 +6,7 @@ export PROG_NAME="Приложения для T-FLEX CAD 18"
export PROG_ICON="tflexcad18" export PROG_ICON="tflexcad18"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"

View File

@@ -6,7 +6,7 @@ export PROG_NAME="Ресурсы для T-FLEX CAD 18"
export PROG_ICON="tflexcad18" export PROG_ICON="tflexcad18"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 2D+ 17" export PROG_NAME="T-FLEX CAD 2D+ 17"
export PROG_ICON="tflexcad17" export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX CAD 2D+ 18" export PROG_NAME="T-FLEX CAD 2D+ 18"
export PROG_ICON="tflexcad18" export PROG_ICON="tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -5,12 +5,13 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX DOCs 17" export PROG_NAME="T-FLEX DOCs 17"
export PROG_ICON="tflexdoc17" export PROG_ICON="tflexdoc17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1" export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=gdi"
# используем общий whdb файл для подготовки префикса и сервисов # используем общий whdb файл для подготовки префикса и сервисов
# prepair_wine используется из файла настроек # prepair_wine используется из файла настроек

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX Viewer 17" export PROG_NAME="T-FLEX Viewer 17"
export PROG_ICON="tflexcad17" export PROG_ICON="tflexcad17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -5,7 +5,7 @@ export PROG_URL="https://www.tflexcad.ru"
export PROG_NAME="T-FLEX Viewer 18" export PROG_NAME="T-FLEX Viewer 18"
export PROG_ICON="tflexcad18" export PROG_ICON="tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -16,11 +16,11 @@ prepair_wine
# фикс постоянного запроса обновления Windows # фикс постоянного запроса обновления Windows
get_and_set_reg_file --add 'Software\CTM\CTMSETUP' 'SkipKBCheck' 'REG_DWORD' "1" "userdef" get_and_set_reg_file --add 'Software\CTM\CTMSETUP' 'SkipKBCheck' 'REG_DWORD' "1" "userdef"
AUTOINSTALL_EXE="${WH_TMP_DIR}/setup_cl.exe" AUTOINSTALL_EXE="${WH_TMP_DIR}/setup_ct.exe"
AUTOINSTALL_UNPACK="${WH_TMP_DIR}/setup_cl" AUTOINSTALL_UNPACK="${WH_TMP_DIR}/setup_ct"
AUTOINSTALL_SETUP="${WH_TMP_DIR}/setup_cl/setup.exe" AUTOINSTALL_SETUP="${WH_TMP_DIR}/setup_ct/setup.exe"
if try_download "https://ftp.ctm.ru/CONTROL/SFX/setup_cl.exe" "${AUTOINSTALL_EXE}" ; then if try_download "https://ftp.ctm.ru/CONTROL/SFX/setup_ct.exe" "${AUTOINSTALL_EXE}" ; then
unpack "${AUTOINSTALL_EXE}" "${AUTOINSTALL_UNPACK}" unpack "${AUTOINSTALL_EXE}" "${AUTOINSTALL_UNPACK}"
try_remove_file "$AUTOINSTALL_EXE" try_remove_file "$AUTOINSTALL_EXE"

View File

@@ -3,12 +3,13 @@
######################################################################## ########################################################################
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export PROG_VERSION="" export PROG_VERSION=""
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"
export INSTALL_DLL="corefonts d3dcompiler_47 dotnet48 dotnet20 vcrun2019 ucrtbase2019 msxml6 fontsmooth=rgb baekmuk droid eufonts ipamona liberation lucida opensymbol sourcehansans tahoma takao uff unifont vlgothic wenquanyi wenquanyizenhei" export INSTALL_DLL="d3dcompiler_47 dotnet48 dotnet20 vcrun2019 ucrtbase2019 msxml6"
# fontsmooth=rgb corefonts baekmuk droid eufonts ipamona liberation lucida opensymbol sourcehansans tahoma takao uff unifont vlgothic wenquanyi wenquanyizenhei"
export WH_USE_MESA_GL_OVERRIDE="1" export WH_USE_MESA_GL_OVERRIDE="1"
GRDCONTROL_VER="4.3.0-0" GRDCONTROL_VER="4.3.0-0"
@@ -31,9 +32,10 @@ then
print_info "Префикс $PREFIX_NAME готов к установке ПО." print_info "Префикс $PREFIX_NAME готов к установке ПО."
print_info "Сервисы: aksusbd и hasplmd уже запущены. grdcontrol-$GRDCONTROL_VER установлен." print_info "Сервисы: aksusbd и hasplmd уже запущены. grdcontrol-$GRDCONTROL_VER установлен."
else else
print_warning "Службы aksusbd и hasplmd не запущены, или grdcontrol-$GRDCONTROL_VER не установлен." print_warning "Проверка и подготовка префикса, служб aksusbd, hasplmd и grdcontrol-$GRDCONTROL_VER."
if [[ "$BASE_PFX" == "none" ]] \ if [[ "$BASE_PFX" == "none" ]] \
|| ! grep -q "t-flex-cad" "$WINEPREFIX/winetricks.log" \
|| ! systemctl list-units --type service --state running | grep aksusbd \ || ! systemctl list-units --type service --state running | grep aksusbd \
|| ! systemctl list-units --type service --state running | grep hasplmd \ || ! systemctl list-units --type service --state running | grep hasplmd \
|| ! rpm -q grdcontrol | grep -q "$GRDCONTROL_VER" || ! rpm -q grdcontrol | grep -q "$GRDCONTROL_VER"

View File

@@ -7,23 +7,29 @@ if [[ $(id -u) -ne 0 ]] ; then
fi fi
##### MESSAGES FUNCTIONS ##### ##### MESSAGES FUNCTIONS #####
print_error () { printf "\E[31m%s ВНИМАНИЕ: $@ %s\e[0m\n" ;} if [[ -t 0 ]] ; then
fatal () { print_error "$@" ; exit 1 ;} print_error () { printf "\E[31m%s Ошибка: $* %s\e[0m\n" ;}
else
print_error () { echo -e "Ошибка: $*" ;}
fi
##### UPDATE SYSTEM ##### fatal () {
apt-get update || fatal "Не удалось обновить список доступных пакетов," print_error "$@ Аварийное завершение работы WineHelper!"
exit 1
}
##### CHECK AREPO (x86_64-i586) ##### ##### CHECK AREPO (x86_64-i586) #####
apt-repo | grep -q "x86_64-i586" || fatal "Репозиторий x86_64-i586 не подключен. \ apt-repo | grep -q "x86_64-i586" || fatal "Репозиторий x86_64-i586 не подключен. \
32-битные зависимости не будут установлены, а значит не будут работать и 32-битные \ 32-битные зависимости не будут установлены, а значит не будут работать и 32-битные \
windows приложения. Подробнее по ссылке: https://www.altlinux.org/Biarch" windows приложения. Подробнее по ссылке: https://www.altlinux.org/Biarch"
##### UPDATE SYSTEM #####
apt-get update || fatal "Не удалось обновить список доступных пакетов,"
##### INSTALL DEPENDENCIES ##### ##### INSTALL DEPENDENCIES #####
# fonts-ttf-ms # fonts-ttf-ms
apt-get install {i586-,}{glibc-core,libstdc++6,glibc-pthread,glibc-nss,\ apt-get install i586-{wine,glibc-core,libstdc++6,glibc-pthread,glibc-nss,\
libnss-mdns,libunixODBC2,ocl-icd,libfreetype,libfontconfig1,\ libnm,libnss,libnss-mdns,libnsl1,libunwind,libunixODBC2,ocl-icd,libfreetype,\
libgnutls30,libGL,libEGL,xorg-dri-swrast,xorg-dri-intel,xorg-dri-radeon,\ libcups,libfontconfig1,libgnutls30,libGL,libEGL,libvulkan1,xorg-dri-swrast,\
libvulkan1,libcups} || fatal "Не удалось установить зависимости." xorg-dri-intel,xorg-dri-radeon} || fatal "Не удалось установить зависимости."
apt-get install {i586-,}wine

BIN
image/dialux.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 125 KiB

BIN
image/wh_default.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -2,9 +2,9 @@
# info_ru: Ручная установка дополнений для T-FLEX CAD 17 или 18 # info_ru: Ручная установка дополнений для T-FLEX CAD 17 или 18
######################################################################## ########################################################################
export PROG_NAME="T-FLEX CAD 17/18" export PROG_NAME="T-FLEX CAD 17/18"
export PROG_ICON="tflexcad" export ICONS_BUTTON_GUI="tflexcad17 tflexcad18"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"

View File

@@ -2,14 +2,15 @@
# info_ru: Ручная установка дополнений для T-FLEX DOCS 17 или 18 # info_ru: Ручная установка дополнений для T-FLEX DOCS 17 или 18
######################################################################## ########################################################################
export PROG_NAME="T-FLEX DOCS 17/18" export PROG_NAME="T-FLEX DOCS 17/18"
export PROG_ICON="tflexcad" export PROG_ICON="tflexdoc17"
export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64" export WH_WINE_USE="wine-10.18.1-tflex-alt2-wow64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v04"
export WINEARCH="win64" export WINEARCH="win64"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEPREFIX="tflex" export WINEPREFIX="tflex"
export WH_XDG_OPEN="log" export WH_XDG_OPEN="log"
export WH_USE_MESA_GL_OVERRIDE="1" export WH_USE_MESA_GL_OVERRIDE="1"
export WINE_D3D_CONFIG="renderer=gdi"
if [[ -f "$2" ]] ; then if [[ -f "$2" ]] ; then
# используем общий whdb файл для подготовки префикса и сервисов # используем общий whdb файл для подготовки префикса и сервисов

View File

@@ -1,6 +1,7 @@
##### WINE WOW64 ##### ##### WINE WOW64 #####
e9a8b79dfe12cad1304dca573d73aefe109e3d69b6fff739c8dbb8b2d3c271c6 wine-10.12.1-alt1-wow64.tar.xz e9a8b79dfe12cad1304dca573d73aefe109e3d69b6fff739c8dbb8b2d3c271c6 wine-10.12.1-alt1-wow64.tar.xz
a862761c432f8619caf8100589678a1cbb523787259120ccd4388089d81e3b17 wine-10.18.1-tflex-alt2-wow64.tar.xz a862761c432f8619caf8100589678a1cbb523787259120ccd4388089d81e3b17 wine-10.18.1-tflex-alt2-wow64.tar.xz
349c707148a23e667970309248bbbf97b4e2a0db59c548e73d9fe9c3f585872c wine-10.18.1-alt1-wow64.tar.xz
##### WINE AMD64 ##### ##### WINE AMD64 #####
009c95bfe2df3f9264c9c5092f3e30ea7a168dd7869046058a718a70739602d4 wine_wh_tflex_10-9_amd64.tar.xz 009c95bfe2df3f9264c9c5092f3e30ea7a168dd7869046058a718a70739602d4 wine_wh_tflex_10-9_amd64.tar.xz
@@ -114,6 +115,7 @@ edf16d2b37bc77d121d5d81b06b60d3f694e0060c6606e729ceab30de3d27466 vkd3d-proton-s
##### CPCSP_PROXY ##### ##### CPCSP_PROXY #####
3153088ff28d6af415c3504a421e5382554dbb305f38d5a87dd84df90d680421 wine-cpcsp_proxy-0.6.1-alt1.tar.xz 3153088ff28d6af415c3504a421e5382554dbb305f38d5a87dd84df90d680421 wine-cpcsp_proxy-0.6.1-alt1.tar.xz
fbe72bfe3c2c307363782ce2d37589e142b44111f269657b0e516a6b2d6ab8a9 wine-cpcsp_proxy-0.7.3-alt5-wow64.tar.xz fbe72bfe3c2c307363782ce2d37589e142b44111f269657b0e516a6b2d6ab8a9 wine-cpcsp_proxy-0.7.3-alt5-wow64.tar.xz
6f43427148c6f424cd49a406328669e4ec4f21df7bc86f1a6aad2b5c16b50e39 wine-cpcsp_proxy-0.7.7-alt1-wow64.tar.xz
##### FONTS ##### ##### FONTS #####
405bfe3b7c7f80034837c05656535053305727ee4bf1d993521b67b71d08ebc6 extra_fonts_v01.tar.xz 405bfe3b7c7f80034837c05656535053305727ee4bf1d993521b67b71d08ebc6 extra_fonts_v01.tar.xz
@@ -143,6 +145,10 @@ eb1fec64eea3d83f2bdce185c7bc0c1a93afb51139f16256c885098a6f7e2242 defpfx_dn48_x6
# create with wine_wh_tflex_10-9_amd64 # create with wine_wh_tflex_10-9_amd64
# winetricks isolate_home msxml6 ipamona opensymbol wenquanyi ucrtbase2019 uff unifont droid wenquanyizenhei internal dotnet48 dotnet20 eufonts takao d3dcompiler_47 fontsmooth=rgb vcrun2019 vlgothic andale arial comicsans courier georgia impact times trebuchet verdana webdings corefonts liberation sourcehansans baekmuk tahoma lucida t-flex-cad-prepair # winetricks isolate_home msxml6 ipamona opensymbol wenquanyi ucrtbase2019 uff unifont droid wenquanyizenhei internal dotnet48 dotnet20 eufonts takao d3dcompiler_47 fontsmooth=rgb vcrun2019 vlgothic andale arial comicsans courier georgia impact times trebuchet verdana webdings corefonts liberation sourcehansans baekmuk tahoma lucida t-flex-cad-prepair
e71a03b4d26d7ac7091ed526d50103f95cb08ce53dd54a7f52381b8b74c1bc17 tflex_pfx_x64_v04.tar.xz
# create with wine-10.18.1-tflex-alt2-wow64
# winetricks isolate_home msxml6 ucrtbase2019 fontfix dotnet20 dotnet40 dotnet48 d3dcompiler_47 vcrun2019
7edbd69b40b8ca3fb3594933c6cd37030180c494c08fd13cbd1a5b46565d65e6 ved_ctm_pfx_x86_v03.tar.xz 7edbd69b40b8ca3fb3594933c6cd37030180c494c08fd13cbd1a5b46565d65e6 ved_ctm_pfx_x86_v03.tar.xz
# create with wine_x_tkg_10-0_amd64 (universal user: xuser) # create with wine_x_tkg_10-0_amd64 (universal user: xuser)
# winetricks isolate_home msxml6 mdac27 wsh57 jet40 vb6run mdac28 vcrun2022 msxml3 arial dotnet40 dotnet48 art2k7min vcrun6 andale comicsans courier georgia impact times trebuchet verdana webdings corefonts msls31 ie8 # winetricks isolate_home msxml6 mdac27 wsh57 jet40 vb6run mdac28 vcrun2022 msxml3 arial dotnet40 dotnet48 art2k7min vcrun6 andale comicsans courier georgia impact times trebuchet verdana webdings corefonts msls31 ie8
@@ -180,14 +186,24 @@ dfb44ce5e5af7dba1686932c63d6b05e5dd6919a21c78130a7d1d0271b93958e audiorecstatio
# create with wine_x_tkg_10-0_amd64 (universal user: xuser) # 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 # winetricks dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6 dotnet20
# addons with ODBC, SSH, *.reg
0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb scadoffice_addons_v02.tar.xz
ef7e8f1ba785d48e4ea287feed5b79bd630d423e59efadb43da9653adefef218 ais-lpu-client_pfx_x86_v01.tar.xz ef7e8f1ba785d48e4ea287feed5b79bd630d423e59efadb43da9653adefef218 ais-lpu-client_pfx_x86_v01.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser) # create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks vcrun2005 vcrun2008 dotnet20sp2 dotnet40 mfc42 7zip # winetricks vcrun2005 vcrun2008 dotnet20sp2 dotnet40 mfc42 7zip
f18864014fdb2fead0b45b5e70e95073072b89168df8cd6debba89081ac51a2a ksamu_pfx_x64_v01.tar.xz f18864014fdb2fead0b45b5e70e95073072b89168df8cd6debba89081ac51a2a ksamu_pfx_x64_v01.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser) # create with wine-10.12.1-alt1-wow64 (universal user: xuser)
# winetricks msxml6 msxml4 msxml3 riched30 msls31 riched20 msftedit richtx32 fontsmooth=gray # winetricks msxml6 msxml4 msxml3 riched30 msls31 riched20 msftedit richtx32 fontsmooth=gray
# + manuall installed riched32 # + manuall installed riched32
7377159d7f21537e517ecc7bdd4c09d6ccab39f1368688506e78e11cfde7dc2a ksamu_pfx_x64_v02.tar.xz
# create with wine-10.18.1-alt1-wow64 (universal user: xuser)
# winetricks corefonts tahoma msxml6 msxml4 msxml3 riched30 msls31 riched20 msftedit richtx32 fontsmooth=gray
# + manuall installed riched32
06bb83c64ef5e749741fb009a12e07ad62865474c5c7db049894c7871a1471cc dialux_pfx_x86_v04.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks mdac27 wsh57 jet40 msxml6 mdac28 gdiplus msxml4 msxml3 vcrun2010 msls31 ie8 dotnet20sp1
##### ADDONS #####
# addons with ODBC, SSH, *.reg
0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb scadoffice_addons_v02.tar.xz

View File

@@ -3,13 +3,13 @@
######################################################################## ########################################################################
export PROG_URL="https://www.nalog.gov.ru" export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64" export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="nalog" export WINEPREFIX="declaration"
export PROG_NAME="Декларация" export PROG_NAME="Декларация"
export PROG_ICON="declarac" export PROG_ICON="declarac"
export BASE_PFX="none" export BASE_PFX="defpfx_x86_v01"
export WINEARCH="win32" export WINEARCH="win32"
export INSTALL_DLL="msxml3 msxml4 msxml6 corefonts wsh57 vcrun6 jet40 gdiplus"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
try_get_page "https://www.nalog.gov.ru/rn77/program/5961249/" try_get_page "https://www.nalog.gov.ru/rn77/program/5961249/"
VER_YEAR=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-2)}' | head -n 1) VER_YEAR=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-2)}' | head -n 1)

16
testinstall/dialux Normal file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# info_ru: Программное обеспечение для 3D-графики, предназначенное для проектирования освещения. (Версия 4.4.0.2)
########################################################################
export WH_WINE_USE="wine_x_tkg_10-0_i586"
export WINEPREFIX="dialux"
export PROG_NAME="DIALux"
export PROG_ICON="dialux"
export BASE_PFX="dialux_pfx_x86_v04"
export WH_WINDOWS_VER="xp"
export WINEARCH="win32"
export INSTALL_DLL="mdac28 jet40 vcrun2010 gdiplus dotnet20sp1 msxml3 msxml4 msxml6 ie8"
prepair_wine
WIN_FILE_EXEC="$DRIVE_C/Program Files/DIALux/DIALux.exe"
create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON"

View File

@@ -2,17 +2,41 @@
# info_ru: “КСАМУ” - Комплексная система автоматизации медицинского учреждения. # info_ru: “КСАМУ” - Комплексная система автоматизации медицинского учреждения.
######################################################################## ########################################################################
export PROG_URL="https://docs.medicine-it.ru/" export PROG_URL="https://docs.medicine-it.ru/"
export WH_WINE_USE="wine-10.12.1-alt1-wow64" export WH_WINE_USE="wine-10.18.1-alt1-wow64"
export WINEPREFIX="ksamu" export WINEPREFIX="ksamu"
export PROG_NAME="КСАМУ" export PROG_NAME="КСАМУ"
export PROG_ICON="ksamu" export PROG_ICON="ksamu"
export BASE_PFX="ksamu_pfx_x64_v01" export BASE_PFX="ksamu_pfx_x64_v02"
export WINEARCH="win64" export WINEARCH="win64"
export INSTALL_DLL="richtx32 riched20 riched30 msls31 msftedit msxml6 msxml4 msxml3 fontsmooth=gray" export INSTALL_DLL="corefonts tahoma richtx32 riched20 riched30 msls31 msftedit msxml6 msxml4 msxml3 fontsmooth=gray"
# riched32 # riched32
export WH_USE_EXTRA_FONTS="1"
export WH_WINDOWS_VER="7" export WH_WINDOWS_VER="7"
export WH_USE_CPCSP_PROXY="1" export WH_USE_CPCSP_PROXY="1"
export WH_MAIN_DECORATED="1"
export WH_VIRTUAL_DESKTOP="0"
prepair_wine prepair_wine
create_desktop "$PROG_NAME" "$DRIVE_C/KSAMU/KSAMU.exe" "$PROG_ICON" create_desktop "$PROG_NAME" "$DRIVE_C/KSAMU/KSAMU.exe" "$PROG_ICON"
echo '
# хак для исправления открытия выбора файла сертификата в фоне
if ! command -v wmctrl &>/dev/null ; then
wmctrl_not_found="Для продолжения работы установите wmctrl:\n\nsu -\napt-get update\napt-get install wmctrl\nexit"
zenity --error --title="Ошибка" --text="$wmctrl_not_found" --ok-label="Выход"
fatal "$wmctrl_not_found"
fi
background_task() {
while true; do
sleep 1
OPEN_WIN_ID=$(wmctrl -xl | grep -i "ksamu" | grep -i "открыть" | cut -d" " -f1)
if [[ -n $OPEN_WIN_ID ]] ; then
wmctrl -i -r $OPEN_WIN_ID -b add,above
fi
done
}
background_task &
WH_BG_PID=$!
export WH_BG_PID
' >> "$DRIVE_C/KSAMU/KSAMU.exe.whdb"

View File

@@ -6,10 +6,10 @@ export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="nalog" export WINEPREFIX="nalog"
export PROG_NAME="Налогоплательщик ЮЛ" export PROG_NAME="Налогоплательщик ЮЛ"
export PROG_ICON="npul" export PROG_ICON="npul"
export BASE_PFX="none" export BASE_PFX="defpfx_x86_v01"
export WINEARCH="win32" export WINEARCH="win32"
export INSTALL_DLL="msxml3 msxml4 msxml6 corefonts wsh57 vcrun6 jet40 gdiplus"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
try_get_page "https://data.nalog.ru/rn77/program/5961229/" try_get_page "https://data.nalog.ru/rn77/program/5961229/"
VER_MSI=$(read_page | grep -oP 'NalogUL\d+\.msi' | tail -1 | grep -oP '\d+') VER_MSI=$(read_page | grep -oP 'NalogUL\d+\.msi' | tail -1 | grep -oP '\d+')

View File

@@ -3,14 +3,15 @@
######################################################################## ########################################################################
export PROG_URL="https://www.nalog.gov.ru" export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64" export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="nalog" export WINEPREFIX="ppdgr2"
export PROG_NAME="ППДГР-2" export PROG_NAME="ППДГР-2"
export PROG_ICON="ppdgr" export PROG_ICON="ppdgr"
export BASE_PFX="none" export BASE_PFX="defpfx_dn48_x86_v01"
export WINEARCH="win32" export WINEARCH="win32"
export INSTALL_DLL="dotnet48 msxml3 msxml4 msxml6 corefonts lucida wsh57 vcrun6 jet40 gdiplus"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
var_winedlloverride_update "msxml4=b,wininet=b" export WH_USE_EXTRA_FONTS="1"
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48" var_winedlloverride_update "gdiplus,msxml3,wininet=b;msxml4=n"
try_get_page "https://www.nalog.gov.ru/rn77/program/5961277/" try_get_page "https://www.nalog.gov.ru/rn77/program/5961277/"
VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1) VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1)
@@ -24,4 +25,3 @@ if try_download "https://data.nalog.ru/files/ppdgr/${VER_MSI_SLASH}/SetupPPDGR2.
WIN_FILE_EXEC="$DRIVE_C/АО ГНИВЦ/ППДГР-2/PPDGR2.exe" WIN_FILE_EXEC="$DRIVE_C/АО ГНИВЦ/ППДГР-2/PPDGR2.exe"
create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON" create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON"
fi fi
https://data.nalog.ru/files/ppdgr/2.7.3/SetupPPDGR2.msi

View File

@@ -3,13 +3,14 @@
######################################################################## ########################################################################
export PROG_URL="https://www.nalog.gov.ru" export PROG_URL="https://www.nalog.gov.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64" export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="nalog" export WINEPREFIX="soun"
export PROG_NAME="СОУН" export PROG_NAME="СОУН"
export PROG_ICON="soun" export PROG_ICON="soun"
export BASE_PFX="none" export BASE_PFX="defpfx_x86_v01"
export WINEARCH="win32" export WINEARCH="win32"
export INSTALL_DLL=""
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48" export WH_USE_EXTRA_FONTS="1"
try_get_page "https://www.nalog.gov.ru/rn77/program/5961268/" try_get_page "https://www.nalog.gov.ru/rn77/program/5961268/"
VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1) VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1)

View File

@@ -6,10 +6,10 @@ export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="nalog" export WINEPREFIX="nalog"
export PROG_NAME="Тестер" export PROG_NAME="Тестер"
export PROG_ICON="tester" export PROG_ICON="tester"
export BASE_PFX="none" export BASE_PFX="defpfx_x86_v01"
export WINEARCH="win32" export WINEARCH="win32"
export INSTALL_DLL="msxml3 msxml4 msxml6 corefonts wsh57 vcrun6 jet40 gdiplus"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export INSTALL_DLL="corefonts micross tahoma lucida riched20 comctl32 msxml3 msxml4 msxml6 mdac28 wsh57 vcrun6 vb6run jet40 gdiplus vcrun2019 dotnet20sp2 dotnet40 dotnet48"
try_get_page "https://www.nalog.gov.ru/rn77/program/5961279/" try_get_page "https://www.nalog.gov.ru/rn77/program/5961279/"
VER_EXE_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | tail -n 1) VER_EXE_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | tail -n 1)

View File

@@ -40,7 +40,6 @@ else
WH_WINETRICKS="/usr/bin/winetricks" WH_WINETRICKS="/usr/bin/winetricks"
WH_DEVEL="1" WH_DEVEL="1"
# минимальная проверка синтаксиса скриптов # минимальная проверка синтаксиса скриптов
for self_check_script in "$RUN_SCRIPT" \ for self_check_script in "$RUN_SCRIPT" \
"$DATA_PATH/dependencies.sh" "$DATA_PATH/autoinstall"/* \ "$DATA_PATH/dependencies.sh" "$DATA_PATH/autoinstall"/* \
@@ -143,10 +142,14 @@ check_variables WH_WINE_USE "wine_x_tkg_10-0_amd64" # or system
check_variables WH_USE_CPCSP_PROXY "0" check_variables WH_USE_CPCSP_PROXY "0"
check_variables CPCSP_PROXY_X86_64_VER "0.6.1-alt1" check_variables CPCSP_PROXY_X86_64_VER "0.6.1-alt1"
check_variables CPCSP_PROXY_WOW64_VER "0.7.3-alt5-wow64" check_variables CPCSP_PROXY_WOW64_VER "0.7.7-alt1-wow64"
check_variables WH_USE_CPCSP_CADES "0"
check_variables WH_USE_EXTRA_FONTS "0" check_variables WH_USE_EXTRA_FONTS "0"
check_variables EXTRA_FONTS_VER "01" check_variables EXTRA_FONTS_VER "01"
check_variables WH_FONT_MSS_REPLACE "0"
check_variables WH_FONT_SMOOTHING "0"
# check_variables FREETYPE_PROPERTIES "truetype:interpreter-version=35"
check_variables STAGING_SHARED_MEMORY "1" check_variables STAGING_SHARED_MEMORY "1"
check_variables WINE_LARGE_ADDRESS_AWARE "1" check_variables WINE_LARGE_ADDRESS_AWARE "1"
@@ -162,6 +165,9 @@ check_variables WH_USE_SHADER_CACHE "1"
check_variables WH_USE_MESA_GL_OVERRIDE "0" check_variables WH_USE_MESA_GL_OVERRIDE "0"
check_variables WH_USE_WINE_DXGI "0" check_variables WH_USE_WINE_DXGI "0"
check_variables WH_DLL_INSTALL "" check_variables WH_DLL_INSTALL ""
check_variables WH_MAIN_DECORATED "default"
check_variables WH_MC_DECORATED "default"
check_variables WH_VIRTUAL_DESKTOP "default"
check_variables WINE_WIN_START "start /wait /high /unix" check_variables WINE_WIN_START "start /wait /high /unix"
@@ -202,17 +208,29 @@ su_run () {
} }
##### CHECK DEPENDENCIES ##### ##### CHECK DEPENDENCIES #####
# fonts-ttf-ms check_deps_i586 () {
if [[ $WH_USE_GUI != "1" ]] && [[ ! -t 0 ]] ; then
if ! rpm -q {i586-,}{wine,glibc-core,libstdc++6,glibc-pthread,glibc-nss,\ print_warning "Скрипт запущен из desktop файла."
libnss-mdns,libunixODBC2,ocl-icd,libfreetype,libfontconfig1,libgnutls30,libGL,\ return 0
libEGL,xorg-dri-swrast,xorg-dri-intel,xorg-dri-radeon,libvulkan1,libcups} 1>/dev/null
then
if su_run "$DATA_PATH/dependencies.sh"
then print_info "Зависимости успешно установлены. Продолжаем работу $SCRIPT_NAME"
else fatal "Не удалось установить зависимости. Работа $SCRIPT_NAME прервана."
fi fi
fi
if [[ $WH_SKIP_DEPS == "1" ]] ; then
unset WH_SKIP_DEPS
return 0
fi
if ! rpm -q i586-{wine,glibc-core,libstdc++6,glibc-pthread,glibc-nss,\
libnm,libnss,libnss-mdns,libnsl1,libunwind,libunixODBC2,ocl-icd,libfreetype,\
libcups,libfontconfig1,libgnutls30,libGL,libEGL,libvulkan1,xorg-dri-swrast,\
xorg-dri-intel,xorg-dri-radeon} 1>/dev/null
then
print_warning "Необходимо установить 32-битные зависимости!"
if su_run "$DATA_PATH/dependencies.sh"
then print_info "Зависимости успешно установлены. Продолжаем работу $SCRIPT_NAME"
else fatal "Не удалось установить зависимости. Работа $SCRIPT_NAME прервана."
fi
fi
}
##### HELPER FUNCTIONS ##### ##### HELPER FUNCTIONS #####
add_to_var () { add_to_var () {
@@ -460,7 +478,7 @@ try_copy_wine_dll_to_pfx_64 () {
fi fi
} }
try_copy_wine_dll_to_pfx_32() { try_copy_wine_dll_to_pfx_32 () {
if [[ -d "$WINEDIR/lib/wine/i386-windows" ]] ; then if [[ -d "$WINEDIR/lib/wine/i386-windows" ]] ; then
WINE_BUILD_DLL_32="$WINEDIR/lib/wine/i386-windows" WINE_BUILD_DLL_32="$WINEDIR/lib/wine/i386-windows"
elif [[ -d "$WINEDIR/lib64/wine/i386-windows" ]] ; then elif [[ -d "$WINEDIR/lib64/wine/i386-windows" ]] ; then
@@ -610,7 +628,7 @@ create_desktop () {
print_ok "Иконка успешно извлечена и сохранена: $icon_file" print_ok "Иконка успешно извлечена и сохранена: $icon_file"
else else
print_warning "Не удалось извлечь иконку из $exe_file. Используется иконка по умолчанию." print_warning "Не удалось извлечь иконку из $exe_file. Используется иконка по умолчанию."
icon_file="wine" # Запасной вариант icon_file="$WH_IMAGE_PATH/wh_default.png" # Запасной вариант
fi fi
try_remove_dir "$tmp_ico_dir" try_remove_dir "$tmp_ico_dir"
fi fi
@@ -620,7 +638,7 @@ create_desktop () {
# Случай 4: Запасной вариант по умолчанию # Случай 4: Запасной вариант по умолчанию
else else
print_info "Иконка '$icon_arg' не найдена. Используется иконка по умолчанию." print_info "Иконка '$icon_arg' не найдена. Используется иконка по умолчанию."
icon_file="wine" icon_file="$WH_IMAGE_PATH/wh_default.png"
fi fi
# --- Конец логики обработки иконки --- # --- Конец логики обработки иконки ---
@@ -714,8 +732,10 @@ EOF
} > "$exe_file".whdb } > "$exe_file".whdb
grep -e "info_" -e "#####" -e "PROG_URL=" -e "WINEPREFIX=" -e "INSTALL_DLL=" \ grep -e "info_" -e "#####" -e "PROG_URL=" -e "WINEPREFIX=" -e "INSTALL_DLL=" \
-e "PROG_NAME=" -e "PROG_ICON=" -e "var_" "$INSTALL_SCRIPT" \ -e "PROG_NAME=" -e "PROG_ICON=" -e "var_" -e "WH_MAIN_DECORATED" \
| awk '{$1=$1;print}' >> "$exe_file".whdb -e "WH_VIRTUAL_DESKTOP" -e "WINE_TOP_WINDOW" -e "WH_FONT_SMOOTHING "\
-e "WH_FONT_MSS_REPLACE" \
"$INSTALL_SCRIPT" | awk '{$1=$1;print}' >> "$exe_file".whdb
print_info "Создан файл настроек для $exe_file" print_info "Создан файл настроек для $exe_file"
fi fi
@@ -773,13 +793,6 @@ check_installed_programs () {
[[ -n $2 ]] && fatal "Не найден файл запуска для $2" [[ -n $2 ]] && fatal "Не найден файл запуска для $2"
} }
run_installed_programs () {
if check_installed_programs check_only "$1" ; then
/usr/bin/env bash -c "\"$RUN_SCRIPT\" \"$EXE_PATH\"" &
exit 0
fi
}
copy_wined3d () { copy_wined3d () {
for wined3dfiles in $1 ; do for wined3dfiles in $1 ; do
try_copy_wine_dll_to_pfx_64 "$wined3dfiles.dll" try_copy_wine_dll_to_pfx_64 "$wined3dfiles.dll"
@@ -871,19 +884,26 @@ init_wine_ver () {
try_download cloud "$download_url" "$wine_package" "check256sum" try_download cloud "$download_url" "$wine_package" "check256sum"
unpack "$wine_package" "$WH_DIST_DIR/" unpack "$wine_package" "$WH_DIST_DIR/"
try_remove_file "$wine_package" try_remove_file "$wine_package"
# Управление структурой подкаталога Proton "files", перемещая содержимое вверх
if [[ -d "$WINEDIR/files" ]]; then
print_info "Обнаружена структура каталогов Proton, исправляем пути..."
mv "$WINEDIR"/files/* "$WINEDIR/"
rmdir "$WINEDIR/files"
fi
fi fi
[[ ! -f "$WINEDIR/version" ]] && echo "$WH_WINE_USE" > "$WINEDIR/version" # Управление структурой подкаталога Proton "files", перемещая содержимое вверх
if [[ $WH_WINE_USE =~ wow64 ]] if [[ ${WINEDIR,,} =~ proton ]] \
then export WH_WINE_WOW64="1" && [[ -d "$WINEDIR/files" ]]
else export WH_WINE_WOW64="0" then
print_info "Обнаружена структура каталогов Proton, исправляем пути..."
mv "$WINEDIR"/files/* "$WINEDIR/"
try_remove_dir "$WINEDIR/files"
fi
if [[ ! -f "$WINEDIR/version" ]] ; then
echo "$WH_WINE_USE" > "$WINEDIR/version"
fi
if [[ $WH_WINE_USE =~ wow64 ]] ; then
export WH_WINE_WOW64="1"
else
export WH_WINE_WOW64="0"
check_deps_i586
fi fi
export WINE="$WINEDIR/bin/wine" export WINE="$WINEDIR/bin/wine"
@@ -1139,29 +1159,66 @@ init_wineprefix () {
export DRIVE_C="$WINEPREFIX/drive_c" export DRIVE_C="$WINEPREFIX/drive_c"
export XUSER_PATH="$DRIVE_C/users/xuser" export XUSER_PATH="$DRIVE_C/users/xuser"
if [[ -d "$XUSER_PATH" ]] \ if [[ ! -d "$WINEPREFIX" ]] ; then
&& [[ ! -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$XUSER_PATH" "$DRIVE_C/users/$USER"
fi
if [[ ! -f "$WINEPREFIX/.firstboot" ]] ; then
create_new_dir "$WINEPREFIX" create_new_dir "$WINEPREFIX"
if [[ "$CLEAR_PREFIX" == "1" ]] if [[ "$CLEAR_PREFIX" == "1" ]]
then print_warning "Используется переменная \"CLEAR_PREFIX=1\", которая принудительно создает чистый префикс с установкой компонентов с помощью winetricks." then print_warning "Используется переменная \"CLEAR_PREFIX=1\", которая принудительно создает чистый префикс с установкой компонентов с помощью winetricks."
elif [[ "$BASE_PFX" != "none" ]] elif [[ "$BASE_PFX" != "none" ]]
then get_base_pfx "$BASE_PFX" then get_base_pfx "$BASE_PFX"
fi fi
fi
if [[ ! -d "$WINEPREFIX/drive_c/windows" ]] ; then
print_info "Создание префикса $WINEPREFIX."
"$WINELOADER" wineboot -i
wait_wineserver
elif [[ ! -f "$WINEPREFIX/.update-timestamp" ]] \
|| [[ ! -d "$WINEPREFIX/drive_c/users" ]]
then
print_info "Обновление префикса $WINEPREFIX." print_info "Обновление префикса $WINEPREFIX."
if [[ -d "$WINEPREFIX/drive_c/windows" ]] "$WINELOADER" wineboot -u
then "$WINELOADER" wineboot -u
else "$WINELOADER" wineboot -i
fi
touch "$WINEPREFIX/.firstboot"
wait_wineserver wait_wineserver
fi fi
if [[ -d "$XUSER_PATH" ]] && [[ ! -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$XUSER_PATH" "$DRIVE_C/users/$USER"
elif [[ ! -d "$XUSER_PATH" ]] && [[ -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$DRIVE_C/users/$USER" "$XUSER_PATH"
fi
if [[ -L "$XUSER_PATH/Desktop" ]]
then rm -f "$XUSER_PATH/Desktop"
fi
create_new_dir "$XUSER_PATH/Desktop"
create_new_dir "$XUSER_PATH/AppData/Local/Temp"
create_new_dir "$DRIVE_C/ProgramData/Package Cache"
create_new_dir "$DRIVE_C/windows/temp"
create_new_dir "$DRIVE_C/windows/Installer"
if [[ ! -d "$WINEPREFIX/dosdevices" ]] ; then
create_new_dir "$WINEPREFIX/dosdevices"
local run_wbr="1"
fi
if [[ ! -d "${WINEPREFIX}/dosdevices/c:" ]] ; then
try_force_link_dir "${WINEPREFIX}/drive_c/" "${WINEPREFIX}/dosdevices/c:"
fi
if [[ ! -d "${WINEPREFIX}/dosdevices/z:" ]] ; then
try_force_link_dir "/" "${WINEPREFIX}/dosdevices/z:"
fi
if [[ ! -d "${WINEPREFIX}/dosdevices/h:" ]] ; then
try_force_link_dir "$HOME" "${WINEPREFIX}/dosdevices/h:"
fi
if [[ $run_wbr == "1" ]] ; then
"$WINELOADER" wineboot -r
wait_wineserver
unset run_wbr
fi
if [[ -f "$WINEPREFIX/system.reg" ]] \ if [[ -f "$WINEPREFIX/system.reg" ]] \
&& [[ -z $(grep "Windows $WH_WINDOWS_VER" "$WINEPREFIX/system.reg") ]] && ! grep -iq "Microsoft Windows $WH_WINDOWS_VER" "$WINEPREFIX/system.reg"
then then
if [[ $(echo "$WH_WINDOWS_VER" | sed 's/.*/\L&/') == "xp" ]] \ if [[ $(echo "$WH_WINDOWS_VER" | sed 's/.*/\L&/') == "xp" ]] \
&& [[ "$WINEARCH" != "win32" ]] && [[ "$WINEARCH" != "win32" ]]
@@ -1172,33 +1229,11 @@ init_wineprefix () {
print_info "Windows версия изменена на win${WH_WINDOWS_VER}" print_info "Windows версия изменена на win${WH_WINDOWS_VER}"
fi fi
if [[ -d "$XUSER_PATH" ]] && [[ ! -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$XUSER_PATH" "$DRIVE_C/users/$USER"
elif [[ ! -d "$XUSER_PATH" ]] && [[ -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$DRIVE_C/users/$USER" "$XUSER_PATH"
fi
if [[ ! -f "$WINEPREFIX/.update-timestamp" ]] ; then
print_info "Обновление префикса $WINEPREFIX."
"$WINELOADER" wineboot -u
wait_wineserver
fi
if [[ -L "$XUSER_PATH/Desktop" ]]
then rm -f "$XUSER_PATH/Desktop"
fi
create_new_dir "$XUSER_PATH/Desktop"
if [[ ! -L "$WINEPREFIX/dosdevices/h:" ]]
then try_force_link_dir "$HOME" "$WINEPREFIX/dosdevices/h:"
fi
if [[ $WH_USE_MESA_GL_OVERRIDE == "1" ]] \ if [[ $WH_USE_MESA_GL_OVERRIDE == "1" ]] \
&& ! lspci | grep -i nvidia > /dev/null && ! lspci | grep -i nvidia > /dev/null
then then
export MESA_GL_VERSION_OVERRIDE="3.3" export MESA_GL_VERSION_OVERRIDE="3.3"
export MESA_GLSL_VERSION_OVERRIDE="330" export MESA_GLSL_VERSION_OVERRIDE="330"
fi fi
if check_wayland_session ; then if check_wayland_session ; then
@@ -1211,13 +1246,6 @@ init_wineprefix () {
unset WINE_WAYLAND_HACKS unset WINE_WAYLAND_HACKS
get_and_set_reg_file --delete 'Software\Wine\Drivers' 'Graphics' get_and_set_reg_file --delete 'Software\Wine\Drivers' 'Graphics'
fi fi
# исправляем некорректное отображение выпадающих окон под wayland
if [[ $DXVK_VER == "none" ]] \
|| [[ $VKD3D_VER == "none" ]]
then
check_variables WINE_D3D_CONFIG "renderer=vulkan"
fi
fi fi
# хак для XRDP сессии # хак для XRDP сессии
@@ -1230,20 +1258,49 @@ init_wineprefix () {
get_and_set_reg_file --delete 'Software\Wine\X11 Driver' 'UseXVidMode' get_and_set_reg_file --delete 'Software\Wine\X11 Driver' 'UseXVidMode'
fi fi
# отключаем декоратор для maincontroller.exe # включаем виртуальный рабочий стол при необходимости
# заменяет патч: https://git.altlinux.org/gears/w/wine.git?p=wine.git;a=blob;f=patches/0009-wine.inf.in-disable-decorated-window-for-maincontrol.patch;h=887a5e90e130cddeefdead831ef7a78a32588f11;hb=d097f4e4b64873c82ec31542c6f49f70829ab2b4 if [[ $WH_VIRTUAL_DESKTOP == "1" ]] ; then
get_and_set_reg_file --add 'Software\Wine\AppDefaults\maincontroller.exe\X11 Driver' 'Decorated' 'REG_SZ' "N" "user" get_and_set_reg_file --add 'Software\Wine\Explorer' 'Desktop' 'REG_SZ' "Default" "user"
WH_SCREEN_RESOLUTION="$(xrandr | sed -rn 's/^.*primary.* ([0-9]+x[0-9]+).*$/\1/p')"
[[ $WH_SCREEN_RESOLUTION != *x* ]] && WH_SCREEN_RESOLUTION="1920x1080"
get_and_set_reg_file --add 'Software\Wine\Explorer\Desktops' 'Default' 'REG_SZ' "$WH_SCREEN_RESOLUTION" "user"
elif [[ $WH_VIRTUAL_DESKTOP == *x* ]] ; then
get_and_set_reg_file --add 'Software\Wine\Explorer' 'Desktop' 'REG_SZ' "Default" "user"
get_and_set_reg_file --add 'Software\Wine\Explorer\Desktops' 'Default' 'REG_SZ' "$WH_VIRTUAL_DESKTOP" "user"
elif [[ $WH_VIRTUAL_DESKTOP == "0" ]] ; then
get_and_set_reg_file --delete 'Software\Wine\Explorer\Desktops' 'Default'
get_and_set_reg_file --delete 'Software\Wine\Explorer' 'Desktop'
fi
# управляем декоратором для ПО по умолчанию
if [[ $WH_MAIN_DECORATED = "0" ]] ; then
get_and_set_reg_file --add 'Software\Wine\X11 Driver' 'Decorated' 'REG_SZ' "N" "user"
elif [[ $WH_MAIN_DECORATED = "1" ]] ; then
get_and_set_reg_file --add 'Software\Wine\X11 Driver' 'Decorated' 'REG_SZ' "Y" "user"
fi
# управляем декоратором для maincontroller.exe
if [[ $WH_MC_DECORATED = "0" ]] ; then
# заменяет патч: https://git.altlinux.org/gears/w/wine.git?p=wine.git;a=blob;f=patches/0009-wine.inf.in-disable-decorated-window-for-maincontrol.patch;h=887a5e90e130cddeefdead831ef7a78a32588f11;hb=d097f4e4b64873c82ec31542c6f49f70829ab2b4
get_and_set_reg_file --add 'Software\Wine\AppDefaults\maincontroller.exe\X11 Driver' 'Decorated' 'REG_SZ' "N" "user"
elif [[ $WH_MC_DECORATED = "1" ]] ; then
get_and_set_reg_file --add 'Software\Wine\AppDefaults\maincontroller.exe\X11 Driver' 'Decorated' 'REG_SZ' "Y" "user"
fi
# заменям шрифт Microsoft Sans Serif на Tahoma # заменям шрифт Microsoft Sans Serif на Tahoma
# заменяет патч: https://git.altlinux.org/gears/w/wine.git?p=wine.git;a=blob;f=patches/0003-wine.inf-Add-the-font-replacement-for-Microsoft-Sans.patch;h=26b8ae2192d94a2b8ddd8565b90b62a2c2b0ed52;hb=d097f4e4b64873c82ec31542c6f49f70829ab2b4 if [[ $WH_FONT_MSS_REPLACE = "1" ]] ; then
get_and_set_reg_file --add 'Software\Wine\Fonts\Replacements' 'Microsoft Sans Serif' 'REG_SZ' "Tahoma" "user" # заменяет патч: https://git.altlinux.org/gears/w/wine.git?p=wine.git;a=blob;f=patches/0003-wine.inf-Add-the-font-replacement-for-Microsoft-Sans.patch;h=26b8ae2192d94a2b8ddd8565b90b62a2c2b0ed52;hb=d097f4e4b64873c82ec31542c6f49f70829ab2b4
get_and_set_reg_file --add 'Software\Wine\Fonts\Replacements' 'Microsoft Sans Serif' 'REG_SZ' "Tahoma" "user"
fi
# добавляем сглаживание шрифтов # добавляем сглаживание шрифтов
# заменяет патч: https://git.altlinux.org/gears/w/wine.git?p=wine.git;a=blob;f=patches/0002-Add-font-smoothing.patch;h=d7c252899499e9ee0e1a93f7c02548cc79025358;hb=d097f4e4b64873c82ec31542c6f49f70829ab2b4 if [[ $WH_FONT_SMOOTHING = "1" ]] ; then
get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothing' 'REG_SZ' "2" "user" # заменяет патч: https://git.altlinux.org/gears/w/wine.git?p=wine.git;a=blob;f=patches/0002-Add-font-smoothing.patch;h=d7c252899499e9ee0e1a93f7c02548cc79025358;hb=d097f4e4b64873c82ec31542c6f49f70829ab2b4
get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothingGamma' 'REG_DWORD' "0x00000578" "user" get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothing' 'REG_SZ' "2" "user"
get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothingOrientation' 'REG_DWORD' "0x00000001" "user" get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothingGamma' 'REG_DWORD' "0x00000578" "user"
get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothingType' 'REG_DWORD' "0x00000002" "user" get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothingOrientation' 'REG_DWORD' "0x00000001" "user"
get_and_set_reg_file --add 'Control Panel\Desktop' 'FontSmoothingType' 'REG_DWORD' "0x00000002" "user"
fi
# добавление ассоциаций файлов для запуска нативного приложения из wine # добавление ассоциаций файлов для запуска нативного приложения из wine
# пример переменной: WH_XDG_OPEN="txt doc pdf" # пример переменной: WH_XDG_OPEN="txt doc pdf"
@@ -1292,24 +1349,26 @@ init_wineprefix () {
# настраиваем префикс для работы с cpcsp_proxy # настраиваем префикс для работы с cpcsp_proxy
if [[ $WH_USE_CPCSP_PROXY == "1" ]] ; then if [[ $WH_USE_CPCSP_PROXY == "1" ]] ; then
local cades_ver="release_2_0_14892" if [[ $WH_USE_CPCSP_CADES == "1" ]] ; then
local url_cades_dll="https://cryptopro.ru/sites/default/files/products/cades/$cades_ver" local cades_ver="release_2_0_14892"
local url_cades_dll="https://cryptopro.ru/sites/default/files/products/cades/$cades_ver"
if [[ ! -d "$DRIVE_C/Program Files (x86)/Common Files/Crypto Pro/Shared/" ]] if [[ ! -d "$DRIVE_C/Program Files (x86)/Common Files/Crypto Pro/Shared/" ]]
then then
local msi_cades32="cades-win32.msi" local msi_cades32="cades-win32.msi"
try_download cloud "$url_cades_dll/$msi_cades32" "$WH_TMP_DIR/$msi_cades32" try_download cloud "$url_cades_dll/$msi_cades32" "$WH_TMP_DIR/$msi_cades32"
print_info "Установка КриптоПро ЭЦП Runtime ($msi_cades32)" print_info "Установка КриптоПро ЭЦП Runtime ($msi_cades32)"
WINEDLLOVERRIDES="msxml3=b" wine_run "$WH_TMP_DIR/$msi_cades32" /q WINEDLLOVERRIDES="msxml3=b" wine_run "$WH_TMP_DIR/$msi_cades32" /q
fi fi
if [[ "$WINEARCH" == "win64" ]] \ if [[ "$WINEARCH" == "win64" ]] \
&& [[ ! -d "$DRIVE_C/Program Files/Common Files/Crypto Pro/Shared" ]] && [[ ! -d "$DRIVE_C/Program Files/Common Files/Crypto Pro/Shared" ]]
then then
local msi_cades64="cades-x64.msi" local msi_cades64="cades-x64.msi"
try_download cloud "$url_cades_dll/$msi_cades64" "$WH_TMP_DIR/$msi_cades64" try_download cloud "$url_cades_dll/$msi_cades64" "$WH_TMP_DIR/$msi_cades64"
print_info "Установка КриптоПро ЭЦП Runtime ($msi_cades64)" print_info "Установка КриптоПро ЭЦП Runtime ($msi_cades64)"
WINEDLLOVERRIDES="msxml3=b" wine_run "$WH_TMP_DIR/$msi_cades64" /q WINEDLLOVERRIDES="msxml3=b" wine_run "$WH_TMP_DIR/$msi_cades64" /q
fi
fi fi
if ! grep -q "cpcsp_proxy.dll" "$WINEPREFIX/system.reg" ; then if ! grep -q "cpcsp_proxy.dll" "$WINEPREFIX/system.reg" ; then
@@ -1320,11 +1379,15 @@ init_wineprefix () {
try_copy_wine_dll_to_pfx_32 "cpcsp_proxy.dll" try_copy_wine_dll_to_pfx_32 "cpcsp_proxy.dll"
if [[ $WH_WINE_WOW64 == "1" ]] ; then if [[ $WH_WINE_WOW64 == "1" ]] ; then
print_info "Запускаем регистрацию 64-битного cpcsp_proxy.dll..."
env WINEDEBUG="fixme-all" "$WINE" "C:\\windows\\system32\\regsvr32.exe" \ env WINEDEBUG="fixme-all" "$WINE" "C:\\windows\\system32\\regsvr32.exe" \
/s /n /i cpcsp_proxy.dll 2>&1 | tee "$WINEPREFIX/cpcsp_setup.log" /s /n /i cpcsp_proxy.dll 2>&1 | tee "$WINEPREFIX/cpcsp_setup.log"
wait_wineserver
print_info "Запускаем регистрацию 32-битного cpcsp_proxy.dll..."
env WINEDEBUG="fixme-all" "$WINE" "C:\\windows\\syswow64\\regsvr32.exe" \ env WINEDEBUG="fixme-all" "$WINE" "C:\\windows\\syswow64\\regsvr32.exe" \
/s /n /i cpcsp_proxy.dll 2>&1 | tee -a "$WINEPREFIX/cpcsp_setup.log" /s /n /i cpcsp_proxy.dll 2>&1 | tee -a "$WINEPREFIX/cpcsp_setup.log"
wait_wineserver
else else
try_copy_wine_dll_to_pfx_64 "cpcsp_proxy_setup.exe" try_copy_wine_dll_to_pfx_64 "cpcsp_proxy_setup.exe"
try_copy_wine_dll_to_pfx_32 "cpcsp_proxy_setup.exe" try_copy_wine_dll_to_pfx_32 "cpcsp_proxy_setup.exe"
@@ -1350,7 +1413,6 @@ init_wineprefix () {
fi fi
try_remove_file "$WINEPREFIX/cpcsp_setup.log" try_remove_file "$WINEPREFIX/cpcsp_setup.log"
wait_wineserver
if [[ $CPCSP_PROXY_OK == "1" ]] if [[ $CPCSP_PROXY_OK == "1" ]]
then print_info "Настройка cpcsp_proxy успешно завершена." then print_info "Настройка cpcsp_proxy успешно завершена."
else fatal "Ошибка во время настройки cpcsp_proxy." else fatal "Ошибка во время настройки cpcsp_proxy."
@@ -1378,7 +1440,7 @@ init_wineprefix () {
for var in WH_WINE_USE BASE_PFX WINEARCH WH_WINDOWS_VER WINEESYNC WINEFSYNC \ 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 \ 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_MESA_GL_OVERRIDE \ WINE_CPU_TOPOLOGY DXVK_VER VKD3D_VER WH_XDG_OPEN WH_USE_MESA_GL_OVERRIDE \
WH_USE_CPCSP_PROXY WH_USE_CPCSP_PROXY WH_USE_EXTRA_FONTS
do do
echo "export $var=\"${!var}\"" >> "$WINEPREFIX/last.conf" echo "export $var=\"${!var}\"" >> "$WINEPREFIX/last.conf"
done done
@@ -1474,6 +1536,11 @@ prepair_wine () {
fi fi
init_wine_ver init_wine_ver
# отключаем создание .desktop файлов средствами wine
# и отключаем winebth, так как может сломать winedevice.exe
var_winedlloverride_update "winemenubuilder.exe,winebth.sys=d"
init_wineprefix init_wineprefix
use_winetricks use_winetricks
init_dxvk "$DXVK_VER" init_dxvk "$DXVK_VER"
@@ -1538,13 +1605,17 @@ wine_run () {
create_new_dir "$log_dir" create_new_dir "$log_dir"
date > "$log_file" date > "$log_file"
echo -e "\n##### Версия установленного WineHelper #####" | tee -a "$log_file"
rpm -q winehelper | tee -a "$log_file"
print_warning "Включен режим логирования работы WINE." print_warning "Включен режим логирования работы WINE."
print_warning "Лог будет сохранен по пути: $log_file" print_warning "Лог будет сохранен по пути: $log_file"
echo "##### Основные переменные #####" | tee -a "$log_file" echo -e "\n##### Основные переменные #####" | tee -a "$log_file"
env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" | tee -a "$log_file" env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" -e "LD_" \
echo "##### Лог WINE #####" | tee -a "$log_file" | grep -v "ICON" | sort | tee -a "$log_file"
echo -e "\n##### Лог WINE #####" | tee -a "$log_file"
$MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$log_file" $MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$log_file"
else else
$MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS $MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS
@@ -1694,14 +1765,16 @@ select_wine_version() {
local total_versions_found=0 local total_versions_found=0
# --- System --- # --- System ---
local system_wine_display_name="system" # Добавляем системную версию только для 64-битного префикса
if command -v wine &>/dev/null; then if [[ "$WINEARCH" == "win64" ]]; then
local system_wine_version local system_wine_display_name="system"
system_wine_version=$(wine --version 2>/dev/null) if command -v wine &>/dev/null; then
[[ -n "$system_wine_version" ]] && system_wine_display_name="$system_wine_version" local system_wine_version
system_wine_version=$(wine --version 2>/dev/null)
[[ -n "$system_wine_version" ]] && system_wine_display_name="$system_wine_version"
fi
options+=("--- SYSTEM ---" "$system_wine_display_name")
fi fi
options+=("--- System ---")
options+=("$system_wine_display_name")
# --- Other versions from sha256sum.list --- # --- Other versions from sha256sum.list ---
local current_group="" local current_group=""
@@ -1718,14 +1791,28 @@ select_wine_version() {
} }
while IFS= read -r line; do while IFS= read -r line; do
if [[ "$line" =~ ^#+[[:space:]]([^#[:space:]]+)[[:space:]]#* ]]; then if [[ "$line" =~ ^#+[[:space:]](.*[^#[:space:]])[[:space:]]#* ]] ; then
flush_group flush_group
current_group="${BASH_REMATCH[1]}" current_group="${BASH_REMATCH[1]}"
# Отображаем только группы, которые являются сборками WINE или PROTON # Отображаем только группы, которые являются сборками WINE или PROTON
case "$current_group" in case "$current_group" in
WINE|WINE_LG|PROTON_LG|PROTON_STEAM) "WINE WOW64"|"WINE AMD64"|"WINE I586")
local pretty_key=$(echo "$current_group" | tr '_' ' ' | sed -e "s/\b\(.\)/\u\1/g") # Фильтрация групп в зависимости от архитектуры префикса
options+=("--- $pretty_key ---") if [[ "$WINEARCH" == "win64" ]]; then
# Для 64-битного префикса скрываем группу I586
if [[ "$current_group" != "WINE I586" ]]; then
local pretty_key="$current_group"
options+=("--- $pretty_key ---")
else
current_group="" # Игнорируем группу I586
fi
elif [[ "$WINEARCH" == "win32" ]]; then
# Для 32-битного префикса скрываем только группу WOW64
if [[ "$current_group" != "WINE WOW64" ]]; then
local pretty_key="$current_group"
options+=("--- $pretty_key ---")
fi
fi
;; ;;
*) *)
current_group="" current_group=""
@@ -1736,11 +1823,14 @@ select_wine_version() {
local version_name=${filename%.tar.xz} local version_name=${filename%.tar.xz}
if [[ "$WINEARCH" == "win64" ]]; then if [[ "$WINEARCH" == "win64" ]]; then
if [[ "$version_name" =~ (amd64|x86_64|wow64) ]] || ! [[ "$version_name" =~ i[3-6]86 ]]; then # Для 64-битного префикса показываем только 64-битные версии
if ! [[ "$version_name" =~ i[3-6]86 ]]; then
group_versions+=("$version_name") group_versions+=("$version_name")
fi fi
else # win32 else # Для 32-битного префикса показываем и i586, и amd64
group_versions+=("$version_name") if [[ "$version_name" =~ (i[3-6]86|amd64) ]]; then
group_versions+=("$version_name")
fi
fi fi
fi fi
done < "$sha256_file" done < "$sha256_file"
@@ -1824,13 +1914,7 @@ select_wine_version() {
print_info "Операция отменена." print_info "Операция отменена."
return 1 return 1
fi fi
local selected_opt export WH_WINE_USE="${selectable_options[$user_choice]}"
selected_opt="${selectable_options[$user_choice]}"
if [[ "$selected_opt" == "$system_wine_display_name" ]]; then
export WH_WINE_USE="system"
else
export WH_WINE_USE="$selected_opt"
fi
break break
else else
print_error "Неверный выбор. Введите число от 0 до $max_choice." print_error "Неверный выбор. Введите число от 0 до $max_choice."
@@ -1839,6 +1923,67 @@ select_wine_version() {
return 0 return 0
} }
select_prepared_prefix() {
local arch="$1"
local sha256_file="$DATA_PATH/sha256sum.list"
[[ ! -f "$sha256_file" ]] && fatal "Файл с описаниями префиксов не найден: $sha256_file"
options=()
descriptions=()
options+=("none")
descriptions+=("Создать чистый префикс без дополнительных библиотек")
local in_prefix_section=false
local current_description=""
local current_prefix_name=""
while IFS= read -r line; do
if [[ "$line" =~ ^#####[[:space:]]PREFIX[[:space:]]#####$ ]] ; then
in_prefix_section=true
continue
elif [[ "$line" =~ ^#####.* ]] ; then
in_prefix_section=false
fi
if [[ "$in_prefix_section" == true ]] ; then
if [[ "$line" =~ ^[a-f0-9]{64} ]] ; then
# Если у нас есть имя предыдущего префикса, добавляем его описание
if [[ -n "$current_prefix_name" ]] ; then
descriptions+=("$(echo -e "${current_description}" | sed 's/\\n$//')")
fi
current_description=""
local filename
filename=$(echo "$line" | awk '{print $2}')
current_prefix_name=${filename%.tar.xz}
if [[ "$arch" == "win32" ]] && ([[ "$current_prefix_name" == *"_x86_"* ]] || [[ "$current_prefix_name" == *"_i586_"* ]]) ; then
options+=("$current_prefix_name")
elif [[ "$arch" == "win64" ]] && ([[ "$current_prefix_name" == *"_x64_"* ]] || [[ "$current_prefix_name" == *"_amd64_"* ]]) ; then
options+=("$current_prefix_name")
else
# Если архитектура не совпадает, сбрасываем имя, чтобы не добавлять описание
current_prefix_name=""
fi
elif [[ "$line" =~ ^#[[:space:]] ]] ; then
local comment_line=${line:2} # Удаляем '# '
current_description+="$comment_line\n"
fi
fi
done < "$sha256_file"
# Добавляем описание для самого последнего префикса в файле
if [[ -n "$current_prefix_name" ]] ; then
descriptions+=("$(echo -e "${current_description}" | sed 's/\\n$//')")
fi
echo
print_info "Выберите тип создаваемого префикса:"
for i in "${!options[@]}" ; do
printf "\n\E[36m %s) %s \e[0m\n" "$((i+1))" "${options[$i]}"
[[ -n "${descriptions[$i]}" ]] && printf " \E[33m%s\e[0m\n" "$(echo -e "${descriptions[$i]}" | sed 's/^/ /g')"
done
}
create_prefix() { create_prefix() {
print_info "Существующие префиксы:" print_info "Существующие префиксы:"
local prefixes=() local prefixes=()
@@ -1888,19 +2033,22 @@ create_prefix() {
select_wine_version || exit 0 select_wine_version || exit 0
print_info "Выберите тип создаваемого префикса:" select_prepared_prefix "$WINEARCH"
echo " 0) Отмена создания префикса" local max_choice=${#options[@]}
echo " 1) Чистый префикс (без библиотек)" local user_choice
echo " 2) С рекомендуемыми библиотеками" while true; do
echo read -p "Ваш выбор [1-$max_choice] (0 для отмены): " user_choice
local pfx_type_choice if [[ "$user_choice" == "0" ]]; then
read -p "Ваш выбор [0-2] (по умолчанию 1): " pfx_type_choice print_info "Создание префикса отменено." ; exit 0
case "${pfx_type_choice:-1}" in elif [[ "$user_choice" -ge 1 && "$user_choice" -le "$max_choice" ]]; then
0) print_info "Создание префикса отменено." ; exit 0 ;; export BASE_PFX="${options[$((user_choice-1))]}"
1) export BASE_PFX="none" ;; break
2) ;; # Оставляем BASE_PFX пустым, чтобы init_wineprefix использовал значение по умолчанию else
*) fatal "Неверный выбор. Операция отменена." ;; print_error "Неверный выбор. Введите число от 1 до $max_choice."
esac fi
done
print_license_agreement || exit 0
export WINEPREFIX="$WH_PREFIXES_DIR/$prefix_name" export WINEPREFIX="$WH_PREFIXES_DIR/$prefix_name"
@@ -1992,8 +2140,6 @@ create_base_pfx () {
fi fi
# удаляем всё ненужное для переноса префикса # удаляем всё ненужное для переноса префикса
try_remove_file "$prefix_dir/.update-timestamp"
try_remove_file "$prefix_dir/.firstboot"
try_remove_file "$prefix_dir/last.conf" try_remove_file "$prefix_dir/last.conf"
try_remove_dir "$prefix_dir/dosdevices/" try_remove_dir "$prefix_dir/dosdevices/"
try_remove_dir "$users_dir/$USER" try_remove_dir "$users_dir/$USER"
@@ -2010,7 +2156,7 @@ create_base_pfx () {
cd "$prefix_dir" cd "$prefix_dir"
# запускаем сжатие префикса # запускаем сжатие префикса
if tar --no-xattrs -c -I 'xz --memlimit=8000MiB -9 -T0' -f "$archive_path" ./* ; then if tar --no-xattrs -c -I 'xz --memlimit=8000MiB -9 -T0' -f "$archive_path" . ; then
print_ok "Архив создан по пути: $archive_path" print_ok "Архив создан по пути: $archive_path"
xdg-open "$(dirname "$archive_path")" & xdg-open "$(dirname "$archive_path")" &
cd - cd -
@@ -2042,7 +2188,6 @@ backup_prefix() {
print_info "Подготовка префикса к упаковке..." print_info "Подготовка префикса к упаковке..."
if cp -a "$WINEPREFIX" "$temp_prefix_dir" ; then if cp -a "$WINEPREFIX" "$temp_prefix_dir" ; then
try_remove_dir "$temp_prefix_dir/dosdevices" try_remove_dir "$temp_prefix_dir/dosdevices"
try_remove_file "$temp_prefix_dir/.update-timestamp"
if [[ -d "$temp_users_dir/$USER" ]] \ if [[ -d "$temp_users_dir/$USER" ]] \
&& [[ ! -L "$temp_users_dir/$USER" ]] && [[ ! -L "$temp_users_dir/$USER" ]]
then then
@@ -2097,7 +2242,6 @@ restore_prefix() {
local backup_archive_path="$1" local backup_archive_path="$1"
local temp_extract_dir prefix_name local temp_extract_dir prefix_name
if [[ -z "$backup_archive_path" ]] ; then if [[ -z "$backup_archive_path" ]] ; then
read -e -p "Укажите путь к архиву резервной копии (/путь/к/архиву.whpack): " backup_archive_path read -e -p "Укажите путь к архиву резервной копии (/путь/к/архиву.whpack): " backup_archive_path
backup_archive_path=$(echo "$backup_archive_path" | sed "s/'//g; s/\"//g") backup_archive_path=$(echo "$backup_archive_path" | sed "s/'//g; s/\"//g")
@@ -2168,6 +2312,15 @@ restore_prefix() {
else else
print_ok "Префикс $prefix_name восстановлен." print_ok "Префикс $prefix_name восстановлен."
export WINEPREFIX="$WH_PREFIXES_DIR/$prefix_name"
if [[ -f "$WINEPREFIX/last.conf" ]] ; then
source "$WINEPREFIX/last.conf"
prepair_wine
if [[ -f "$WINEPREFIX/restore_pfx.sh" ]] ; then
source "$WINEPREFIX/restore_pfx.sh"
fi
fi
print_info "Восстановление ярлыков для префикса $prefix_name..." print_info "Восстановление ярлыков для префикса $prefix_name..."
export RESTORE_FROM_BACKUP="1" # Устанавливаем флаг восстановления export RESTORE_FROM_BACKUP="1" # Устанавливаем флаг восстановления
while IFS='=' read -r name_desktop exe_path icon_name ; do while IFS='=' read -r name_desktop exe_path icon_name ; do
@@ -2466,10 +2619,6 @@ else
arg1="--help" arg1="--help"
fi fi
# отключаем создание .desktop файлов средствами wine
# и отключаем winebth, так как может сломать winedevice.exe
var_winedlloverride_update "winemenubuilder.exe,winebth.sys=d"
case "$arg1" in case "$arg1" in
--version|version) rpm -qi "$SCRIPT_NAME" ; exit 0 ;; --version|version) rpm -qi "$SCRIPT_NAME" ; exit 0 ;;
--help|help) wh_info ; exit 0 ;; --help|help) wh_info ; exit 0 ;;
@@ -2487,7 +2636,6 @@ case "$arg1" in
install-vkd3d) run_install_vkd3d "$@" ;; install-vkd3d) run_install_vkd3d "$@" ;;
change-wine) run_change_wine_version "$@" ;; change-wine) run_change_wine_version "$@" ;;
installed) check_installed_programs "$1" ;; installed) check_installed_programs "$1" ;;
run|-r) run_installed_programs "$1" ;;
backup-prefix) backup_prefix "$@" ;; backup-prefix) backup_prefix "$@" ;;
restore-prefix) restore_prefix "$@" ;; restore-prefix) restore_prefix "$@" ;;
remove-all) remove_winehelper "$@" ;; remove-all) remove_winehelper "$@" ;;
@@ -2496,6 +2644,14 @@ case "$arg1" in
create-base-pfx) create_base_pfx "$@" ;; create-base-pfx) create_base_pfx "$@" ;;
init-prefix) prepair_wine ; wait_wineserver ;; init-prefix) prepair_wine ; wait_wineserver ;;
clear-winetricks-cache) clear_winetricks_cache "$@" ;; clear-winetricks-cache) clear_winetricks_cache "$@" ;;
run|-r)
if check_installed_programs check_only "$1" ; then
WIN_FILE_EXEC="$(readlink -f "$EXE_PATH")"
shift
prepair_wine
wine_run "$WIN_FILE_EXEC" "$@"
fi
;;
*) *)
if [[ -f "$arg1" ]] ; then if [[ -f "$arg1" ]] ; then
WIN_FILE_EXEC="$(readlink -f "$arg1")" WIN_FILE_EXEC="$(readlink -f "$arg1")"
@@ -2516,3 +2672,8 @@ case "$arg1" in
fi fi
;; ;;
esac esac
if [[ -n "$WH_BG_PID" ]] ; then
print_info "Завершение фонового процесса: $WH_BG_PID"
kill "$WH_BG_PID" 2>/dev/null
fi

View File

@@ -33,393 +33,6 @@ class Var:
GENERAL = os.environ.get("GENERAL") GENERAL = os.environ.get("GENERAL")
WH_WINETRICKS = os.environ.get("WH_WINETRICKS") WH_WINETRICKS = os.environ.get("WH_WINETRICKS")
class DependencyManager:
"""Класс для управления проверкой и установкой системных зависимостей."""
def __init__(self):
"""Инициализирует менеджер, определяя необходимые пути."""
self.dependencies_script_path = self._get_dependencies_path()
self.config_dir = os.path.join(os.path.expanduser("~"), ".config", "winehelper")
self.hash_flag_file = os.path.join(self.config_dir, "dependencies_hash.txt")
os.makedirs(self.config_dir, exist_ok=True)
self.app_icon = QIcon(Var.WH_ICON_PATH) if Var.WH_ICON_PATH and os.path.exists(Var.WH_ICON_PATH) else QIcon()
def _get_dependencies_path(self):
"""Определяет и возвращает путь к скрипту dependencies.sh."""
if not Var.DATA_PATH:
return None
return os.path.join(Var.DATA_PATH, 'dependencies.sh')
def _calculate_file_hash(self):
"""Вычисляет хэш SHA256 файла зависимостей."""
if not self.dependencies_script_path or not os.path.exists(self.dependencies_script_path):
return None
hasher = hashlib.sha256()
try:
with open(self.dependencies_script_path, 'rb') as f:
while chunk := f.read(4096):
hasher.update(chunk)
return hasher.hexdigest()
except IOError:
return None
def _parse_dependencies_from_script(self):
"""
Парсит скрипт dependencies.sh для извлечения списка базовых пакетов.
Возвращает список пакетов или None в случае ошибки.
"""
if not os.path.exists(self.dependencies_script_path):
return None
base_packages = []
try:
with open(self.dependencies_script_path, 'r', encoding='utf-8') as f:
content = f.read()
content = content.replace('\\\n', '')
pattern = r'apt-get install\s+\{i586-,\}(\{.*?\}|[\w.-]+)'
matches = re.findall(pattern, content)
for match in matches:
match = match.strip()
if match.startswith('{') and match.endswith('}'):
group_content = match[1:-1]
packages = [pkg.strip() for pkg in group_content.split(',')]
base_packages.extend(packages)
else:
base_packages.append(match)
return sorted(list(set(pkg for pkg in base_packages if pkg))) or None
except Exception:
return None
def _parse_repo_error_from_script(self):
"""
Парсит скрипт dependencies.sh для извлечения сообщения об ошибке репозитория.
Возвращает сообщение или None в случае ошибки.
"""
if not os.path.exists(self.dependencies_script_path):
return None
try:
with open(self.dependencies_script_path, 'r', encoding='utf-8') as f:
content = f.read()
content = content.replace('\\\n', ' ')
match = re.search(r'apt-repo.*\|\|.*fatal\s+"([^"]+)"', content)
if match:
error_message = match.group(1).strip()
return re.sub(r'\s+', ' ', error_message)
return None
except Exception:
return None
def _show_startup_messages(self):
"""
Проверяет, является ли это первым запуском или обновлением,
и показывает соответствующие сообщения.
"""
current_hash = self._calculate_file_hash()
stored_hash = None
hash_file_exists = os.path.exists(self.hash_flag_file)
if hash_file_exists:
try:
with open(self.hash_flag_file, 'r', encoding='utf-8') as f:
stored_hash = f.read().strip()
except IOError:
pass
if not hash_file_exists:
msg_box = QMessageBox(QMessageBox.Information, "Первый запуск WineHelper",
"Поскольку это первый запуск, программа проверит наличие необходимых системных зависимостей.")
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
elif current_hash != stored_hash:
msg_box = QMessageBox(QMessageBox.Information, "Обновление зависимостей",
"Обнаружены изменения в системных требованиях.\n\n"
"Программа выполнит проверку, чтобы убедиться, что все компоненты на месте.")
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
def _save_dependency_hash(self):
"""Сохраняет хэш зависимостей в конфигурационный файл."""
current_hash = self._calculate_file_hash()
if not current_hash:
return
try:
with open(self.hash_flag_file, 'w', encoding='utf-8') as f:
f.write(current_hash)
except IOError:
print("Предупреждение: не удалось записать файл с хэшем зависимостей.")
def _perform_check_and_install(self):
"""
Выполняет основную логику проверки и установки зависимостей.
Возвращает True в случае успеха, иначе False.
"""
# Проверка наличия ключевых утилит
if not shutil.which('apt-repo') or not shutil.which('rpm'):
return True
if not self.dependencies_script_path or not os.path.exists(self.dependencies_script_path):
msg_box = QMessageBox(QMessageBox.Critical, "Критическая ошибка",
f"Файл зависимостей не найден по пути:\n'{self.dependencies_script_path}'.\n\n"
"Программа не может продолжить работу."
)
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
return False
# 1. Проверка наличия репозитория x86_64-i586
try:
result = subprocess.run(['apt-repo'], capture_output=True, text=True, check=False, encoding='utf-8')
if result.returncode != 0 or 'x86_64-i586' not in result.stdout:
error_message = self._parse_repo_error_from_script()
if not error_message:
msg_box = QMessageBox(QMessageBox.Critical, "Критическая ошибка",
f"Репозиторий x86_64-i586 не подключен, но не удалось извлечь текст ошибки из файла:\n'{self.dependencies_script_path}'.\n\n"
"Проверьте целостность скрипта. Работа программы будет прекращена."
)
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
return False
msg_box = QMessageBox(QMessageBox.Critical, "Ошибка репозитория",
f"{error_message}\n\nРабота программы будет прекращена.")
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
return False
except FileNotFoundError:
return True
# 2. Определение списка пакетов из dependencies.sh
base_packages = self._parse_dependencies_from_script()
# Если парсинг не удался или скрипт не найден, прерываем работу.
if not base_packages:
msg_box = QMessageBox(QMessageBox.Critical, "Критическая ошибка",
f"Не удалось найти или проанализировать файл зависимостей:\n'{self.dependencies_script_path}'.\n\n"
"Программа не может продолжить работу без списка необходимых пакетов."
)
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
return False
required_packages = [f"i586-{pkg}" for pkg in base_packages] + base_packages
# 3. Проверка, какие пакеты отсутствуют
try:
# Запрашиваем список всех установленных пакетов один раз для эффективности
result = subprocess.run(
['rpm', '-qa', '--queryformat', '%{NAME}\n'],
capture_output=True, text=True, check=True, encoding='utf-8'
)
installed_packages_set = set(result.stdout.splitlines())
required_packages_set = set(required_packages)
# Находим разницу между требуемыми и установленными пакетами
missing_packages = sorted(list(required_packages_set - installed_packages_set))
except (subprocess.CalledProcessError, FileNotFoundError) as e:
# В случае ошибки (например, rpm не найден), показываем критическое сообщение
msg_box = QMessageBox(QMessageBox.Critical, "Критическая ошибка",
f"Не удалось получить список установленных пакетов с помощью rpm.\n\nОшибка: {e}\n\n"
"Программа не может проверить зависимости и будет закрыта."
)
msg_box.setWindowIcon(self.app_icon)
msg_box.exec_()
return False
if not missing_packages:
return True
# 4. Запрос у пользователя на установку
msg_box = QMessageBox()
msg_box.setWindowIcon(self.app_icon)
msg_box.setIcon(QMessageBox.Warning)
msg_box.setWindowTitle("Отсутствуют зависимости")
# Устанавливаем формат текста в RichText, чтобы QMessageBox корректно обрабатывал HTML-теги.
msg_box.setTextFormat(Qt.RichText)
# Формируем весь текст как единый HTML-блок для корректного отображения.
full_html_text = (
"Для корректной работы WineHelper требуются дополнительные системные компоненты.<br><br>"
"Отсутствуют следующие пакеты:<br>"
# Ограничиваем высоту блока с пакетами и добавляем прокрутку, если список длинный.
f"""<div style="font-family: monospace; max-height: 150px; overflow-y: auto; margin-top: 5px; margin-bottom: 10px;">
{'<br>'.join(sorted(missing_packages))}
</div>"""
"Нажмите <b>'Установить'</b>, чтобы запустить установку с правами администратора. "
"Вам потребуется ввести пароль. Этот процесс может занять некоторое время."
)
msg_box.setText(full_html_text)
install_button = msg_box.addButton("Установить", QMessageBox.AcceptRole)
cancel_button = msg_box.addButton("Отмена", QMessageBox.RejectRole)
msg_box.setDefaultButton(install_button)
msg_box.exec_()
if msg_box.clickedButton() != install_button:
cancel_box = QMessageBox(QMessageBox.Warning, "Отмена",
"Установка отменена.\n\n"
"WineHelper не может продолжить работу\nбез необходимых зависимостей.")
cancel_box.setWindowIcon(self.app_icon)
cancel_box.exec_()
return False
# 5. Запуск установки с отображением лога в диалоговом окне
if not shutil.which('pkexec'):
error_box = QMessageBox(QMessageBox.Critical, "Ошибка",
"Не найден компонент 'pkexec' для повышения прав.\n"
"Пожалуйста, установите пакет 'polkit-pkexec', "
f"а затем установите зависимости вручную:\n\n sudo apt-get install {' '.join(missing_packages)}"
)
error_box.setWindowIcon(self.app_icon)
error_box.exec_()
return False
install_cmd_str = f"apt-get update && apt-get install -y {' '.join(missing_packages)}"
# Этот флаг будет установлен в True, если установка и проверка пройдут успешно.
installation_successful = False
# Создаем диалог для вывода лога установки
dialog = QDialog()
dialog.setWindowIcon(self.app_icon)
dialog.setWindowTitle("Установка зависимостей")
dialog.setMinimumSize(680, 400)
dialog.setModal(True)
# Центрирование окна по центру экрана
screen_geometry = QApplication.primaryScreen().availableGeometry()
dialog.move(
(screen_geometry.width() - dialog.width()) // 2,
(screen_geometry.height() - dialog.height()) // 2
)
layout = QVBoxLayout(dialog)
log_output = QTextEdit()
log_output.setReadOnly(True)
log_output.setFont(QFont("DejaVu Sans Mono", 10))
layout.addWidget(log_output)
close_button = QPushButton("Закрыть")
close_button.setEnabled(False)
close_button.clicked.connect(dialog.accept)
layout.addWidget(close_button)
process = QProcess(dialog)
process.setProcessChannelMode(QProcess.MergedChannels)
def handle_output():
# Используем insertPlainText для корректного отображения потокового вывода (например, прогресс-баров)
log_output.insertPlainText(process.readAll().data().decode('utf-8', 'ignore'))
log_output.moveCursor(QTextCursor.End)
def handle_finish(exit_code, exit_status):
nonlocal installation_successful
log_output.moveCursor(QTextCursor.End)
if exit_code == 0 and exit_status == QProcess.NormalExit:
log_output.append("\n<b><font color='green'>=== Установка успешно завершена ===</font></b>")
log_output.ensureCursorVisible()
# Повторная проверка зависимостей сразу после установки
try:
result = subprocess.run(
['rpm', '-qa', '--queryformat', '%{NAME}\n'],
capture_output=True, text=True, check=True, encoding='utf-8'
)
installed_packages_set = set(result.stdout.splitlines())
missing_packages_set = set(missing_packages)
still_missing = sorted(list(missing_packages_set - installed_packages_set))
except (subprocess.CalledProcessError, FileNotFoundError):
warn_box = QMessageBox(dialog)
warn_box.setWindowIcon(self.app_icon)
warn_box.setIcon(QMessageBox.Warning)
warn_box.setWindowTitle("Проверка не удалась")
warn_box.setText("Не удалось повторно проверить зависимости после установки.")
warn_box.exec_()
still_missing = missing_packages
if not still_missing:
installation_successful = True
close_button.setText("Запустить WineHelper")
else:
warn_box = QMessageBox(dialog)
warn_box.setWindowIcon(self.app_icon)
warn_box.setIcon(QMessageBox.Warning)
warn_box.setWindowTitle("Установка не завершена")
warn_box.setText(
"Не все зависимости были установлены. WineHelper может работать некорректно.\n\n"
f"Отсутствуют: {', '.join(sorted(still_missing))}\n\n"
"Попробуйте запустить установку снова или установите пакеты вручную."
)
warn_box.exec_()
else:
if exit_code == 127: # pkexec: пользователь отменил аутентификацию
log_output.append("\n<b><font color='orange'>=== УСТАНОВКА ОТМЕНЕНА ПОЛЬЗОВАТЕЛЕМ ===</font></b>")
log_output.append("Вы отменили ввод пароля. Установка зависимостей не была выполнена.")
elif exit_code == 126: # pkexec: у пользователя нет прав
log_output.append("\n<b><font color='red'>=== ОШИБКА: НЕДОСТАТОЧНО ПРАВ ===</font></b>")
log_output.append("У вашего пользователя нет прав для выполнения этой операции.")
else:
log_tag = "ПРЕРВАНО" if exit_status == QProcess.CrashExit else "ОШИБКА"
log_output.append(f"\n<b><font color='red'>=== {log_tag} (код: {exit_code}) ===</font></b>")
log_output.append("Произошла непредвиденная ошибка во время установки.")
log_output.ensureCursorVisible()
close_button.setEnabled(True)
def dialog_close_handler(event):
"""Обрабатывает закрытие окна во время установки зависимостей."""
if process.state() == QProcess.Running:
# QMessageBox без кнопок может некорректно обрабатывать закрытие.
# Используем простой QDialog для надежности.
info_dialog = QDialog(dialog)
info_dialog.setWindowTitle("Идет установка")
info_dialog.setModal(True)
info_dialog.setFixedSize(450, 150)
layout = QVBoxLayout(info_dialog)
label = QLabel(
"<h3>Установка зависимостей еще не завершена.</h3>"
"<p>Пожалуйста, дождитесь окончания процесса.</p>"
"<p>Закрыть основное окно можно будет после завершения установки.</p>"
)
label.setTextFormat(Qt.RichText)
label.setAlignment(Qt.AlignCenter)
layout.addWidget(label)
info_dialog.exec_()
event.ignore()
else:
event.accept()
process.readyRead.connect(handle_output)
process.finished.connect(handle_finish)
log_output.append(f"Выполнение команды:\npkexec sh -c \"{install_cmd_str}\"\n")
log_output.append("Пожалуйста, введите пароль в появившемся окне аутентификации...")
log_output.append("-" * 40 + "\n")
dialog.closeEvent = dialog_close_handler
process.start('pkexec', ['sh', '-c', install_cmd_str])
dialog.exec_()
return installation_successful
def run(self):
"""
Основной публичный метод для запуска полной проверки зависимостей.
Возвращает True, если все зависимости удовлетворены, иначе False.
"""
self._show_startup_messages()
if self._perform_check_and_install():
self._save_dependency_hash()
return True
return False
class WinetricksManagerDialog(QDialog): class WinetricksManagerDialog(QDialog):
"""Диалог для управления компонентами Winetricks.""" """Диалог для управления компонентами Winetricks."""
@@ -642,9 +255,9 @@ class WinetricksManagerDialog(QDialog):
settings_blacklist_pattern = None settings_blacklist_pattern = None
if category == 'dlls': if category == 'dlls':
# Исключаем d3d*, directx9, dont_use, dxvk*, vkd3d*, galliumnine, faudio*, Foundation # Исключаем dont_use, dxvk*, vkd3d*, galliumnine, faudio*, Foundation
dlls_blacklist_pattern = re.compile( dlls_blacklist_pattern = re.compile(
r'^(d3d|directx9|dont_use|dxvk|vkd3d|galliumnine|faudio|foundation)', re.IGNORECASE r'^(dont_use|dxvk|vkd3d|galliumnine|faudio|foundation)', re.IGNORECASE
) )
elif category == 'fonts': elif category == 'fonts':
fonts_blacklist_pattern = re.compile( fonts_blacklist_pattern = re.compile(
@@ -1034,14 +647,21 @@ class ScriptParser:
with open(script_path, 'r', encoding='utf-8') as f: with open(script_path, 'r', encoding='utf-8') as f:
lines = f.readlines() lines = f.readlines()
# 1. Приоритет у PROG_ICON # 1. Приоритет у переменной ICONS_BUTTON_GUI для GUI
for line in lines:
if line.strip().startswith('export ICONS_BUTTON_GUI='):
icon_names_str = line.split('=', 1)[1].strip().strip('"\'')
if icon_names_str:
return icon_names_str.split()
# 2. Если ICONS_BUTTON_GUI не найдена, ищем PROG_ICON (для обратной совместимости)
for line in lines: for line in lines:
if line.strip().startswith('export PROG_ICON='): if line.strip().startswith('export PROG_ICON='):
icon_name = line.split('=', 1)[1].strip().strip('"\'') icon_names_str = line.split('=', 1)[1].strip().strip('"\'')
if icon_name: if icon_names_str:
return [icon_name] return icon_names_str.split()
# 2. Если PROG_ICON не найден, ищем все вызовы create_desktop # 3. Если ничего не найдено, ищем все вызовы create_desktop
icon_names = [] icon_names = []
for line in lines: for line in lines:
line = line.strip() line = line.strip()
@@ -1129,28 +749,28 @@ class WineVersionSelectionDialog(QDialog):
self.search_edit.textChanged.connect(self.filter_versions) self.search_edit.textChanged.connect(self.filter_versions)
main_layout.addWidget(self.search_edit) main_layout.addWidget(self.search_edit)
self.version_tabs = QTabWidget() self.main_tabs = QTabWidget()
main_layout.addWidget(self.version_tabs) main_layout.addWidget(self.main_tabs)
self.load_versions() self.load_versions()
def load_versions(self): def load_versions(self):
"""Запускает процесс получения списка версий Wine.""" """Запускает процесс получения списка версий Wine."""
self.version_tabs.clear() self.main_tabs.clear()
loading_widget = QWidget() loading_widget = QWidget()
loading_layout = QVBoxLayout(loading_widget) loading_layout = QVBoxLayout(loading_widget)
status_label = QLabel("Загрузка, пожалуйста, подождите...") status_label = QLabel("Загрузка, пожалуйста, подождите...")
status_label.setAlignment(Qt.AlignCenter) status_label.setAlignment(Qt.AlignCenter)
loading_layout.addWidget(status_label) loading_layout.addWidget(status_label)
self.version_tabs.addTab(loading_widget, "Загрузка...") self.main_tabs.addTab(loading_widget, "Загрузка...")
self.version_tabs.setEnabled(False) self.main_tabs.setEnabled(False)
QApplication.processEvents() QApplication.processEvents()
self._parse_sha256_list() self._parse_sha256_list()
self.populate_ui() self.populate_ui()
self.version_tabs.setEnabled(True) self.main_tabs.setEnabled(True)
def _parse_sha256_list(self): def _parse_sha256_list(self):
"""Парсит sha256sum.list для получения списка версий.""" """Парсит sha256sum.list для получения списка версий."""
@@ -1170,10 +790,10 @@ class WineVersionSelectionDialog(QDialog):
if not line: if not line:
continue continue
match = re.match(r'^#+\s*([^#]+?)\s*#*$', line) match = re.match(r'^#+\s*(.*?)\s*#*$', line)
if match: if match:
group_name = match.group(1) group_name = match.group(1).strip()
allowed_groups = {"WINE", "WINE_LG", "PROTON_LG", "PROTON_STEAM"} allowed_groups = {"WINE WOW64", "WINE AMD64", "WINE I586"}
# Отображаем только группы, которые являются сборками WINE или PROTON # Отображаем только группы, которые являются сборками WINE или PROTON
if group_name in allowed_groups: if group_name in allowed_groups:
current_group = group_name current_group = group_name
@@ -1194,9 +814,60 @@ class WineVersionSelectionDialog(QDialog):
QMessageBox.warning(self, "Ошибка", f"Не удалось прочитать файл версий:\n{e}") QMessageBox.warning(self, "Ошибка", f"Не удалось прочитать файл версий:\n{e}")
self.wine_versions_data = {} self.wine_versions_data = {}
def _get_installed_versions(self):
"""Возвращает список локально установленных версий Wine."""
dist_path = os.path.join(Var.USER_WORK_PATH, "dist")
if not os.path.isdir(dist_path):
return []
try:
return sorted([
name for name in os.listdir(dist_path)
if os.path.isdir(os.path.join(dist_path, name))
], reverse=True)
except OSError:
return []
def populate_ui(self): def populate_ui(self):
"""Заполняет UI отфильтрованными версиями.""" """Заполняет UI отфильтрованными версиями."""
self.version_tabs.clear() self.main_tabs.clear()
# --- Вкладка "Установленные" ---
installed_tab = QWidget()
self.main_tabs.addTab(installed_tab, "Установленные")
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 = []
# Системная версия
if shutil.which('wine'):
try:
result = subprocess.run(['wine', '--version'], capture_output=True, text=True, check=True, encoding='utf-8')
self.system_wine_display_name = result.stdout.strip()
except (FileNotFoundError, subprocess.CalledProcessError) as e:
print(f"Не удалось получить версию системного wine: {e}")
installed_versions_for_grid.append((self.system_wine_display_name, "system"))
# Локально установленные версии
local_versions = self._get_installed_versions()
installed_versions_for_grid.extend(local_versions)
self._create_grid_buttons(self.installed_grid_layout, installed_versions_for_grid)
# --- Вкладка "Скачать" ---
download_tab = QWidget()
download_layout = QVBoxLayout(download_tab)
self.version_tabs = QTabWidget() # Вложенные табы для категорий
download_layout.addWidget(self.version_tabs)
download_tab.setLayout(download_layout)
self.main_tabs.addTab(download_tab, "Скачать")
if not self.wine_versions_data: if not self.wine_versions_data:
error_widget = QWidget() error_widget = QWidget()
@@ -1205,55 +876,33 @@ class WineVersionSelectionDialog(QDialog):
error_label.setAlignment(Qt.AlignCenter) error_label.setAlignment(Qt.AlignCenter)
error_layout.addWidget(error_label) error_layout.addWidget(error_label)
self.version_tabs.addTab(error_widget, "Ошибка") self.version_tabs.addTab(error_widget, "Ошибка")
self.filter_versions()
return return
# --- Фильтрация и сортировка групп в зависимости от архитектуры ---
is_win64 = self.architecture == "win64" is_win64 = self.architecture == "win64"
re_32bit = re.compile(r'i[3-6]86|x86(?!_64)')
re_64bit = re.compile(r'amd64|x86_64|wow64')
# --- System Tab --- if is_win64:
if shutil.which('wine'): allowed_groups_for_arch = {"WINE AMD64", "WINE WOW64"}
self.system_wine_display_name = "Системная версия" tab_order = ["WINE AMD64", "WINE WOW64"]
try: else: # win32
# Пытаемся получить версию системного wine allowed_groups_for_arch = {"WINE I586","WINE AMD64"}
result = subprocess.run(['wine', '--version'], capture_output=True, text=True, check=True, encoding='utf-8') tab_order = ["WINE I586","WINE AMD64"]
version_line = result.stdout.strip()
# Вывод обычно "wine-X.Y.Z"
self.system_wine_display_name = version_line
except (FileNotFoundError, subprocess.CalledProcessError) as e:
print(f"Не удалось получить версию системного wine: {e}")
# Если wine возвращает ошибку, используем имя по умолчанию "Системная версия"
self._create_version_tab("Системный", [(self.system_wine_display_name, "system")]) # Получаем только те ключи, которые есть в данных и разрешены для данной архитектуры
available_keys = [key for key in self.wine_versions_data.keys() if key in allowed_groups_for_arch]
# Определяем желаемый порядок вкладок # Сортируем доступные ключи в соответствии с заданным порядком
tab_order = ["WINE", "WINE_LG", "PROTON_LG", "PROTON_STEAM"] group_keys = sorted(available_keys, key=lambda k: tab_order.index(k))
# Сортируем ключи в соответствии с заданным порядком
group_keys = sorted(self.wine_versions_data.keys(), key=lambda k: tab_order.index(k) if k in tab_order else len(tab_order))
for key in group_keys: for key in group_keys:
versions = self.wine_versions_data.get(key, []) versions = self.wine_versions_data.get(key, [])
if not versions:
filtered_versions = []
for name in sorted(versions, reverse=True):
if is_win64:
if re_64bit.search(name) or not re_32bit.search(name):
filtered_versions.append(name)
else:
filtered_versions.append(name)
if not filtered_versions:
continue continue
self._create_version_tab(key, sorted(versions, reverse=True))
pretty_key = key.replace('_', ' ').title()
if key.endswith('_LG'):
pretty_key = pretty_key.replace(' Lg', ' LG')
self._create_version_tab(pretty_key, filtered_versions)
self.filter_versions() self.filter_versions()
def _create_version_tab(self, title, versions_list): def _create_version_tab(self, title, versions_list, is_download_tab=True):
"""Создает вкладку с сеткой кнопок для переданного списка версий.""" """Создает вкладку с сеткой кнопок для переданного списка версий."""
tab_page = QWidget() tab_page = QWidget()
tab_layout = QVBoxLayout(tab_page) tab_layout = QVBoxLayout(tab_page)
@@ -1261,6 +910,7 @@ class WineVersionSelectionDialog(QDialog):
scroll_area = QScrollArea() scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True) scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
tab_layout.addWidget(scroll_area) tab_layout.addWidget(scroll_area)
scroll_content = QWidget() scroll_content = QWidget()
@@ -1269,6 +919,14 @@ class WineVersionSelectionDialog(QDialog):
grid_layout = QGridLayout(scroll_content) grid_layout = QGridLayout(scroll_content)
grid_layout.setAlignment(Qt.AlignTop) grid_layout.setAlignment(Qt.AlignTop)
self._create_grid_buttons(grid_layout, versions_list, is_download_tab=is_download_tab)
self.version_tabs.addTab(tab_page, title)
def _create_grid_buttons(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')
num_columns = 3 num_columns = 3
row, col = 0, 0 row, col = 0, 0
for version_data in versions_list: for version_data in versions_list:
@@ -1279,36 +937,64 @@ class WineVersionSelectionDialog(QDialog):
btn = QPushButton(display_name) btn = QPushButton(display_name)
btn.clicked.connect(partial(self.on_version_selected, value_name)) btn.clicked.connect(partial(self.on_version_selected, value_name))
# Выделяем системную версию Wine
if value_name == "system":
btn.setText(f"{display_name} (Системный)")
btn.setToolTip("Системная версия Wine, установленная в вашей ОС.")
# Отключение 32-битных версий Wine при выбранном 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-битных версий Wine (системной и wow64) при выборе 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) grid_layout.addWidget(btn, row, col)
col += 1 col += 1
if col >= num_columns: if col >= num_columns:
col = 0 col = 0
row += 1 row += 1
self.version_tabs.addTab(tab_page, title)
def filter_versions(self): def filter_versions(self):
"""Фильтрует видимость кнопок версий на основе текста поиска.""" """Фильтрует видимость кнопок версий на основе текста поиска."""
search_text = self.search_edit.text().lower() search_text = self.search_edit.text().lower()
for i in range(self.version_tabs.count()): # Фильтр для вкладки "Установленные"
tab_widget = self.version_tabs.widget(i) if hasattr(self, 'installed_grid_layout'):
# The grid layout is inside a scroll area content widget self._filter_grid(self.installed_grid_layout, search_text)
grid_layout = tab_widget.findChild(QGridLayout)
if not grid_layout:
continue
any_visible_in_tab = False # Фильтр для вкладок "Скачать"
for j in range(grid_layout.count()): if hasattr(self, 'version_tabs'):
btn_widget = grid_layout.itemAt(j).widget() for i in range(self.version_tabs.count()):
tab_widget = self.version_tabs.widget(i)
grid_layout = tab_widget.findChild(QGridLayout)
if grid_layout:
any_visible = self._filter_grid(grid_layout, search_text)
self.version_tabs.setTabEnabled(i, any_visible)
def _filter_grid(self, grid_layout, search_text):
"""Helper-функция для фильтрации кнопок в одной сетке."""
any_visible_in_grid = False
if not grid_layout:
return False
for j in range(grid_layout.count()):
item = grid_layout.itemAt(j)
if item:
btn_widget = item.widget()
if isinstance(btn_widget, QPushButton): if isinstance(btn_widget, QPushButton):
is_match = search_text in btn_widget.text().lower() is_match = search_text in btn_widget.text().lower()
btn_widget.setVisible(is_match) btn_widget.setVisible(is_match)
if is_match: if is_match:
any_visible_in_tab = True any_visible_in_grid = True
# Enable/disable tab based on content return any_visible_in_grid
self.version_tabs.setTabEnabled(i, any_visible_in_tab)
def on_version_selected(self, version_name): def on_version_selected(self, version_name):
"""Обрабатывает выбор версии.""" """Обрабатывает выбор версии."""
@@ -1333,6 +1019,7 @@ class CreatePrefixDialog(QDialog):
self.prefix_name = None self.prefix_name = None
self.wine_arch = None self.wine_arch = None
self.base_pfx = None self.base_pfx = None
self.prepared_prefixes = {}
self.selected_wine_version_value = None self.selected_wine_version_value = None
self.selected_wine_version_display = None self.selected_wine_version_display = None
@@ -1367,18 +1054,10 @@ class CreatePrefixDialog(QDialog):
arch_layout.addWidget(self.arch_win64_radio) arch_layout.addWidget(self.arch_win64_radio)
form_layout.addRow("<b>Разрядность:</b>", arch_widget) form_layout.addRow("<b>Разрядность:</b>", arch_widget)
type_widget = QWidget() # Виджет для выбора типа префикса (шаблона)
type_layout = QHBoxLayout(type_widget) self.prefix_template_selector = QComboBox()
type_layout.setContentsMargins(0, 0, 0, 0) self.prefix_template_selector.setToolTip("Выберите шаблон для создания префикса.")
self.type_clean_radio = QRadioButton("Чистый") form_layout.addRow("<b>Шаблон префикса:</b>", self.prefix_template_selector)
self.type_clean_radio.setToolTip("Создает пустой префикс Wine без каких-либо дополнительных компонентов.")
self.type_recommended_radio = QRadioButton("С рекомендуемыми библиотеками")
tooltip_text = "Устанавливает базовый набор компонентов, необходимый для большинства приложений"
self.type_recommended_radio.setToolTip(tooltip_text)
self.type_clean_radio.setChecked(True)
type_layout.addWidget(self.type_clean_radio)
type_layout.addWidget(self.type_recommended_radio)
form_layout.addRow("<b>Наполнение:</b>", type_widget)
self.wine_version_edit = QLineEdit() self.wine_version_edit = QLineEdit()
self.wine_version_edit.setReadOnly(True) self.wine_version_edit.setReadOnly(True)
@@ -1411,10 +1090,82 @@ class CreatePrefixDialog(QDialog):
layout.addLayout(button_layout) layout.addLayout(button_layout)
# Connect signals # Connect signals
self.arch_win32_radio.toggled.connect(self.clear_wine_version_selection) self.arch_win32_radio.toggled.connect(self.on_architecture_changed)
self.prefix_name_edit.textChanged.connect(self.validate_prefix_name) self.prefix_name_edit.textChanged.connect(self.validate_prefix_name)
self.wine_version_edit.textChanged.connect(self.update_create_button_state) 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': []}
sha256_file = os.path.join(Var.DATA_PATH, "sha256sum.list")
if not os.path.exists(sha256_file):
QMessageBox.warning(self, "Ошибка", f"Файл с описаниями префиксов не найден: {sha256_file}")
return
in_prefix_section = False
current_description = ""
current_prefix_name = None
try:
with open(sha256_file, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if "##### PREFIX #####" in line:
in_prefix_section = True
continue
elif line.startswith("#####"):
in_prefix_section = False
continue
if not in_prefix_section:
continue
if re.match(r'^[a-f0-9]{64}', line):
# Если у нас есть имя и описание для предыдущего префикса, добавляем его
if current_prefix_name and current_description:
arch_for_prev_prefix = None
if "_x86_" in current_prefix_name or "_i586_" in current_prefix_name:
arch_for_prev_prefix = 'win32'
elif "_x64_" in current_prefix_name or "_amd64_" in current_prefix_name:
arch_for_prev_prefix = 'win64'
if arch_for_prev_prefix:
description_to_add = current_description.strip().replace('\\n', '\n')
self.prepared_prefixes[arch_for_prev_prefix].append((current_prefix_name, description_to_add))
# Сбрасываем описание для нового префикса
current_description = ""
# Получаем имя нового префикса
current_prefix_name = line.split(maxsplit=1)[1].replace('.tar.xz', '') if len(line.split(maxsplit=1)) > 1 else None
elif line.startswith('# '):
# Накапливаем описание
comment_line = line[2:].strip()
if current_description:
current_description += "\n" + comment_line
else:
current_description = comment_line
# После цикла добавляем описание для самого последнего префикса, если оно есть
if current_prefix_name and current_description:
arch = None
if "_x86_" in current_prefix_name or "_i586_" in current_prefix_name: arch = 'win32'
elif "_x64_" in current_prefix_name or "_amd64_" in current_prefix_name: arch = 'win64'
if arch:
self.prepared_prefixes[arch].append((current_prefix_name, current_description.strip().replace('\\n', '\n')))
except IOError as e:
QMessageBox.warning(self, "Ошибка", f"Не удалось прочитать файл с описаниями префиксов: {e}")
# Добавляем опцию "Чистый префикс" для обеих архитектур
self.prepared_prefixes['win32'].insert(0, ('none', 'Создать чистый префикс без дополнительных библиотек'))
self.prepared_prefixes['win64'].insert(0, ('none', 'Создать чистый префикс без дополнительных библиотек'))
def open_wine_version_dialog(self): def open_wine_version_dialog(self):
"""Открывает диалог выбора версии Wine.""" """Открывает диалог выбора версии Wine."""
architecture = "win32" if self.arch_win32_radio.isChecked() else "win64" architecture = "win32" if self.arch_win32_radio.isChecked() else "win64"
@@ -1423,11 +1174,29 @@ class CreatePrefixDialog(QDialog):
self.wine_version_edit.setText(dialog.selected_display_text) self.wine_version_edit.setText(dialog.selected_display_text)
self.selected_wine_version_value = dialog.selected_version self.selected_wine_version_value = dialog.selected_version
def clear_wine_version_selection(self): def on_architecture_changed(self):
"""Сбрасывает выбор версии Wine.""" """Обновляет список шаблонов и сбрасывает выбор версии Wine при смене архитектуры."""
# Сбрасываем выбор версии
self.wine_version_edit.clear() self.wine_version_edit.clear()
self.selected_wine_version_value = None 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:
# Для 'none' используем более понятное имя
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): def validate_prefix_name(self, text):
"""Проверяет имя префикса в реальном времени и показывает/скрывает предупреждение.""" """Проверяет имя префикса в реальном времени и показывает/скрывает предупреждение."""
valid_pattern = r'^[a-zA-Z0-9_-]*$' valid_pattern = r'^[a-zA-Z0-9_-]*$'
@@ -1471,7 +1240,10 @@ class CreatePrefixDialog(QDialog):
# Save data # Save data
self.prefix_name = prefix_name self.prefix_name = prefix_name
self.wine_arch = "win32" if self.arch_win32_radio.isChecked() else "win64" self.wine_arch = "win32" if self.arch_win32_radio.isChecked() else "win64"
self.base_pfx = "none" if self.type_clean_radio.isChecked() else ""
# Получаем значение `BASE_PFX` из выбранного шаблона
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.selected_wine_version_display = self.wine_version_edit.text()
self.accept() self.accept()
@@ -1567,6 +1339,7 @@ class ComponentVersionSelectionDialog(QDialog):
self.scroll_area = QScrollArea() self.scroll_area = QScrollArea()
self.scroll_area.setWidgetResizable(True) self.scroll_area.setWidgetResizable(True)
self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
main_layout.addWidget(self.scroll_area) main_layout.addWidget(self.scroll_area)
scroll_content = QWidget() scroll_content = QWidget()
@@ -2242,7 +2015,27 @@ class WineHelperGUI(QMainWindow):
scroll_area = QScrollArea() scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True) scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll_area.setContentsMargins(0, 0, 0, 0) scroll_area.setContentsMargins(0, 0, 0, 0)
# Уменьшаем ширину вертикального скроллбара
scroll_area.setStyleSheet("""
QScrollBar:vertical {
width: 10px;
background: transparent;
margin: 0px;
}
QScrollBar::handle:vertical {
background: #555;
min-height: 20px;
border-radius: 5px;
}
QScrollBar::handle:vertical:hover {
background: #666;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0px;
}
""")
layout.addWidget(scroll_area) layout.addWidget(scroll_area)
scroll_content_widget = QWidget() scroll_content_widget = QWidget()
@@ -4155,6 +3948,8 @@ class WineHelperGUI(QMainWindow):
QMessageBox.critical(self, "Ошибка", f"Не удалось модифицировать команду для отладки: {e}") QMessageBox.critical(self, "Ошибка", f"Не удалось модифицировать команду для отладки: {e}")
return return
os.environ["WH_SKIP_DEPS"] = "1"
process = QProcess() process = QProcess()
env = QProcessEnvironment.systemEnvironment() env = QProcessEnvironment.systemEnvironment()
@@ -4187,6 +3982,7 @@ class WineHelperGUI(QMainWindow):
self.running_apps[desktop_path] = process self.running_apps[desktop_path] = process
self._set_run_button_state(True) self._set_run_button_state(True)
print(f"Запущено: {program} {' '.join(arguments)}") print(f"Запущено: {program} {' '.join(arguments)}")
os.environ["WH_SKIP_DEPS"] = "0"
except Exception as e: except Exception as e:
QMessageBox.critical(self, "Ошибка запуска", QMessageBox.critical(self, "Ошибка запуска",
f"Не удалось запустить команду:\n{command_str}\n\nОшибка: {str(e)}") f"Не удалось запустить команду:\n{command_str}\n\nОшибка: {str(e)}")
@@ -4967,6 +4763,7 @@ class WineHelperGUI(QMainWindow):
if exit_code == 0: if exit_code == 0:
self.command_log_output.append(f"\n=== Восстановление успешно завершено ===") self.command_log_output.append(f"\n=== Восстановление успешно завершено ===")
self.update_installed_apps() self.update_installed_apps()
self._load_created_prefixes()
self.filter_installed_buttons() self.filter_installed_buttons()
else: else:
self.command_log_output.append(f"\n=== Ошибка выполнения (код: {exit_code}) ===") self.command_log_output.append(f"\n=== Ошибка выполнения (код: {exit_code}) ===")
@@ -4989,6 +4786,13 @@ class WineHelperGUI(QMainWindow):
def main(): def main():
"""Основная точка входа в приложение.""" """Основная точка входа в приложение."""
# Включаем поддержку HiDPI до создания QApplication для надежного и предсказуемого масштабирования.
# AA_EnableHighDpiScaling включает автоматическое масштабирование на основе DPI дисплея.
if hasattr(Qt, 'AA_EnableHighDpiScaling'):
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
# AA_UseHighDpiPixmaps позволяет использовать высококачественные иконки (например, @2x).
if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
# QApplication должен быть создан до использования любых других частей Qt # QApplication должен быть создан до использования любых других частей Qt
app = QApplication(sys.argv) app = QApplication(sys.argv)
@@ -5013,38 +4817,35 @@ def main():
# На всякий случай удаляем старый файл сокета, если он остался от сбоя. # На всякий случай удаляем старый файл сокета, если он остался от сбоя.
QLocalServer.removeServer(socket_name) QLocalServer.removeServer(socket_name)
dependency_manager = DependencyManager() window = WineHelperGUI()
if dependency_manager.run():
window = WineHelperGUI()
# Создаем локальный сервер для приема "сигналов" от последующих запусков # Создаем локальный сервер для приема "сигналов" от последующих запусков
server = QLocalServer(window) server = QLocalServer(window)
# Функция для обработки входящих подключений # Функция для обработки входящих подключений
def handle_new_connection(): def handle_new_connection():
client_socket = server.nextPendingConnection() client_socket = server.nextPendingConnection()
if client_socket: if client_socket:
# Ждем данные (не обязательно, но для надежности) # Ждем данные (не обязательно, но для надежности)
client_socket.waitForReadyRead(100) client_socket.waitForReadyRead(100)
client_socket.readAll() # Очищаем буфер client_socket.readAll() # Очищаем буфер
window.activate() window.activate()
client_socket.close() client_socket.close()
server.newConnection.connect(handle_new_connection) server.newConnection.connect(handle_new_connection)
# Начинаем слушать. Если не удалось, программа все равно будет работать, # Начинаем слушать. Если не удалось, программа все равно будет работать,
# но без функции активации существующего окна. # но без функции активации существующего окна.
if not server.listen(socket_name): if not server.listen(socket_name):
print(f"Предупреждение: не удалось запустить сервер {socket_name}: {server.errorString()}") print(f"Предупреждение: не удалось запустить сервер {socket_name}: {server.errorString()}")
# Сохраняем ссылку на сервер, чтобы он не был удален сборщиком мусора # Сохраняем ссылку на сервер, чтобы он не был удален сборщиком мусора
window.server = server window.server = server
window.show() window.show()
# Создаем иконку в системном трее после создания окна # Создаем иконку в системном трее после создания окна
# window.create_tray_icon() # Временно отключено # window.create_tray_icon() # Временно отключено
return app.exec_() return app.exec_()
return 1
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(main()) sys.exit(main())