forked from CastroFidel/winehelper
		
	Compare commits
	
		
			60 Commits
		
	
	
		
			e2b2c9568c
			...
			devel
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4afdbaa220 | ||
|  | 81013bfe71 | ||
|  | caccc333db | ||
|  | 151d0ffc48 | ||
|  | ad91466475 | ||
|  | 5e4d94bb57 | ||
|  | 5b572ff540 | ||
|  | c68bcc9abf | ||
|  | 1ad2c6cfa8 | ||
|  | 16a686dc37 | ||
|  | c9d5619ab9 | ||
|  | 74311e9c04 | ||
|  | eb9bef83e2 | ||
|  | c7eddb8b53 | ||
|  | dfc6c1c836 | ||
|  | 04187e9463 | ||
|  | 5f915ab58d | ||
|  | 0e8ee7788a | ||
|  | 49c1ac6846 | ||
|  | 971bcd0f5a | ||
|  | 5b21015aee | ||
|  | 7dee08bcfb | ||
|  | 633deaf1c1 | ||
|  | 4df9508547 | ||
|  | 989f04cdd8 | ||
|  | 95b189f5a2 | ||
|  | 371553277a | ||
|  | dabf50103d | ||
|  | 590b37f1a3 | ||
|  | 1f9b4a9146 | ||
|  | 39f21373f1 | ||
|  | e984ffdb8c | ||
|  | 48834dc078 | ||
|  | b62d06ed71 | ||
|  | 9a1b78276e | ||
|  | f788307f05 | ||
|  | 14273f723b | ||
|  | a8e0fdce0a | ||
|  | da3d5cd7af | ||
|  | 3ee499c758 | ||
|  | 6286cccbab | ||
|  | e8d462b665 | ||
|  | 6476a84ce7 | ||
|  | db7e3f5220 | ||
|  | a817d1a6f5 | ||
|  | e1fc25bb72 | ||
|  | 7c90da2088 | ||
|  | 108316148a | ||
|  | 9029f4d0e8 | ||
|  | cedebe73c1 | ||
|  | e04811446c | ||
|  | 15712f0a0a | ||
|  | 8eeee56ee1 | ||
|  | ac4dd4f0bf | ||
|  | c15d751372 | ||
|  | 78113b92a5 | ||
|  | 9e8e41e812 | ||
|  | 5f4d3a54b1 | ||
|  | 9d16883e6e | ||
|  | e3cafee4f5 | 
							
								
								
									
										11
									
								
								CHANGELOG
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								CHANGELOG
									
									
									
									
									
								
							| @@ -1,5 +1,16 @@ | |||||||
| История изменений: | История изменений: | ||||||
|  |  | ||||||
|  | 0.7.0 | ||||||
|  | * обновлен графический режим Qt5 | ||||||
|  |     - добавлена кнопка открытия каталога с резервными копиями и логами | ||||||
|  |     - добавлена кнопка открытия каталога с префиксом | ||||||
|  |     - добавлена блокировка кнопок для установленного приложения, если оно уже запущено | ||||||
|  |     - добавлено отображения процесса установки сторонних компонентов с помощью winetricks | ||||||
|  |     - добавлена возможность отображения и установки тестовых скриптов (выключено по умолчанию) | ||||||
|  | * добавлены скрипты установки для t-flex версии 18 | ||||||
|  | * добавлен список тестовых скриптов установки ПО | ||||||
|  | * добавлена возможность ассоциации файлов для передачи в приложения запускаемых в WineHelper | ||||||
|  |  | ||||||
| 0.6.0 | 0.6.0 | ||||||
| * обновлен графический режим Qt5 | * обновлен графический режим Qt5 | ||||||
| * добавлен иконка в трее для графического режима Qt5 | * добавлен иконка в трее для графического режима Qt5 | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								GENERAL
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								GENERAL
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | # Руководство пользователя | ||||||
|  | Подробное и актуальное руководство по использованию WineHelper смотрите на сайте: https://www.altlinux.org/Winehelper | ||||||
|  |  | ||||||
|  | # Совместимость ПО и сертификаты | ||||||
|  | С полным списком совместимого ПО и сертификатами можно ознакомиться по следующим ссылкам: | ||||||
|  | Для 10 платформы: https://www.basealt.ru/fileadmin/user_upload/compatibility/P10-view2.html | ||||||
|  | Для 11 платформы: https://www.basealt.ru/fileadmin/user_upload/compatibility/P11-view2.html | ||||||
| @@ -4,7 +4,7 @@ _winehelper_completions() { | |||||||
|     COMPREPLY=() |     COMPREPLY=() | ||||||
|     cur="${COMP_WORDS[COMP_CWORD]}" |     cur="${COMP_WORDS[COMP_CWORD]}" | ||||||
|     prev="${COMP_WORDS[COMP_CWORD-1]}" |     prev="${COMP_WORDS[COMP_CWORD-1]}" | ||||||
|     opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine" |     opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine clear-winetricks-cache" | ||||||
|     wine_cmd="winecfg winereg winefile wineconsole winetricks desktop regedit explorer cmd run" |     wine_cmd="winecfg winereg winefile wineconsole winetricks desktop regedit explorer cmd run" | ||||||
|  |  | ||||||
|     case "${prev}" in |     case "${prev}" in | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ _winehelper() { | |||||||
|     'backup-prefix[Создать резерную копию префикса]' |     'backup-prefix[Создать резерную копию префикса]' | ||||||
|     'restore-prefix[восстановить префикс из резервной копии "путь/до/whpack"]' |     'restore-prefix[восстановить префикс из резервной копии "путь/до/whpack"]' | ||||||
|     'change-wine[Изменить версию Wine/Proton для префикса]' |     'change-wine[Изменить версию Wine/Proton для префикса]' | ||||||
|  |     'clear-winetricks-cache[Очистить кэш Winetricks]' | ||||||
|   ) |   ) | ||||||
|  |  | ||||||
|   wine_cmd=( |   wine_cmd=( | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
| # info_ru:  Сервис обновления ПО | # info_ru:  Сервис обновления ПО: "R-Атлас", "R-Инфо" и "R-Тариф". | ||||||
| ######################################################################## | ######################################################################## | ||||||
| export PROG_URL="https://daobit.ru" | export PROG_URL="https://daobit.ru" | ||||||
| export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586" | export WH_WINE_USE="wine_x_tkg_10-0_i586" # wine-9.0.9-alt1-i586" | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
| # info_ru: «Справки БК» — специальное программное обеспечение, предназначенное для заполнения справок о доходах, расходах, об имуществе и обязательствах имущественного характера. | # info_ru: «Справки БК» (Windows версия 2.5.5) от 31.01.2024 — специальное программное обеспечение, предназначенное для заполнения справок о доходах, расходах, об имуществе и обязательствах имущественного характера. | ||||||
| ######################################################################## | ######################################################################## | ||||||
| export PROG_URL="https://spravki-bk.ru" | export PROG_URL="https://spravki-bk.ru" | ||||||
| export WH_WINE_USE="wine-9.0.14-alt1-i586-spravkibk" | export WH_WINE_USE="wine-9.0.14-alt1-i586-spravkibk" | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								autoinstall/t-flex-cad18
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								autoinstall/t-flex-cad18
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | # info_ru: Профессиональная САПР, объединяющая в себе мощные параметрические возможности 2D и 3D-моделирования со средствами создания и оформления чертежей и конструкторской документации по ЕСКД. | ||||||
|  | ######################################################################## | ||||||
|  | export PROG_URL="https://www.tflexcad.ru" | ||||||
|  | export PROG_NAME="T-FLEX CAD 18" | ||||||
|  | export PROG_ICON="tflexcad" | ||||||
|  | export WH_WINE_USE="wine_wh_tflex_10-9_amd64" | ||||||
|  | export BASE_PFX="tflex_pfx_x64_v03" | ||||||
|  | export WINEARCH="win64" | ||||||
|  | export WH_WINDOWS_VER="10" | ||||||
|  | export WINEPREFIX="tflex" | ||||||
|  | export WH_XDG_OPEN="log" | ||||||
|  | export WH_USE_MESA_GL_OVERRIDE="1" | ||||||
|  |  | ||||||
|  | # используем общий whdb файл для подготовки префикса и сервисов | ||||||
|  | # prepair_wine используется из файла настроек | ||||||
|  | source "$WH_DB_DIR/t-flex-cad.whdb" | ||||||
|  |  | ||||||
|  | # Программа T-FLEX CAD | ||||||
|  | AUTOINSTALL_ZIP="${WH_TMP_DIR}/T-FLEX CAD 18.zip" | ||||||
|  | AUTOINSTALL_DIR="${WH_TMP_DIR}" | ||||||
|  | AUTOINSTALL_UNPACK="${WH_TMP_DIR}/T-FLEX CAD 18" | ||||||
|  | AUTOINSTALL_EXE="${WH_TMP_DIR}/T-FLEX CAD 18/T-FLEX CAD 18.msi" | ||||||
|  |  | ||||||
|  | if try_download "https://www.tflex.ru/downloads/V18/T-FLEX%20CAD%2018.zip" "${AUTOINSTALL_ZIP}" ; then | ||||||
|  |     unpack "${AUTOINSTALL_ZIP}" "${AUTOINSTALL_DIR}" | ||||||
|  |     try_remove_file "${AUTOINSTALL_ZIP}" | ||||||
|  |  | ||||||
|  |     wine_run_install "${AUTOINSTALL_EXE}" /q | ||||||
|  |     try_remove_dir "${AUTOINSTALL_UNPACK}" | ||||||
|  |  | ||||||
|  |     WIN_FILE_EXEC="$DRIVE_C/Program Files/T-FLEX CAD 18/Program/TFlexCad.exe" | ||||||
|  |     create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON" "TFlexCad" | ||||||
|  | fi | ||||||
							
								
								
									
										52
									
								
								autoinstall/t-flex-cad18-applications
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								autoinstall/t-flex-cad18-applications
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | # info_ru: Приложения для T-FLEX CAD 18 (T-FLEX Анализ 18, T-FLEX Динамика 18, T-FLEX Детали машин 18, T-FLEX Раскрой 18, T-FLEX VR 18, T-FLEX Печатные платы 18) | ||||||
|  | ######################################################################## | ||||||
|  | export PROG_URL="https://www.tflexcad.ru" | ||||||
|  | export PROG_NAME="Приложения для T-FLEX CAD 18" | ||||||
|  | export PROG_ICON="tflexcad" | ||||||
|  | export WH_WINDOWS_VER="10" | ||||||
|  | export WH_WINE_USE="wine_wh_tflex_10-9_amd64" | ||||||
|  | export BASE_PFX="tflex_pfx_x64_v03" | ||||||
|  | export WINEARCH="win64" | ||||||
|  | export WINEPREFIX="tflex" | ||||||
|  | export WH_XDG_OPEN="log" | ||||||
|  | export WH_USE_MESA_GL_OVERRIDE="1" | ||||||
|  |  | ||||||
|  | check_prefix_var | ||||||
|  | if [[ ! -f "$WINEPREFIX/drive_c/Program Files/T-FLEX CAD 18/Program/TFlexCad.exe" ]] | ||||||
|  | then fatal "Изначально установите T-FLEX CAD 18." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | BASE_URL="https://www.tflex.ru/downloads/V18" | ||||||
|  | FILES=( | ||||||
|  |     "T-FLEX Analysis 18.zip" | ||||||
|  |     "T-FLEX Dynamics 18.zip" | ||||||
|  |     "T-FLEX Machinery 18.zip" | ||||||
|  |     "T-FLEX Nesting 18.zip" | ||||||
|  |     "T-FLEX VR 18.zip" | ||||||
|  |     "T-FLEX Circuits 18.zip" | ||||||
|  | ) | ||||||
|  | UNPACK_APP="${WH_TMP_DIR}/unpack_applications" | ||||||
|  |  | ||||||
|  | prepair_wine | ||||||
|  |  | ||||||
|  | # Скачивание всех файлов | ||||||
|  | for file_name in "${FILES[@]}" ; do | ||||||
|  |     local output="${WH_TMP_DIR}/${file_name// /_}" | ||||||
|  |  | ||||||
|  |     if try_download "$BASE_URL/$file_name" "$output" ; then | ||||||
|  |         unpack "$output" "${UNPACK_APP}" | ||||||
|  |     fi | ||||||
|  |     try_remove_file "$output" | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Установка .msi файлов | ||||||
|  | for msi_file in "${UNPACK_APP}"/*/*.msi ; do | ||||||
|  |     if [[ -f "$msi_file" ]] ; then | ||||||
|  |         wine_run_install "$msi_file" /q | ||||||
|  |     else | ||||||
|  |         fatal "Нет .msi файлов для установки в ${UNPACK_APP}/*." | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | try_remove_dir "${UNPACK_APP}" | ||||||
							
								
								
									
										49
									
								
								autoinstall/t-flex-cad18-resources
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								autoinstall/t-flex-cad18-resources
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | # info_ru: Обучающие материалы, примеры, бесплатные библиотеки для T-FLEX CAD 18 (Учебное пособие 18, Стандартные элементы 18, Примеры 18) | ||||||
|  | ######################################################################## | ||||||
|  | export PROG_URL="https://www.tflexcad.ru" | ||||||
|  | export PROG_NAME="Ресурсы для T-FLEX CAD 18" | ||||||
|  | export PROG_ICON="tflexcad" | ||||||
|  | export WH_WINDOWS_VER="10" | ||||||
|  | export WH_WINE_USE="wine_wh_tflex_10-9_amd64" | ||||||
|  | export BASE_PFX="tflex_pfx_x64_v03" | ||||||
|  | export WINEARCH="win64" | ||||||
|  | export WINEPREFIX="tflex" | ||||||
|  | export WH_XDG_OPEN="log" | ||||||
|  | export WH_USE_MESA_GL_OVERRIDE="1" | ||||||
|  |  | ||||||
|  | check_prefix_var | ||||||
|  | if [[ ! -f "$WINEPREFIX/drive_c/Program Files/T-FLEX CAD 18/Program/TFlexCad.exe" ]] | ||||||
|  | then fatal "Изначально установите T-FLEX CAD 18." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | BASE_URL="https://www.tflex.ru/downloads/V18" | ||||||
|  | FILES=( | ||||||
|  |     "T-FLEX Tutorial 18.zip" | ||||||
|  |     "Standard parts 18.zip" | ||||||
|  |     "Examples 18.zip" | ||||||
|  | ) | ||||||
|  | UNPACK_RESOURCES="${WH_TMP_DIR}/unpack_resources" | ||||||
|  |  | ||||||
|  | prepair_wine | ||||||
|  |  | ||||||
|  | # Скачивание всех файлов | ||||||
|  | for file_name in "${FILES[@]}" ; do | ||||||
|  |     local output="${WH_TMP_DIR}/${file_name// /_}" | ||||||
|  |  | ||||||
|  |     if try_download "$BASE_URL/$file_name" "$output" ; then | ||||||
|  |         unpack "$output" "$UNPACK_RESOURCES" | ||||||
|  |     fi | ||||||
|  |     try_remove_file "$output" | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Установка .msi файлов | ||||||
|  | for msi_file in "${UNPACK_RESOURCES}"/*/*.msi ; do | ||||||
|  |     if [[ -f "$msi_file" ]] ; then | ||||||
|  |         wine_run_install "$msi_file" /q | ||||||
|  |     else | ||||||
|  |         fatal "Нет .msi файлов для установки в ${UNPACK_RESOURCES}/unpack_dop/*." | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | try_remove_dir "${UNPACK_RESOURCES}" | ||||||
							
								
								
									
										34
									
								
								autoinstall/t-flex-cad2d+18
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								autoinstall/t-flex-cad2d+18
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | # info_ru: Профессиональная САПР, объединяющая в себе мощные параметрические возможности 2D и 3D-моделирования со средствами создания и оформления чертежей и конструкторской документации по ЕСКД. | ||||||
|  | ######################################################################## | ||||||
|  | export PROG_URL="https://www.tflexcad.ru" | ||||||
|  | export PROG_NAME="T-FLEX CAD 2D+ 18" | ||||||
|  | export PROG_ICON="tflexcad" | ||||||
|  | export WH_WINE_USE="wine_wh_tflex_10-9_amd64" | ||||||
|  | export BASE_PFX="tflex_pfx_x64_v03" | ||||||
|  | export WINEARCH="win64" | ||||||
|  | export WH_WINDOWS_VER="10" | ||||||
|  | export WINEPREFIX="tflex" | ||||||
|  | export WH_XDG_OPEN="log" | ||||||
|  | export WH_USE_MESA_GL_OVERRIDE="1" | ||||||
|  |  | ||||||
|  | # используем общий whdb файл для подготовки префикса и сервисов | ||||||
|  | # prepair_wine используется из файла настроек | ||||||
|  | source "$WH_DB_DIR/t-flex-cad.whdb" | ||||||
|  |  | ||||||
|  | # Программа T-FLEX CAD 2D+ 18 | ||||||
|  | AUTOINSTALL_ZIP="${WH_TMP_DIR}/T-FLEX CAD 2D+ 18.zip" | ||||||
|  | AUTOINSTALL_DIR="${WH_TMP_DIR}" | ||||||
|  | AUTOINSTALL_UNPACK="${WH_TMP_DIR}/T-FLEX CAD 2D+ 18" | ||||||
|  | AUTOINSTALL_EXE="${AUTOINSTALL_UNPACK}/T-FLEX CAD 2D+ 18.msi" | ||||||
|  |  | ||||||
|  | if try_download "https://www.tflex.ru/downloads/V18/T-FLEX%20CAD%202D+%2018.zip" "${AUTOINSTALL_ZIP}" ; then | ||||||
|  |     unpack "${AUTOINSTALL_ZIP}" "${AUTOINSTALL_DIR}" | ||||||
|  |     try_remove_file "${AUTOINSTALL_ZIP}" | ||||||
|  |  | ||||||
|  |     wine_run_install "${AUTOINSTALL_EXE}" /q | ||||||
|  |     try_remove_dir "${AUTOINSTALL_UNPACK}" | ||||||
|  |  | ||||||
|  |     WIN_FILE_EXEC="$DRIVE_C/Program Files/T-FLEX CAD 2D+ 18/Program/TFlexCad.exe" | ||||||
|  |     create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON" "TFlexCad2D" | ||||||
|  | fi | ||||||
							
								
								
									
										34
									
								
								autoinstall/t-flex-viewer18
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								autoinstall/t-flex-viewer18
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | # info_ru: Просмотр, печать и аннотирование документов T-FLEX CAD | ||||||
|  | ######################################################################## | ||||||
|  | export PROG_URL="https://www.tflexcad.ru" | ||||||
|  | export PROG_NAME="T-FLEX Viewer 18" | ||||||
|  | export PROG_ICON="tflexcad" | ||||||
|  | export WH_WINE_USE="wine_wh_tflex_10-9_amd64" | ||||||
|  | export BASE_PFX="tflex_pfx_x64_v03" | ||||||
|  | export WINEARCH="win64" | ||||||
|  | export WH_WINDOWS_VER="10" | ||||||
|  | export WINEPREFIX="tflex" | ||||||
|  | export WH_XDG_OPEN="log" | ||||||
|  | export WH_USE_MESA_GL_OVERRIDE="1" | ||||||
|  |  | ||||||
|  | # используем общий whdb файл для подготовки префикса и сервисов | ||||||
|  | # prepair_wine используется из файла настроек | ||||||
|  | source "$WH_DB_DIR/t-flex-cad.whdb" | ||||||
|  |  | ||||||
|  | # Программа T-FLEX Viewer | ||||||
|  | AUTOINSTALL_ZIP="${WH_TMP_DIR}/T-FLEX Viewer 18.zip" | ||||||
|  | AUTOINSTALL_DIR="${WH_TMP_DIR}" | ||||||
|  | AUTOINSTALL_UNPACK="${WH_TMP_DIR}/T-FLEX Viewer 18" | ||||||
|  | AUTOINSTALL_EXE="${AUTOINSTALL_UNPACK}/T-FLEX Viewer 18.msi" | ||||||
|  |  | ||||||
|  | if try_download "https://www.tflex.ru/downloads/V18/T-FLEX%20Viewer%2018.zip" "${AUTOINSTALL_ZIP}" ; then | ||||||
|  |     unpack "${AUTOINSTALL_ZIP}" "${AUTOINSTALL_DIR}" | ||||||
|  |     try_remove_file "${AUTOINSTALL_ZIP}" | ||||||
|  |  | ||||||
|  |     wine_run_install "${AUTOINSTALL_EXE}" /q | ||||||
|  |     try_remove_dir "${AUTOINSTALL_UNPACK}" | ||||||
|  |  | ||||||
|  |     WIN_FILE_EXEC="$DRIVE_C/Program Files/T-FLEX Viewer 18/Program/TFlexViewer.exe" | ||||||
|  |     create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON" | ||||||
|  | fi | ||||||
							
								
								
									
										
											BIN
										
									
								
								image/ksamu.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								image/ksamu.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 5.0 KiB | 
| @@ -208,12 +208,18 @@ dfb44ce5e5af7dba1686932c63d6b05e5dd6919a21c78130a7d1d0271b93958e  audiorecstatio | |||||||
| # create with wine_x_tkg_10-0_i586 (universal user: xuser) | # create with wine_x_tkg_10-0_i586 (universal user: xuser) | ||||||
| # winetricks arial dotnet7 dotnetdesktop7 renderer=gdi | # winetricks arial dotnet7 dotnetdesktop7 renderer=gdi | ||||||
|  |  | ||||||
| 4fa93434c5c15440014357323257ddcee7d28b94ad6a56bd6f5a08b33ae4c3cb  scadaoffice_pfx_x64_v04.tar.xz | 8c6312f2e4e846a98ca4a87fc90ee1917eb28d4caaddde040fb4d2dd05f8c0fe  scadaoffice_pfx_x64_v05.tar.xz | ||||||
| # create with wine-8.8-staging-amd64 | # 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 |  | ||||||
|  | # addons with ODBC, SSH, *.reg | ||||||
| 0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb  scadoffice_addons_v02.tar.xz | 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 | ||||||
|  | # create with wine_x_tkg_10-0_i586 (universal user: xuser) | ||||||
|  | # winetricks msxml6 msxml4 msxml3 riched30 msls31 riched20 msftedit richtx32 fontsmooth=gray | ||||||
|  | # + manuall installed riched32 | ||||||
|   | |||||||
| @@ -3,37 +3,33 @@ | |||||||
| ######################################################################## | ######################################################################## | ||||||
| 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="declaration" | export WINEPREFIX="nalog" | ||||||
| export PROG_NAME="Декларация" | export PROG_NAME="Декларация" | ||||||
| export PROG_ICON="declarac" | export PROG_ICON="declarac" | ||||||
| export BASE_PFX="defpfx_x86_v01" | export BASE_PFX="none" | ||||||
| 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" | ||||||
| 
 | 
 | ||||||
| DECL_FILE="${WH_TMP_DIR}/decl.html" | try_get_page "https://www.nalog.gov.ru/rn77/program/5961249/" | ||||||
| curl -o "$DECL_FILE" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "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) | ||||||
| 
 |  | ||||||
| if [[ ! -f "$DECL_FILE" ]] \ |  | ||||||
| || grep -q "Forbidden" "$DECL_FILE" |  | ||||||
| then |  | ||||||
|     fatal "The site page is unavailable or the request limit has been exceeded." |  | ||||||
| fi |  | ||||||
| 
 |  | ||||||
| VER_YEAR=$(grep -oP 'href="\K[^"]*.msi[^"]*' "$DECL_FILE" | awk -F'/' '{print $(NF-2)}' | head -n 1) |  | ||||||
| YEAR="${VER_YEAR//decl/}" | YEAR="${VER_YEAR//decl/}" | ||||||
| VER_MSI_SLASH=$(grep -oP 'href="\K[^"]*.msi[^"]*' "$DECL_FILE" | 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) | ||||||
| VER_MSI=$(grep -oP 'href="\K[^"]*.msi[^"]*' "$DECL_FILE" | awk -F'/' '{print $(NF)}' | head -n 1) | VER_MSI=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF)}' | head -n 1) | ||||||
| 
 |  | ||||||
| AUTOINSTALL_MSI="${WH_TMP_DIR}/${VER_MSI}" | AUTOINSTALL_MSI="${WH_TMP_DIR}/${VER_MSI}" | ||||||
| 
 | 
 | ||||||
| prepair_wine | prepair_wine | ||||||
| if try_download "https://data.nalog.ru/files/${VER_YEAR}/${VER_MSI_SLASH}/$VER_MSI" "${AUTOINSTALL_MSI}" ; then | if try_download "https://data.nalog.ru/files/${VER_YEAR}/${VER_MSI_SLASH}/${VER_MSI}" "${AUTOINSTALL_MSI}" ; then | ||||||
|     wine_run_install "${AUTOINSTALL_MSI}" "/q" |     wine_run_install "${AUTOINSTALL_MSI}" /q | ||||||
|     try_remove_file "${AUTOINSTALL_MSI}" |     try_remove_file "${AUTOINSTALL_MSI}" | ||||||
| 
 | 
 | ||||||
|     WIN_FILE_EXEC="$DRIVE_C/АО ГНИВЦ/Декларация ${YEAR}/Decl${YEAR}.exe" |     WIN_FILE_EXEC="$DRIVE_C/АО ГНИВЦ/Декларация ${YEAR}/Decl${YEAR}.exe" | ||||||
|     create_desktop "$PROG_NAME $YEAR" "$WIN_FILE_EXEC" "$PROG_ICON" |     create_desktop "$PROG_NAME $YEAR" "$WIN_FILE_EXEC" "$PROG_ICON" | ||||||
|     remove_desktop "Декларация $((YEAR - 1))" |  | ||||||
| fi |  | ||||||
| 
 | 
 | ||||||
|  |     # Удаляем ярлык предыдущей версии | ||||||
|  |     remove_desktop "Декларация $((YEAR - 1))" | ||||||
|  | 
 | ||||||
|  |     print_info "Программа Декларация $YEAR успешно установлена" | ||||||
|  | else | ||||||
|  |     fatal "Не удалось скачать установочный файл" | ||||||
|  | fi | ||||||
							
								
								
									
										17
									
								
								testinstall/ksamu
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								testinstall/ksamu
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  | # info_ru: Программа “КСАМУ”. | ||||||
|  | ######################################################################## | ||||||
|  | export PROG_URL="https://docs.medicine-it.ru/" | ||||||
|  | export WH_WINE_USE="wine_x_tkg_10-0_amd64" | ||||||
|  | export WINEPREFIX="ksamu" | ||||||
|  | export PROG_NAME="КСАМУ" | ||||||
|  | export PROG_ICON="ksamu" | ||||||
|  | export BASE_PFX="ksamu_pfx_x64_v01" | ||||||
|  | export WINEARCH="win64" | ||||||
|  | export INSTALL_DLL="richtx32 riched20 riched30 msls31 msftedit msxml6 msxml3 msxml4 fontsmooth=gray" #riched32 | ||||||
|  | export WH_USE_EXTRA_FONTS="1" | ||||||
|  | export WH_WINDOWS_VER="7" | ||||||
|  |  | ||||||
|  | prepair_wine | ||||||
|  |  | ||||||
|  | create_desktop "$PROG_NAME" "$DRIVE_C/KSAMU/KSAMU.exe" "$PROG_ICON" | ||||||
| @@ -6,30 +6,22 @@ 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="defpfx_x86_v01" | export BASE_PFX="none" | ||||||
| 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" | ||||||
| 
 | 
 | ||||||
| NPUL_FILE="${WH_TMP_DIR}/npul.html" | try_get_page "https://data.nalog.ru/rn77/program/5961229/" | ||||||
| curl -o "$NPUL_FILE" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "https://www.nalog.gov.ru/rn77/program/5961229/" | VER_MSI=$(read_page | grep -oP 'NalogUL\d+\.msi' | tail -1 | grep -oP '\d+') | ||||||
| 
 | VER_MSI_URL="${VER_MSI:0:1}.${VER_MSI:1}"  # 492 → 4.92 | ||||||
| if [[ ! -f "$NPUL_FILE" ]] \ | VER_EXE=$(read_page | grep -oP 'NalogUL\d+\.exe' | tail -1 | grep -oP '\d+') | ||||||
| || grep -q "Forbidden" "$NPUL_FILE" | VER_EXE_URL="${VER_EXE:0:1}.${VER_EXE:1:2}.${VER_EXE:3}"  # 4924 → 4.92.4 | ||||||
| then |  | ||||||
|     fatal "Страница сайта не доступна, или превышено количество запросов к странице." |  | ||||||
| fi |  | ||||||
| 
 |  | ||||||
| VER_MSI=$(grep -oP 'NalogUL\K[0-9.]+(?=\.msi)' "$NPUL_FILE" | tail -n 1) |  | ||||||
| VER_MSI_SLASH=$(grep -oP '[0-9]+\.[0-9]+/NalogUL[0-9]+\.msi' "$NPUL_FILE" | tail -n 1) |  | ||||||
| VER_EXE=$(grep -oP 'NalogUL\K[0-9.]+(?=\.exe)' "$NPUL_FILE" | tail -n 1) |  | ||||||
| VER_EXE_SLASH=$(grep -oP '[0-9]+\.[0-9]+\.[0-9]+/NalogUL[0-9]+\.exe' "$NPUL_FILE" | tail -n 1) |  | ||||||
| 
 | 
 | ||||||
| AUTOINSTALL_MSI="${WH_TMP_DIR}/NalogUL${VER_MSI}.msi" | AUTOINSTALL_MSI="${WH_TMP_DIR}/NalogUL${VER_MSI}.msi" | ||||||
| AUTOINSTALL_EXE="${WH_TMP_DIR}/NalogUL${VER_EXE}.exe" | AUTOINSTALL_EXE="${WH_TMP_DIR}/NalogUL${VER_EXE}.exe" | ||||||
| 
 | 
 | ||||||
| prepair_wine | prepair_wine | ||||||
| if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_SLASH}" "${AUTOINSTALL_MSI}" ; then | if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_URL}/NalogUL${VER_MSI}.msi" "${AUTOINSTALL_MSI}" ; then | ||||||
|     wine_run_install "${AUTOINSTALL_MSI}" /quiet INSTALLDIR="c:\npul" |     wine_run_install "${AUTOINSTALL_MSI}" /quiet INSTALLDIR="c:\npul" | ||||||
|     try_remove_file "${AUTOINSTALL_MSI}" |     try_remove_file "${AUTOINSTALL_MSI}" | ||||||
| 
 | 
 | ||||||
| @@ -42,7 +34,7 @@ if try_download "https://data.nalog.ru/files/nalul/${VER_MSI_SLASH}" "${AUTOINST | |||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if [[ -n "$VER_EXE" ]] \ | if [[ -n "$VER_EXE" ]] \ | ||||||
| && try_download "https://data.nalog.ru/files/nalul/${VER_EXE_SLASH}" "${AUTOINSTALL_EXE}" | && try_download "https://data.nalog.ru/files/nalul/${VER_EXE_URL}/NalogUL${VER_EXE}.exe" "${AUTOINSTALL_EXE}" | ||||||
| then | then | ||||||
|     wine_run_install "${AUTOINSTALL_EXE}" "/SILENT" |     wine_run_install "${AUTOINSTALL_EXE}" "/SILENT" | ||||||
|     try_remove_file "${AUTOINSTALL_EXE}" |     try_remove_file "${AUTOINSTALL_EXE}" | ||||||
| @@ -53,4 +45,3 @@ fi | |||||||
| touch "$DRIVE_C/npul/INPUTDOC/linux.txt" | touch "$DRIVE_C/npul/INPUTDOC/linux.txt" | ||||||
| WIN_FILE_EXEC="$DRIVE_C/npul/INPUTDOC/inputdoc.exe" | WIN_FILE_EXEC="$DRIVE_C/npul/INPUTDOC/inputdoc.exe" | ||||||
| create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON" | create_desktop "$PROG_NAME" "$WIN_FILE_EXEC" "$PROG_ICON" | ||||||
| try_remove_file "$NPUL_FILE" |  | ||||||
| @@ -2,24 +2,26 @@ | |||||||
| # info_ru: Подготовка документов для государственной регистрации (ППДГР) | # info_ru: Подготовка документов для государственной регистрации (ППДГР) | ||||||
| ######################################################################## | ######################################################################## | ||||||
| export PROG_URL="https://www.nalog.gov.ru" | export PROG_URL="https://www.nalog.gov.ru" | ||||||
| export AUTOINSTALL_EXE="${WH_TMP_DIR}/SetupPPDGR2.msi" |  | ||||||
| export WH_WINE_USE="wine_x_tkg_10-0_amd64" | export WH_WINE_USE="wine_x_tkg_10-0_amd64" | ||||||
| export WINEPREFIX="ppdgr2" | export WINEPREFIX="nalog" | ||||||
| export PROG_NAME="ППДГР-2" | export PROG_NAME="ППДГР-2" | ||||||
| # export PROG_VERSION="" |  | ||||||
| export PROG_ICON="ppdgr" | export PROG_ICON="ppdgr" | ||||||
| # export ADD_MIME_TYPE="" | 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" | var_winedlloverride_update "msxml4=b,wininet=b" | ||||||
|  | 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/5961277/" | ||||||
|  | VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.msi[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1) | ||||||
|  | AUTOINSTALL_EXE="${WH_TMP_DIR}/SetupPPDGR2.msi" | ||||||
| 
 | 
 | ||||||
| prepair_wine | prepair_wine | ||||||
| if try_download "https://data.nalog.ru/files/ppdgr/2.7.0/SetupPPDGR2.msi" "${AUTOINSTALL_EXE}" ; then | if try_download "https://data.nalog.ru/files/ppdgr/${VER_MSI_SLASH}/SetupPPDGR2.msi" "${AUTOINSTALL_EXE}" ; then | ||||||
|     wine_run_install "${AUTOINSTALL_EXE}" /q |     wine_run_install "${AUTOINSTALL_EXE}" /q | ||||||
|     try_remove_file "${AUTOINSTALL_EXE}" |     try_remove_file "${AUTOINSTALL_EXE}" | ||||||
| 
 | 
 | ||||||
|     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 | ||||||
| @@ -1,12 +1,12 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
| # info_ru: SCAD Office — это программный комплекс для расчёта строительных конструкций, с дополнением Apache OpenOffice. Apache OpenOffice - пакет офисного программного обеспечения для обработки текстов, электронных таблиц, презентаций, графики, баз данных и многого другого. | # info_ru: SCAD Office — это программный комплекс для расчёта строительных конструкций. | ||||||
| ######################################################################## | ######################################################################## | ||||||
| export PROG_URL="https://scadoffice.ru" | export PROG_URL="https://scadoffice.ru" | ||||||
| export WH_WINE_USE="wine_x_tkg_10-0_amd64" | export WH_WINE_USE="wine_x_tkg_10-0_amd64" | ||||||
| export WINEPREFIX="scadoffice" | export WINEPREFIX="scadoffice" | ||||||
| export PROG_NAME="SCAD Office" | export PROG_NAME="SCAD Office" | ||||||
| export PROG_ICON="scadoffice" | export PROG_ICON="scadoffice" | ||||||
| export BASE_PFX="scadaoffice_pfx_x64_v04" | export BASE_PFX="scadaoffice_pfx_x64_v05" | ||||||
| export WH_WINDOWS_VER="10" | export WH_WINDOWS_VER="10" | ||||||
| export WINEARCH="win64" | export WINEARCH="win64" | ||||||
| export INSTALL_DLL="dotnet20 dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6" | export INSTALL_DLL="dotnet20 dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6" | ||||||
| @@ -32,39 +32,39 @@ if [[ -n $2 ]] ; then | |||||||
|     fi |     fi | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if [[ $BASE_PFX == "none" ]] ; then | print_info "Установка дополнительных компонентов..." | ||||||
|     print_info "Установка дополнительных компонентов..." |  | ||||||
| 
 | 
 | ||||||
|     ADDONS_PACK="${WH_TMP_DIR}/$(basename "$SCADOFFICE_ADDONS_URL")" | ADDONS_PACK="${WH_TMP_DIR}/$(basename "$SCADOFFICE_ADDONS_URL")" | ||||||
|     ADDONS_PATH="${WH_TMP_DIR}/scadoffice_addons" | ADDONS_PATH="${WH_TMP_DIR}/scadoffice_addons" | ||||||
| 
 | 
 | ||||||
|     ADDONS_PATH_REG="${ADDONS_PATH}/REG" | ADDONS_PATH_REG="${ADDONS_PATH}/REG" | ||||||
|     ADDONS_PATH_MDAC="${ADDONS_PATH}/mdac64" | ADDONS_PATH_MDAC="${ADDONS_PATH}/mdac64" | ||||||
|     ADDONS_PATH_OPENSSH="${ADDONS_PATH}/OpenSSH" | ADDONS_PATH_OPENSSH="${ADDONS_PATH}/OpenSSH" | ||||||
| 
 | 
 | ||||||
|     if try_download "$SCADOFFICE_ADDONS_URL" "${ADDONS_PACK}" ; then | if try_download "$SCADOFFICE_ADDONS_URL" "${ADDONS_PACK}" ; then | ||||||
|     create_new_dir "${ADDONS_PATH}" |     create_new_dir "${ADDONS_PATH}" | ||||||
|     unpack "${ADDONS_PACK}" "${ADDONS_PATH}" |     unpack "${ADDONS_PACK}" "${ADDONS_PATH}" | ||||||
|         wine_run regedit "${ADDONS_PATH_REG}"/*.reg |     wine_run "${ADDONS_PATH_REG}"/*.reg | ||||||
| 
 | 
 | ||||||
|     # Установка ODBC |     # Установка ODBC | ||||||
|     rm -fR "$DRIVE_C/Program Files (x86)/Common Files/System" |     rm -fR "$DRIVE_C/Program Files (x86)/Common Files/System" | ||||||
|     cp -r "${ADDONS_PATH_MDAC}/System" "$DRIVE_C/Program Files (x86)/Common Files/System" |     cp -r "${ADDONS_PATH_MDAC}/System" "$DRIVE_C/Program Files (x86)/Common Files/System" | ||||||
|     cp -r "${ADDONS_PATH_MDAC}"/*.* "$DRIVE_C/windows/system32/" |     cp -r "${ADDONS_PATH_MDAC}"/*.* "$DRIVE_C/windows/system32/" | ||||||
|         wine_run regedit "${ADDONS_PATH_MDAC}"/*.reg |     wine_run "${ADDONS_PATH_MDAC}"/*.reg | ||||||
| 
 | 
 | ||||||
|     # Установка SSH |     # Установка SSH | ||||||
|     cp -r "${ADDONS_PATH_OPENSSH}" "$DRIVE_C/windows/system32/" |     cp -r "${ADDONS_PATH_OPENSSH}" "$DRIVE_C/windows/system32/" | ||||||
| 
 | 
 | ||||||
|     try_remove_dir "$ADDONS_PATH" |     try_remove_dir "$ADDONS_PATH" | ||||||
|     try_remove_file "$ADDONS_PACK" |     try_remove_file "$ADDONS_PACK" | ||||||
|     fi |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if try_download "https://scadhelp.ru/files/10/download" "${AUTOINSTALL_EXE}" ; then | if try_download "https://scadhelp.ru/files/10/download" "${AUTOINSTALL_EXE}" ; then | ||||||
|     create_new_dir "$DRIVE_C/SDATA" |     create_new_dir "$DRIVE_C/SDATA" | ||||||
|     create_new_dir "$DRIVE_C/SWORK" |     create_new_dir "$DRIVE_C/SWORK" | ||||||
|     wine_run_install "${AUTOINSTALL_EXE}" /auto /hide |     # временно запрещаем запуск hasplms.exe, hasplmv.exe для успешного завершения установки | ||||||
|  |     tmp_winedlloverride_update "hasplms.exe,hasplmv.exe=d" | ||||||
|  |     wine_run_install "$AUTOINSTALL_EXE" | ||||||
|     try_remove_file "$AUTOINSTALL_EXE" |     try_remove_file "$AUTOINSTALL_EXE" | ||||||
| 
 | 
 | ||||||
|     # Определение всех программ, значков и исполняемых файлов |     # Определение всех программ, значков и исполняемых файлов | ||||||
| @@ -2,20 +2,21 @@ | |||||||
| # info_ru: Справочник кодов обозначения налоговых органов для целей учета налогоплательщиков | # info_ru: Справочник кодов обозначения налоговых органов для целей учета налогоплательщиков | ||||||
| ######################################################################## | ######################################################################## | ||||||
| export PROG_URL="https://www.nalog.gov.ru" | export PROG_URL="https://www.nalog.gov.ru" | ||||||
| export AUTOINSTALL_EXE="${WH_TMP_DIR}/soun_ins.exe" |  | ||||||
| export WH_WINE_USE="wine_x_tkg_10-0_amd64" | export WH_WINE_USE="wine_x_tkg_10-0_amd64" | ||||||
| export WINEPREFIX="soun" | export WINEPREFIX="nalog" | ||||||
| export PROG_NAME="СОУН" | export PROG_NAME="СОУН" | ||||||
| # export PROG_VERSION="" |  | ||||||
| export PROG_ICON="soun" | export PROG_ICON="soun" | ||||||
| # export ADD_MIME_TYPE="" | export BASE_PFX="none" | ||||||
| export BASE_PFX="defpfx_x86_v01" |  | ||||||
| export WINEARCH="win32" | export WINEARCH="win32" | ||||||
| export INSTALL_DLL="corefonts" |  | ||||||
| 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/5961268/" | ||||||
|  | VER_MSI_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | head -n 1) | ||||||
|  | AUTOINSTALL_EXE="${WH_TMP_DIR}/soun_ins.exe" | ||||||
| 
 | 
 | ||||||
| prepair_wine | prepair_wine | ||||||
| if try_download "https://data.nalog.ru/files/Soun/2.6.2/soun_ins.exe" "${AUTOINSTALL_EXE}" ; then | if try_download "https://data.nalog.ru/files/Soun/${VER_MSI_SLASH}/soun_ins.exe" "${AUTOINSTALL_EXE}" ; then | ||||||
|     # TODO: Тихий режим или предупреждение |     # TODO: Тихий режим или предупреждение | ||||||
|     wine_run_install "${AUTOINSTALL_EXE}" |     wine_run_install "${AUTOINSTALL_EXE}" | ||||||
|     try_remove_file "${AUTOINSTALL_EXE}" |     try_remove_file "${AUTOINSTALL_EXE}" | ||||||
| @@ -2,22 +2,23 @@ | |||||||
| # info_ru: Программа проверки файлов на соответствие форматам представления в электронном виде налоговых деклараций, бухгалтерской отчетности. | # info_ru: Программа проверки файлов на соответствие форматам представления в электронном виде налоговых деклараций, бухгалтерской отчетности. | ||||||
| ######################################################################## | ######################################################################## | ||||||
| export PROG_URL="https://www.nalog.gov.ru" | export PROG_URL="https://www.nalog.gov.ru" | ||||||
| export LAUNCH_PARAMETERS="/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" |  | ||||||
| export AUTOINSTALL_EXE="${WH_TMP_DIR}/tester2269.exe" |  | ||||||
| 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="nalog" | ||||||
| export PROG_NAME="Тестер" | export PROG_NAME="Тестер" | ||||||
| # export PROG_VERSION="" |  | ||||||
| export PROG_ICON="tester" | export PROG_ICON="tester" | ||||||
| # export ADD_MIME_TYPE="" | 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/" | ||||||
|  | VER_EXE_SLASH=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF-1)}' | tail -n 1) | ||||||
|  | VER_EXE=$(read_page | grep -oP 'href="\K[^"]*.exe[^"]*' | awk -F'/' '{print $(NF)}' | tail -n 1) | ||||||
|  | AUTOINSTALL_EXE="${WH_TMP_DIR}/${VER_EXE}" | ||||||
| 
 | 
 | ||||||
| prepair_wine | prepair_wine | ||||||
| if try_download "https://data.nalog.ru/files/tester/2.269/tester2269.exe" "${AUTOINSTALL_EXE}" ; then | if try_download "https://data.nalog.ru/files/tester/${VER_EXE_SLASH}/${VER_EXE}" "${AUTOINSTALL_EXE}" ; then | ||||||
|     wine_run_install "${AUTOINSTALL_EXE}" |     wine_run_install "${AUTOINSTALL_EXE}" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- | ||||||
|     try_remove_file "${AUTOINSTALL_EXE}" |     try_remove_file "${AUTOINSTALL_EXE}" | ||||||
| 
 | 
 | ||||||
|     WIN_FILE_EXEC="$DRIVE_C/Tester/tester.exe" |     WIN_FILE_EXEC="$DRIVE_C/Tester/tester.exe" | ||||||
							
								
								
									
										263
									
								
								winehelper
									
									
									
									
									
								
							
							
						
						
									
										263
									
								
								winehelper
									
									
									
									
									
								
							| @@ -7,7 +7,7 @@ if [[ $(id -u) -eq 0 ]] ; then | |||||||
| fi | fi | ||||||
|  |  | ||||||
| ##### DEFAULT PATH ##### | ##### DEFAULT PATH ##### | ||||||
| export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH LICENSE_FILE AGREEMENT THIRD_PARTY_FILE | export SCRIPT_NAME USER_WORK_PATH RUN_SCRIPT DATA_PATH CHANGELOG_FILE WH_ICON_PATH LICENSE_FILE AGREEMENT THIRD_PARTY_FILE WH_ICON_TRAY GENERAL | ||||||
|  |  | ||||||
| SCRIPT_NAME="$(basename "$0")" | SCRIPT_NAME="$(basename "$0")" | ||||||
| if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then | if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then | ||||||
| @@ -17,10 +17,12 @@ if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then | |||||||
|     RUN_SCRIPT="/usr/bin/$SCRIPT_NAME" |     RUN_SCRIPT="/usr/bin/$SCRIPT_NAME" | ||||||
|     DATA_PATH="/usr/share/$SCRIPT_NAME" |     DATA_PATH="/usr/share/$SCRIPT_NAME" | ||||||
|     WH_ICON_PATH="/usr/share/icons/hicolor/scalable/apps/winehelper.svg" |     WH_ICON_PATH="/usr/share/icons/hicolor/scalable/apps/winehelper.svg" | ||||||
|  |     WH_ICON_TRAY="/usr/share/icons/hicolor/symbolic/apps/winehelper-symbolic.svg" | ||||||
|     CHANGELOG_FILE="/usr/share/doc/winehelper-$WH_VERSION/CHANGELOG" |     CHANGELOG_FILE="/usr/share/doc/winehelper-$WH_VERSION/CHANGELOG" | ||||||
|     LICENSE_FILE="/usr/share/doc/winehelper-$WH_VERSION/LICENSE" |     LICENSE_FILE="/usr/share/doc/winehelper-$WH_VERSION/LICENSE" | ||||||
|     AGREEMENT="/usr/share/doc/winehelper-$WH_VERSION/LICENSE_AGREEMENT" |     AGREEMENT="/usr/share/doc/winehelper-$WH_VERSION/LICENSE_AGREEMENT" | ||||||
|     THIRD_PARTY_FILE="/usr/share/doc/winehelper-$WH_VERSION/THIRD-PARTY" |     THIRD_PARTY_FILE="/usr/share/doc/winehelper-$WH_VERSION/THIRD-PARTY" | ||||||
|  |     GENERAL="/usr/share/doc/winehelper-$WH_VERSION/GENERAL" | ||||||
| else | else | ||||||
|     # переменные для тестового запуска WineHelper из репозитория |     # переменные для тестового запуска WineHelper из репозитория | ||||||
|     USER_WORK_PATH="$HOME/test-$SCRIPT_NAME" |     USER_WORK_PATH="$HOME/test-$SCRIPT_NAME" | ||||||
| @@ -28,9 +30,12 @@ else | |||||||
|     DATA_PATH="$(dirname "$RUN_SCRIPT")" |     DATA_PATH="$(dirname "$RUN_SCRIPT")" | ||||||
|     CHANGELOG_FILE="$DATA_PATH/CHANGELOG" |     CHANGELOG_FILE="$DATA_PATH/CHANGELOG" | ||||||
|     WH_ICON_PATH="$DATA_PATH/image/gui/winehelper-devel.svg" |     WH_ICON_PATH="$DATA_PATH/image/gui/winehelper-devel.svg" | ||||||
|  |     WH_ICON_TRAY="$DATA_PATH/image/gui/winehelper-symbolic.svg" | ||||||
|     LICENSE_FILE="$DATA_PATH/LICENSE" |     LICENSE_FILE="$DATA_PATH/LICENSE" | ||||||
|     AGREEMENT="$DATA_PATH/LICENSE_AGREEMENT" |     AGREEMENT="$DATA_PATH/LICENSE_AGREEMENT" | ||||||
|     THIRD_PARTY_FILE="$DATA_PATH/THIRD-PARTY" |     THIRD_PARTY_FILE="$DATA_PATH/THIRD-PARTY" | ||||||
|  |     GENERAL="$DATA_PATH/GENERAL" | ||||||
|  |     WH_DEVEL="1" | ||||||
|  |  | ||||||
|     # минимальная проверка синтаксиса скриптов |     # минимальная проверка синтаксиса скриптов | ||||||
|     for self_check_script in "$RUN_SCRIPT" \ |     for self_check_script in "$RUN_SCRIPT" \ | ||||||
| @@ -49,21 +54,21 @@ fi | |||||||
|  |  | ||||||
| ##### MESSAGES FUNCTIONS ##### | ##### MESSAGES FUNCTIONS ##### | ||||||
| if [[ $WH_USE_GUI != "1" ]] ; then | if [[ $WH_USE_GUI != "1" ]] ; then | ||||||
|     print_error () { printf "\E[31m%s Ошибка: $@ %s\e[0m\n" ;} |     print_error () { printf "\E[31m%s Ошибка: $* %s\e[0m\n" ;} | ||||||
|     print_warning () { printf "\E[33m%s Предупреждение: $@ %s\e[0m\n" ;} |     print_warning () { printf "\E[33m%s Предупреждение: $* %s\e[0m\n" ;} | ||||||
|     print_info () { printf "\E[36m%s Информация: \"$@\" %s\e[0m\n" ;} |     print_info () { printf "\E[36m%s Информация: \"$*\" %s\e[0m\n" ;} | ||||||
|     print_ok () { printf "\E[35m%s Успех: $@ %s\e[0m\n" ;} |     print_ok () { printf "\E[35m%s Успех: $* %s\e[0m\n" ;} | ||||||
| else | else | ||||||
|     print_error () { echo -e "Ошибка: $@" ;} |     print_error () { echo -e "Ошибка: $*" ;} | ||||||
|     print_warning () { echo -e "Предупреждение: $@" ;} |     print_warning () { echo -e "Предупреждение: $*" ;} | ||||||
|     print_info () { echo -e "Информация: \"$@\"" ;} |     print_info () { echo -e "Информация: \"$*\"" ;} | ||||||
|     print_ok () { echo -e "Успех: $@" ;} |     print_ok () { echo -e "Успех: $*" ;} | ||||||
| fi | fi | ||||||
|  |  | ||||||
| print_var () { for vp in $@ ; do echo "${vp}=${!vp}" ; done ;} | print_var () { for vp in $@ ; do echo "${vp}=${!vp}" ; done ;} | ||||||
|  |  | ||||||
| fatal () { | fatal () { | ||||||
|     print_error "$@" |     print_error "$@ Аварийное завершение работы WineHelper!" | ||||||
|     [[ -n "$WINESERVER" ]] && "$WINESERVER" -w |     [[ -n "$WINESERVER" ]] && "$WINESERVER" -w | ||||||
|     exit 1 |     exit 1 | ||||||
| } | } | ||||||
| @@ -101,16 +106,6 @@ else | |||||||
|     check_variables DXVK_NVAPI_LOG_LEVEL "none" |     check_variables DXVK_NVAPI_LOG_LEVEL "none" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| if [[ $WINEDEBUG != "-all" ]] ; then |  | ||||||
|     log_dir="$HOME/winehelper_backup_log" |  | ||||||
|     mkdir -p "$log_dir" |  | ||||||
|     export LOG_FILE="$log_dir/winehelper.log" |  | ||||||
|     date > "$LOG_FILE" |  | ||||||
|     print_warning "Включен режим логирования работы WINE." |  | ||||||
|     print_warning "Лог будет сохранен по пути: $LOG_FILE" |  | ||||||
|     sleep 3 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| ##### WINETRICKS VERSION ##### | ##### WINETRICKS VERSION ##### | ||||||
| WINETRICKS_VERSION="20250102" | WINETRICKS_VERSION="20250102" | ||||||
|  |  | ||||||
| @@ -163,6 +158,7 @@ check_variables WH_WINDOWS_VER "10" | |||||||
| # check_variables WH_USE_GSTREAMER "1" | # check_variables WH_USE_GSTREAMER "1" | ||||||
| # check_variables WH_USE_D3D_EXTRAS "1" | # check_variables WH_USE_D3D_EXTRAS "1" | ||||||
| check_variables WH_USE_SHADER_CACHE "1" | check_variables WH_USE_SHADER_CACHE "1" | ||||||
|  | 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 "" | ||||||
|  |  | ||||||
| @@ -332,6 +328,7 @@ unpack () { | |||||||
| try_get_page () { | try_get_page () { | ||||||
|     local url_page="$1" |     local url_page="$1" | ||||||
|     export OUT_PAGE_TMP="${WH_TMP_DIR}/url_page.tmp" |     export OUT_PAGE_TMP="${WH_TMP_DIR}/url_page.tmp" | ||||||
|  |     try_remove_file "$OUT_PAGE_TMP" | ||||||
|     print_info "Чтение страницы: $url_page" |     print_info "Чтение страницы: $url_page" | ||||||
|     if ! curl -o "$OUT_PAGE_TMP" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "$url_page" \ |     if ! curl -o "$OUT_PAGE_TMP" -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" "$url_page" \ | ||||||
|     || grep -q "Forbidden" "$OUT_PAGE_TMP" |     || grep -q "Forbidden" "$OUT_PAGE_TMP" | ||||||
| @@ -348,7 +345,6 @@ read_page () { | |||||||
|     && [[ -f "$OUT_PAGE_TMP" ]] |     && [[ -f "$OUT_PAGE_TMP" ]] | ||||||
|     then |     then | ||||||
|         cat "$OUT_PAGE_TMP" |         cat "$OUT_PAGE_TMP" | ||||||
|         try_remove_file "$OUT_PAGE_TMP" |  | ||||||
|         unset OUT_PAGE_TMP |         unset OUT_PAGE_TMP | ||||||
|     else |     else | ||||||
|         echo "Используй try_get_page перед read_page" |         echo "Используй try_get_page перед read_page" | ||||||
| @@ -484,6 +480,10 @@ var_winedlloverride_update () { | |||||||
|     fi |     fi | ||||||
| } | } | ||||||
|  |  | ||||||
|  | tmp_winedlloverride_update () { | ||||||
|  |     var_winedlloverride_update "$1" | ||||||
|  | } | ||||||
|  |  | ||||||
| var_dxvk_config_update () { | var_dxvk_config_update () { | ||||||
|     if [[ -n "${DXVK_CONFIG}" ]] |     if [[ -n "${DXVK_CONFIG}" ]] | ||||||
|     then export DXVK_CONFIG="${1};${DXVK_CONFIG}" |     then export DXVK_CONFIG="${1};${DXVK_CONFIG}" | ||||||
| @@ -552,8 +552,6 @@ create_desktop () { | |||||||
|     if [[ -z "$name_desktop" ]] || [[ -z "$exe_file" ]] ; then |     if [[ -z "$name_desktop" ]] || [[ -z "$exe_file" ]] ; then | ||||||
|         fatal "Использование: $0 desktop \"Имя ярлыка\" \"/путь/к/файлу.exe\" [иконка|auto] [имя_desktop_файла]" |         fatal "Использование: $0 desktop \"Имя ярлыка\" \"/путь/к/файлу.exe\" [иконка|auto] [имя_desktop_файла]" | ||||||
|     elif [[ ! -f "$exe_file" ]] ; then |     elif [[ ! -f "$exe_file" ]] ; then | ||||||
|         print_warning "Для создания ярлыка не найден исполняемый файл: $exe_file" |  | ||||||
|  |  | ||||||
|         local BASENAME_EXE="$(basename "$exe_file")" |         local BASENAME_EXE="$(basename "$exe_file")" | ||||||
|         print_info "Запускаем поиск $BASENAME_EXE" |         print_info "Запускаем поиск $BASENAME_EXE" | ||||||
|         local FIND_PATH |         local FIND_PATH | ||||||
| @@ -564,9 +562,11 @@ create_desktop () { | |||||||
|         exe_file="$(find "$FIND_PATH" -type f -not -type l \ |         exe_file="$(find "$FIND_PATH" -type f -not -type l \ | ||||||
|                     -not -path "*/windows/*" -not -path "*/dosdevices/*" \ |                     -not -path "*/windows/*" -not -path "*/dosdevices/*" \ | ||||||
|                     -iname "$BASENAME_EXE")" |                     -iname "$BASENAME_EXE")" | ||||||
|         if [[ -z "$exe_file" ]] || [[ ! -f "$exe_file" ]] |         if [[ -z "$exe_file" ]] || [[ ! -f "$exe_file" ]] ; then | ||||||
|         then fatal "Для создания ярлыка не найден исполняемый файл: $BASENAME_EXE" |             print_error "Для создания ярлыка не найден исполняемый файл: $BASENAME_EXE" | ||||||
|         else print_ok "Исполняемый файл $BASENAME_EXE найден по пути: $(dirname "$exe_file")/" |             return 1 | ||||||
|  |         else | ||||||
|  |             print_ok "Исполняемый файл $BASENAME_EXE найден по пути: $(dirname "$exe_file")/" | ||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
| @@ -1286,7 +1286,8 @@ init_wineprefix () { | |||||||
|     echo "# переменные последнего использования префикса:" > "$WINEPREFIX/last.conf" |     echo "# переменные последнего использования префикса:" > "$WINEPREFIX/last.conf" | ||||||
|     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 | ||||||
|     do |     do | ||||||
|         echo "export $var=\"${!var}\"" >> "$WINEPREFIX/last.conf" |         echo "export $var=\"${!var}\"" >> "$WINEPREFIX/last.conf" | ||||||
|     done |     done | ||||||
| @@ -1347,23 +1348,25 @@ kill_wine () { | |||||||
| } | } | ||||||
|  |  | ||||||
| init_database () { | init_database () { | ||||||
|     WHDB_FILE="0" |     local whdb_file="0" | ||||||
|     if [[ -f "$WIN_FILE_EXEC" ]] ; then |     if [[ -n "$WIN_FILE_EXEC" ]] \ | ||||||
|  |     && [[ -f "$WIN_FILE_EXEC" ]] | ||||||
|  |     then | ||||||
|         WHDB="$(basename "$WIN_FILE_EXEC" .exe)" |         WHDB="$(basename "$WIN_FILE_EXEC" .exe)" | ||||||
|         if [[ -f "$WIN_FILE_EXEC".whdb ]] ; then |         if [[ -f "$WIN_FILE_EXEC".whdb ]] ; then | ||||||
|             WHDB_FILE="$WIN_FILE_EXEC".whdb |             whdb_file="$WIN_FILE_EXEC".whdb | ||||||
|         else |         else | ||||||
|             orig_IFS="$IFS" && IFS=$'\n' |             orig_IFS="$IFS" && IFS=$'\n' | ||||||
|             if WH_FIND_DB_FILE="$(grep -ilw "#$WHDB.exe" "$WH_DB_DIR"/* )" ; then |             if WH_FIND_DB_FILE="$(grep -ilw "#$WHDB.exe" "$WH_DB_DIR"/* )" ; then | ||||||
|                 WHDB_FILE="$WH_FIND_DB_FILE" |                 whdb_file="$WH_FIND_DB_FILE" | ||||||
|             fi |             fi | ||||||
|             IFS="$orig_IFS" |             IFS="$orig_IFS" | ||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     if [[ "$WHDB_FILE" != "0" ]] ; then |     if [[ "$whdb_file" != "0" ]] ; then | ||||||
|         print_info "Используется файл настроек: $WHDB_FILE" |         print_info "Используется файл настроек: $whdb_file" | ||||||
|         . "$WHDB_FILE" |         . "$whdb_file" | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     if check_prefix_var && [[ -f "$WINEPREFIX/last.conf" ]] ; then |     if check_prefix_var && [[ -f "$WINEPREFIX/last.conf" ]] ; then | ||||||
| @@ -1388,40 +1391,89 @@ prepair_wine () { | |||||||
|     [[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud" |     [[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | wine_regfile () { | ||||||
|  |     print_info "Запускаем команду: $WINELOADER $@" | ||||||
|  |     "$WINELOADER" "$@" && print_ok "Выполнено." || fatal "Не выполнено: $WINELOADER $@" | ||||||
|  |     wait_wineserver | ||||||
|  |  | ||||||
|  |     if [[ "$WINEARCH" == "win64" ]] \ | ||||||
|  |     && [[ -f "${WINELOADER}64" ]] | ||||||
|  |     then | ||||||
|  |         print_info "Запускаем команду: ${WINELOADER}64 $@" | ||||||
|  |         "${WINELOADER}64" "$@" && print_ok "Выполнено." || fatal "Не выполнено: ${WINELOADER}64 $@" | ||||||
|  |         wait_wineserver | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
| wine_run () { | wine_run () { | ||||||
|  |     local wh_add_args win_file_exec win_file_path win_file_name | ||||||
|  |  | ||||||
|  |     if [[ $1 =~ (winecfg|regedit|winefile|wineconsole) ]] ; then | ||||||
|  |         win_file_exec="$1" | ||||||
|  |         win_file_name="$win_file_exec" | ||||||
|  |         win_file_path="$DRIVE_C" | ||||||
|  |         wh_add_args="" | ||||||
|  |     elif [[ $1 =~ \.dll$ ]] ; then | ||||||
|  |         wine_regfile regsvr32 /s "$@" | ||||||
|  |         return 0 | ||||||
|  |     elif [[ -f "$1" ]] ; then | ||||||
|  |         win_file_exec="$(readlink -f "$1")" | ||||||
|  |         win_file_path="$(dirname "$win_file_exec")" | ||||||
|  |         win_file_name="$(basename "$win_file_exec")" | ||||||
|  |  | ||||||
|  |         case "${win_file_name,,}" in | ||||||
|  |             *.exe) wh_add_args="$WINE_WIN_START" ;; | ||||||
|  |             *.msi) wh_add_args="msiexec /i" ;; | ||||||
|  |             *.bat|*.cmd) wh_add_args="" ;; | ||||||
|  |             *.reg) wine_regfile regedit "$@" ; return 0 ;; | ||||||
|  |             *) fatal "Не удалось запустить файл $1. Проверьте расширение файла." ;; | ||||||
|  |         esac | ||||||
|  |  | ||||||
|         if [[ $WINEARCH == "win32" ]] \ |         if [[ $WINEARCH == "win32" ]] \ | ||||||
|     && file "$WIN_FILE_EXEC" | grep -q "x86-64" |         && file "$win_file_exec" | grep -q "x86-64" | ||||||
|         then fatal "Нельзя запустить 64-битное приложение в 32-битном префиксе!" |         then fatal "Нельзя запустить 64-битное приложение в 32-битном префиксе!" | ||||||
|         fi |         fi | ||||||
|  |  | ||||||
|     WIN_FILE_PATH="$(dirname "$WIN_FILE_EXEC")" |  | ||||||
|     [[ -d "$WIN_FILE_PATH" ]] && cd "$WIN_FILE_PATH" |  | ||||||
|  |  | ||||||
|     if [[ -n $LOG_FILE ]] && [[ -f "$LOG_FILE" ]] ; then |  | ||||||
|         echo "##### Основные переменные #####" | tee -a "$LOG_FILE" |  | ||||||
|         env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" | tee -a "$LOG_FILE" |  | ||||||
|  |  | ||||||
|         echo "##### Лог WINE #####" | tee -a "$LOG_FILE" |  | ||||||
|         $MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$LOG_FILE" |  | ||||||
|     else |     else | ||||||
|         $MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS |         fatal "Команда введена не правильно или не найден исполняемый файл $1" | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|  |     shift | ||||||
|  |     cd "$win_file_path" | ||||||
|  |  | ||||||
|  |     if [[ $WINEDEBUG != "-all" ]] ; then | ||||||
|  |         local log_dir log_file | ||||||
|  |         log_dir="$HOME/winehelper_backup_log" | ||||||
|  |         log_file="$log_dir/${PREFIX_NAME}_${win_file_name%.*}.log" | ||||||
|  |         create_new_dir "$log_dir" | ||||||
|  |         date > "$log_file" | ||||||
|  |  | ||||||
|  |         print_warning "Включен режим логирования работы WINE." | ||||||
|  |         print_warning "Лог будет сохранен по пути: $log_file" | ||||||
|  |  | ||||||
|  |         echo "##### Основные переменные #####" | tee -a "$log_file" | ||||||
|  |         env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" | tee -a "$log_file" | ||||||
|  |         echo "##### Лог WINE #####" | tee -a "$log_file" | ||||||
|  |  | ||||||
|  |         $MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$log_file" | ||||||
|  |     else | ||||||
|  |         $MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS | ||||||
|  |     fi | ||||||
|  |  | ||||||
|     wait_wineserver |     wait_wineserver | ||||||
|  |     cd "$DRIVE_C" | ||||||
| } | } | ||||||
|  |  | ||||||
| wine_run_install () { | wine_run_install () { | ||||||
|     print_info "Запускаем установку: $1." |     print_info "Запускаем установку: $1." | ||||||
|     if [[ "$INSTALL_MODE" == "manual" ]] |     case "$WH_INSTALL_MODE" in | ||||||
|     then print_warning "Рекомендуется не менять пути для установки приложения!" |         "manual") print_warning "Рекомендуется не менять пути для установки приложения!" ;; | ||||||
|     fi |           "test") print_warning "Установка приложения из списка экспериментальных скриптов." ;; | ||||||
|     [[ ! -f "$1" ]] && fatal "Нет файла для установки: $1" |  | ||||||
|     case "${1,,}" in |  | ||||||
|         *.exe) wine_run $WINE_WIN_START "$@" ;; |  | ||||||
|         *.msi) wine_run msiexec /i "$@" ;; |  | ||||||
|         *.bat|*.cmd) wine_run "$@" ;; |  | ||||||
|         *) fatal "Не удалось запустить файл $1. Проверьте расширение файла." ;; |  | ||||||
|     esac |     esac | ||||||
|     wait_wineserver |  | ||||||
|  |     if [[ ! -f "$1" ]] | ||||||
|  |     then fatal "Нет файла для установки: $1" | ||||||
|  |     else wine_run "$@" | ||||||
|  |     fi | ||||||
| } | } | ||||||
|  |  | ||||||
| run_autoinstall () { | run_autoinstall () { | ||||||
| @@ -1439,24 +1491,20 @@ run_autoinstall () { | |||||||
|     elif [[ -f "$WH_MANUALINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then |     elif [[ -f "$WH_MANUALINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then | ||||||
|         INSTALL_SCRIPT="$WH_MANUALINSTALL_DIR/$INSTALL_SCRIPT_NAME" |         INSTALL_SCRIPT="$WH_MANUALINSTALL_DIR/$INSTALL_SCRIPT_NAME" | ||||||
|         WH_INSTALL_MODE="manual" |         WH_INSTALL_MODE="manual" | ||||||
|     elif [[ -d "$WH_TESTINSTALL_DIR" ]] \ |     elif [[ -f "$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then | ||||||
|     && [[ -f "$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] |  | ||||||
|     then |  | ||||||
|         INSTALL_SCRIPT="$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME" |         INSTALL_SCRIPT="$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME" | ||||||
|         WH_INSTALL_MODE="test" |         WH_INSTALL_MODE="test" | ||||||
|     else |     else | ||||||
|         INSTALL_SCRIPT="0" |         INSTALL_SCRIPT="0" | ||||||
|     fi |     fi | ||||||
|     export INSTALL_SCRIPT INSTALL_MODE |     export INSTALL_SCRIPT WH_INSTALL_MODE | ||||||
|  |  | ||||||
|     if [[ $INSTALL_SCRIPT_NAME == "list" ]] || [[ -z "$INSTALL_SCRIPT_NAME" ]] ; then |     if [[ $INSTALL_SCRIPT_NAME == "list" ]] || [[ -z "$INSTALL_SCRIPT_NAME" ]] ; then | ||||||
|  |  | ||||||
|         list_install_scripts() { |         print_install_list () { | ||||||
|             local dir="$1" |             parse_install_scripts() { | ||||||
|             local title="$2" |                 local parse_dir="$1" | ||||||
|             [[ ! -d "$dir" ]] || [[ -z "$(ls -A "$dir" 2>/dev/null)" ]] && return |                 [[ ! -d "$parse_dir" ]] || [[ -z "$(ls -A "$parse_dir" 2>/dev/null)" ]] && return | ||||||
|  |  | ||||||
|             print_info "$title" |  | ||||||
|  |  | ||||||
|                 awk ' |                 awk ' | ||||||
|                     FNR==1 { |                     FNR==1 { | ||||||
| @@ -1473,12 +1521,19 @@ run_autoinstall () { | |||||||
|                             printf "\n%s - %s\n%s\n", filename, progname, info |                             printf "\n%s - %s\n%s\n", filename, progname, info | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|             ' "$dir"/* |                 ' "$parse_dir"/* | ||||||
|  |                 echo | ||||||
|  |             } | ||||||
|  |             print_info "Список программ с возможностью автоматической установки:" | ||||||
|  |             parse_install_scripts "$WH_AUTOINSTALL_DIR" | ||||||
|  |             print_info "Список программ с возможностью установки из существующего дистрибутива:" | ||||||
|  |             parse_install_scripts "$WH_MANUALINSTALL_DIR" | ||||||
|  |             print_warning "Программы из списка экспериментальных скриптов:" | ||||||
|  |             parse_install_scripts "$WH_TESTINSTALL_DIR" | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         list_install_scripts "$WH_AUTOINSTALL_DIR" "Список программ с возможностью автоматической установки:" |         print_install_list | less -R --use-color | ||||||
|         echo |  | ||||||
|         list_install_scripts "$WH_MANUALINSTALL_DIR" "Список программ с возможностью установки из существующего дистрибутива:" |  | ||||||
|     elif [[ "$INSTALL_SCRIPT" != "0" ]] ; then |     elif [[ "$INSTALL_SCRIPT" != "0" ]] ; then | ||||||
|         if [[ $WH_USE_GUI == "1" ]] \ |         if [[ $WH_USE_GUI == "1" ]] \ | ||||||
|         && [[ $(ps -o command= -p "$PPID" | awk '{print $2}') =~ "$DATA_PATH/winehelper_gui.py" ]] |         && [[ $(ps -o command= -p "$PPID" | awk '{print $2}') =~ "$DATA_PATH/winehelper_gui.py" ]] | ||||||
| @@ -1486,6 +1541,7 @@ run_autoinstall () { | |||||||
|         else print_license_agreement |         else print_license_agreement | ||||||
|         fi |         fi | ||||||
|         source "$INSTALL_SCRIPT" "$@" |         source "$INSTALL_SCRIPT" "$@" | ||||||
|  |         [[ -n $OUT_PAGE_TMP ]] && try_remove_file "$OUT_PAGE_TMP" | ||||||
|         print_info "Завершена установка $INSTALL_SCRIPT_NAME" |         print_info "Завершена установка $INSTALL_SCRIPT_NAME" | ||||||
|     else |     else | ||||||
|         fatal "Скрипт автоматической установки для $INSTALL_SCRIPT_NAME не найден!" |         fatal "Скрипт автоматической установки для $INSTALL_SCRIPT_NAME не найден!" | ||||||
| @@ -2150,20 +2206,21 @@ select_component_version() { | |||||||
| } | } | ||||||
|  |  | ||||||
| run_install_to_prefix() { | run_install_to_prefix() { | ||||||
|     export WINEPREFIX="$1" |     if [[ -z "$1" ]] || [[ -z "$2" ]] || [[ ! -f "$2" ]] ; then | ||||||
|     local WIN_FILE_EXEC="$2" |  | ||||||
|  |  | ||||||
|     if [[ -z "$WINEPREFIX" ]] || [[ -z "$WIN_FILE_EXEC" ]]; then |  | ||||||
|         fatal "Использование: $SCRIPT_NAME install-to-prefix <имя_префикса> <путь_к_установщику>" |         fatal "Использование: $SCRIPT_NAME install-to-prefix <имя_префикса> <путь_к_установщику>" | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|  |     export WINEPREFIX="$1" | ||||||
|  |     shift | ||||||
|  |  | ||||||
|     check_prefix_var |     check_prefix_var | ||||||
|     prepair_wine |     prepair_wine | ||||||
|     wine_run_install "$WIN_FILE_EXEC" |     wine_run "$@" | ||||||
| } | } | ||||||
|  |  | ||||||
| run_install_dxvk() { | run_install_dxvk() { | ||||||
|     local version="$1" |     local version="$1" | ||||||
|  |  | ||||||
|     if [[ -z "$version" ]] ; then |     if [[ -z "$version" ]] ; then | ||||||
|         version=$(select_component_version "DXVK") |         version=$(select_component_version "DXVK") | ||||||
|         [[ $? -ne 0 ]] && print_info "Установка DXVK отменена." && return |         [[ $? -ne 0 ]] && print_info "Установка DXVK отменена." && return | ||||||
| @@ -2171,21 +2228,27 @@ run_install_dxvk() { | |||||||
|         list_component_versions "DXVK" |         list_component_versions "DXVK" | ||||||
|         return |         return | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     check_prefix_var |     check_prefix_var | ||||||
|     init_database |     init_database | ||||||
|  |  | ||||||
|     export DXVK_VER="$version" |     export DXVK_VER="$version" | ||||||
|  |  | ||||||
|     init_wine_ver |     init_wine_ver | ||||||
|     init_wineprefix |     init_wineprefix | ||||||
|  |  | ||||||
|     if [[ "$DXVK_VER" == "none" ]] |     if [[ "$DXVK_VER" == "none" ]] | ||||||
|     then print_info "Удаление DXVK..." |     then print_info "Удаление DXVK..." | ||||||
|     else print_info "Установка DXVK: $DXVK_VER" |     else print_info "Установка DXVK: $DXVK_VER" | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     init_dxvk "$DXVK_VER" |     init_dxvk "$DXVK_VER" | ||||||
|     wait_wineserver |     wait_wineserver | ||||||
| } | } | ||||||
|  |  | ||||||
| run_install_vkd3d() { | run_install_vkd3d() { | ||||||
|     local version="$1" |     local version="$1" | ||||||
|  |  | ||||||
|     if [[ -z "$version" ]] ; then |     if [[ -z "$version" ]] ; then | ||||||
|         version=$(select_component_version "VKD3D") |         version=$(select_component_version "VKD3D") | ||||||
|         [[ $? -ne 0 ]] && print_info "Установка VKD3D отменена." && return |         [[ $? -ne 0 ]] && print_info "Установка VKD3D отменена." && return | ||||||
| @@ -2193,15 +2256,20 @@ run_install_vkd3d() { | |||||||
|         list_component_versions "VKD3D" |         list_component_versions "VKD3D" | ||||||
|         return |         return | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     check_prefix_var |     check_prefix_var | ||||||
|     init_database |     init_database | ||||||
|  |  | ||||||
|     export VKD3D_VER="$version" |     export VKD3D_VER="$version" | ||||||
|  |  | ||||||
|     init_wine_ver |     init_wine_ver | ||||||
|     init_wineprefix |     init_wineprefix | ||||||
|  |  | ||||||
|     if [[ "$VKD3D_VER" == "none" ]] |     if [[ "$VKD3D_VER" == "none" ]] | ||||||
|     then print_info "Удаление VKD3D..." |     then print_info "Удаление VKD3D..." | ||||||
|     else print_info "Установка VKD3D: $VKD3D_VER" |     else print_info "Установка VKD3D: $VKD3D_VER" | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     init_vkd3d "$VKD3D_VER" |     init_vkd3d "$VKD3D_VER" | ||||||
|     wait_wineserver |     wait_wineserver | ||||||
| } | } | ||||||
| @@ -2220,13 +2288,35 @@ run_change_wine_version() { | |||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     init_wine_ver |     init_wine_ver | ||||||
|  |  | ||||||
|     init_wineprefix |     init_wineprefix | ||||||
|  |  | ||||||
|     wait_wineserver |     wait_wineserver | ||||||
|     print_ok "Версия Wine для префикса $PREFIX_NAME успешно изменена на $WH_WINE_USE." |     print_ok "Версия Wine для префикса $PREFIX_NAME успешно изменена на $WH_WINE_USE." | ||||||
| } | } | ||||||
|  |  | ||||||
|  | clear_winetricks_cache() { | ||||||
|  |     local winetricks_cache_dir="$HOME/.cache/winetricks" | ||||||
|  |     local winehelper_wt_cache_dir="$HOME/.cache/winehelper/winetricks" | ||||||
|  |  | ||||||
|  |     if [[ ! -d "$winetricks_cache_dir" ]] && [[ ! -d "$winehelper_wt_cache_dir" ]]; then | ||||||
|  |         print_info "Кэш Winetricks не найден. Очистка не требуется." | ||||||
|  |         return 0 | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if [[ ! $1 =~ --force|-y ]] ; then | ||||||
|  |         print_warning "Вы собираетесь очистить кэш Winetricks." | ||||||
|  |         echo "Будут удалены все скачанные установщики Winetricks и списки компонентов." | ||||||
|  |         if ! print_confirmation "Продолжить?" | ||||||
|  |         then | ||||||
|  |             print_info "Операция отменена." | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |     print_info "Очистка кэша Winetricks..." | ||||||
|  |     try_remove_dir "$winetricks_cache_dir" | ||||||
|  |     try_remove_dir "$winehelper_wt_cache_dir" | ||||||
|  |     print_ok "Кэш Winetricks успешно очищен." | ||||||
|  | } | ||||||
|  |  | ||||||
| wh_info () { | wh_info () { | ||||||
|     echo "Использование: $SCRIPT_NAME [команда] |     echo "Использование: $SCRIPT_NAME [команда] | ||||||
|  |  | ||||||
| @@ -2246,6 +2336,7 @@ wh_info () { | |||||||
|     remove-prefix [имя_префикса]    удалить префикс и все связанные данные |     remove-prefix [имя_префикса]    удалить префикс и все связанные данные | ||||||
|     backup-prefix [имя_префикса]    создать резервную копию префикса |     backup-prefix [имя_префикса]    создать резервную копию префикса | ||||||
|     restore-prefix \"путь/до/whpack\" восстановить префикс из резервной копии |     restore-prefix \"путь/до/whpack\" восстановить префикс из резервной копии | ||||||
|  |     clear-winetricks-cache          очистить кэш Winetricks | ||||||
|  |  | ||||||
| Параметры: | Параметры: | ||||||
|     --help                          показать эту справку и выйти |     --help                          показать эту справку и выйти | ||||||
| @@ -2262,7 +2353,8 @@ create_new_dir "$WH_DIST_DIR" | |||||||
| create_new_dir "$WH_PREFIXES_DIR" | create_new_dir "$WH_PREFIXES_DIR" | ||||||
| create_new_dir "$WH_VULKAN_LIBDIR" | create_new_dir "$WH_VULKAN_LIBDIR" | ||||||
|  |  | ||||||
| if [[ -d "$HOME/.local/share/$SCRIPT_NAME" ]] \ | if [[ $WH_DEVEL != "1" ]] \ | ||||||
|  | && [[ -d "$HOME/.local/share/$SCRIPT_NAME" ]] \ | ||||||
| && [[ ! -L "$HOME/.winehelper" ]] | && [[ ! -L "$HOME/.winehelper" ]] | ||||||
| then try_force_link_dir "$HOME/.local/share/$SCRIPT_NAME" "$HOME/.winehelper" | then try_force_link_dir "$HOME/.local/share/$SCRIPT_NAME" "$HOME/.winehelper" | ||||||
| fi | fi | ||||||
| @@ -2303,17 +2395,20 @@ case "$arg1" in | |||||||
|     remove-prefix) remove_prefix "$@" ;; |     remove-prefix) remove_prefix "$@" ;; | ||||||
|     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 "$@" ;; | ||||||
|     *) |     *) | ||||||
|         if [[ -f "$arg1" ]] ; then |         if [[ -f "$arg1" ]] ; then | ||||||
|             WIN_FILE_EXEC="$(readlink -f "$arg1")" |             WIN_FILE_EXEC="$(readlink -f "$arg1")" | ||||||
|             WIN_FILE_NAME="$(basename "$WIN_FILE_EXEC")" |             WIN_FILE_NAME="$(basename "$WIN_FILE_EXEC")" | ||||||
|             find_prefix "$WIN_FILE_EXEC" |             find_prefix "$WIN_FILE_EXEC" | ||||||
|             case "${WIN_FILE_NAME,,}" in |             prepair_wine | ||||||
|                 *.exe) prepair_wine ; wine_run $WINE_WIN_START "$WIN_FILE_EXEC" "$@" ;; |  | ||||||
|                 *.msi) prepair_wine ; wine_run msiexec /i "$WIN_FILE_EXEC" "$@" ;; |             if [[ -n "$1" ]] && [[ -f "$1" ]] ; then | ||||||
|                 *.bat|*.cmd) prepair_wine ; wine_run start "$WIN_FILE_EXEC" "$@" ;; |                 WIN_OPEN_FILE="$("$WINELOADER" winepath -w "$1")" | ||||||
|                 *) fatal "Тип файла не поддерживается." ;; |                 shift | ||||||
|             esac |             fi | ||||||
|  |  | ||||||
|  |             wine_run "$WIN_FILE_EXEC" "$@" "$WIN_OPEN_FILE" | ||||||
|         else |         else | ||||||
|             print_error "Команды $arg1 не существует." |             print_error "Команды $arg1 не существует." | ||||||
|             wh_info |             wh_info | ||||||
|   | |||||||
| @@ -13,8 +13,8 @@ from functools import partial | |||||||
| from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar, | from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar, | ||||||
|                              QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox, |                              QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox, | ||||||
|                              QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu) |                              QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu) | ||||||
| from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve | from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve, pyqtSignal, QRect | ||||||
| from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor | from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor, QTextCharFormat, QColor, QPalette | ||||||
| from PyQt5.QtNetwork import QLocalServer, QLocalSocket | from PyQt5.QtNetwork import QLocalServer, QLocalSocket | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -26,9 +26,11 @@ class Var: | |||||||
|     DATA_PATH = os.environ.get("DATA_PATH") |     DATA_PATH = os.environ.get("DATA_PATH") | ||||||
|     CHANGELOG_FILE = os.environ.get("CHANGELOG_FILE") |     CHANGELOG_FILE = os.environ.get("CHANGELOG_FILE") | ||||||
|     WH_ICON_PATH = os.environ.get("WH_ICON_PATH") |     WH_ICON_PATH = os.environ.get("WH_ICON_PATH") | ||||||
|  |     WH_ICON_TRAY = os.environ.get("WH_ICON_TRAY") | ||||||
|     LICENSE_FILE = os.environ.get("LICENSE_FILE") |     LICENSE_FILE = os.environ.get("LICENSE_FILE") | ||||||
|     LICENSE_AGREEMENT_FILE = os.environ.get("AGREEMENT") |     LICENSE_AGREEMENT_FILE = os.environ.get("AGREEMENT") | ||||||
|     THIRD_PARTY_FILE = os.environ.get("THIRD_PARTY_FILE") |     THIRD_PARTY_FILE = os.environ.get("THIRD_PARTY_FILE") | ||||||
|  |     GENERAL = os.environ.get("GENERAL") | ||||||
|  |  | ||||||
| class DependencyManager: | class DependencyManager: | ||||||
|     """Класс для управления проверкой и установкой системных зависимостей.""" |     """Класс для управления проверкой и установкой системных зависимостей.""" | ||||||
| @@ -428,6 +430,8 @@ class WinetricksManagerDialog(QDialog): | |||||||
|         "Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»." |         "Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»." | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  |     installation_complete = pyqtSignal() | ||||||
|  |  | ||||||
|     def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None): |     def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None): | ||||||
|         super().__init__(parent) |         super().__init__(parent) | ||||||
|         self.prefix_path = prefix_path |         self.prefix_path = prefix_path | ||||||
| @@ -442,6 +446,7 @@ class WinetricksManagerDialog(QDialog): | |||||||
|         self.previous_tab_widget = None |         self.previous_tab_widget = None | ||||||
|         self.cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "winehelper", "winetricks") |         self.cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "winehelper", "winetricks") | ||||||
|         os.makedirs(self.cache_dir, exist_ok=True) |         os.makedirs(self.cache_dir, exist_ok=True) | ||||||
|  |         self.is_reloading_after_cache_clear = False | ||||||
|  |  | ||||||
|         self.setWindowTitle(f"Менеджер компонентов для префикса: {os.path.basename(prefix_path)}") |         self.setWindowTitle(f"Менеджер компонентов для префикса: {os.path.basename(prefix_path)}") | ||||||
|         self.setMinimumSize(800, 500) |         self.setMinimumSize(800, 500) | ||||||
| @@ -474,8 +479,14 @@ class WinetricksManagerDialog(QDialog): | |||||||
|         self.log_output.setText(self.INFO_TEXT) |         self.log_output.setText(self.INFO_TEXT) | ||||||
|         main_layout.addWidget(self.log_output) |         main_layout.addWidget(self.log_output) | ||||||
|  |  | ||||||
|         # Кнопки управления, выровненные по правому краю |         # Кнопки управления | ||||||
|         button_layout = QHBoxLayout() |         button_layout = QHBoxLayout() | ||||||
|  |  | ||||||
|  |         self.clear_cache_button = QPushButton("Очистить кеш") | ||||||
|  |         self.clear_cache_button.setStyleSheet("background-color: red; color: white;") | ||||||
|  |         self.clear_cache_button.clicked.connect(self.clear_winetricks_cache) | ||||||
|  |         button_layout.addWidget(self.clear_cache_button) | ||||||
|  |  | ||||||
|         button_layout.addStretch(1) |         button_layout.addStretch(1) | ||||||
|  |  | ||||||
|         self.apply_button = QPushButton("Применить") |         self.apply_button = QPushButton("Применить") | ||||||
| @@ -617,12 +628,33 @@ class WinetricksManagerDialog(QDialog): | |||||||
|             self._log(f"--- Предупреждение: не удалось прочитать {log_path}: {e} ---") |             self._log(f"--- Предупреждение: не удалось прочитать {log_path}: {e} ---") | ||||||
|         return installed_verbs |         return installed_verbs | ||||||
|  |  | ||||||
|     def _parse_winetricks_list_output(self, output, installed_verbs, list_widget): |     def _parse_winetricks_list_output(self, output, installed_verbs, list_widget, category): | ||||||
|         """Парсит вывод 'winetricks list' и заполняет QListWidget.""" |         """Парсит вывод 'winetricks list' и заполняет QListWidget.""" | ||||||
|         # Regex, который обрабатывает строки как с префиксом статуса '[ ]', так и без него. |         # Regex, который обрабатывает строки как с префиксом статуса '[ ]', так и без него. | ||||||
|         # 1. `(?:\[(.)]\s+)?` - опциональная группа для статуса (напр. '[x]'). |         # 1. `(?:\[(.)]\s+)?` - опциональная группа для статуса (напр. '[x]'). | ||||||
|         # 2. `([^\s]+)` - имя компонента (без пробелов). |         # 2. `([^\s]+)` - имя компонента (без пробелов). | ||||||
|         # 3. `(.*)` - оставшаяся часть строки (описание). |         # 3. `(.*)` - оставшаяся часть строки (описание). | ||||||
|  |  | ||||||
|  |         # Определяем шаблоны для фильтрации на основе категории | ||||||
|  |         dlls_blacklist_pattern = None | ||||||
|  |         fonts_blacklist_pattern = None | ||||||
|  |         settings_blacklist_pattern = None | ||||||
|  |  | ||||||
|  |         if category == 'dlls': | ||||||
|  |             # Исключаем d3d*, directx9, dont_use, dxvk*, vkd3d*, galliumnine, faudio*, Foundation | ||||||
|  |             dlls_blacklist_pattern = re.compile( | ||||||
|  |                 r'^(d3d|directx9|dont_use|dxvk|vkd3d|galliumnine|faudio|foundation)', re.IGNORECASE | ||||||
|  |             ) | ||||||
|  |         elif category == 'fonts': | ||||||
|  |             fonts_blacklist_pattern = re.compile( | ||||||
|  |                 r'^(dont_use)', re.IGNORECASE | ||||||
|  |             ) | ||||||
|  |         elif category == 'settings': | ||||||
|  |             # Исключаем vista*, alldlls, autostart_*, bad*, good*, win*, videomemory*, vd=*, isolate_home | ||||||
|  |             settings_blacklist_pattern = re.compile( | ||||||
|  |                 r'^(vista|alldlls|autostart_|bad|good|win|videomemory|vd=|isolate_home)', re.IGNORECASE | ||||||
|  |             ) | ||||||
|  |  | ||||||
|         line_re = re.compile(r"^\s*(?:\[(.)]\s+)?([^\s]+)\s*(.*)") |         line_re = re.compile(r"^\s*(?:\[(.)]\s+)?([^\s]+)\s*(.*)") | ||||||
|         found_items = False |         found_items = False | ||||||
|  |  | ||||||
| @@ -643,6 +675,14 @@ class WinetricksManagerDialog(QDialog): | |||||||
|             if '/' in name or '\\' in name or name.lower() in ('executing', 'using', 'warning:') or name.endswith(':'): |             if '/' in name or '\\' in name or name.lower() in ('executing', 'using', 'warning:') or name.endswith(':'): | ||||||
|                 continue |                 continue | ||||||
|  |  | ||||||
|  |             # Применяем фильтры для черных списков | ||||||
|  |             if dlls_blacklist_pattern and dlls_blacklist_pattern.search(name): | ||||||
|  |                 continue | ||||||
|  |             if fonts_blacklist_pattern and fonts_blacklist_pattern.search(name): | ||||||
|  |                 continue | ||||||
|  |             if settings_blacklist_pattern and settings_blacklist_pattern.search(name): | ||||||
|  |                 continue | ||||||
|  |  | ||||||
|             is_checked = name in installed_verbs |             is_checked = name in installed_verbs | ||||||
|             item_text = f"{name.ljust(27)}{description.strip()}" |             item_text = f"{name.ljust(27)}{description.strip()}" | ||||||
|             item = QListWidgetItem(item_text) |             item = QListWidgetItem(item_text) | ||||||
| @@ -681,7 +721,7 @@ class WinetricksManagerDialog(QDialog): | |||||||
|             self._log("--------------------------------------------------", "red") |             self._log("--------------------------------------------------", "red") | ||||||
|         else: |         else: | ||||||
|             installed_verbs = self._parse_winetricks_log() |             installed_verbs = self._parse_winetricks_log() | ||||||
|             found_items = self._parse_winetricks_list_output(output, installed_verbs, list_widget) |             found_items = self._parse_winetricks_list_output(output, installed_verbs, list_widget, category) | ||||||
|  |  | ||||||
|             if from_cache is None:  # Только если мы не читали из кэша |             if from_cache is None:  # Только если мы не читали из кэша | ||||||
|                 # Сохраняем успешный результат в кэш |                 # Сохраняем успешный результат в кэш | ||||||
| @@ -703,9 +743,18 @@ class WinetricksManagerDialog(QDialog): | |||||||
|                 self._log(output) |                 self._log(output) | ||||||
|                 self._log("--------------------------------------------------") |                 self._log("--------------------------------------------------") | ||||||
|  |  | ||||||
|  |         # Проверяем, были ли ошибки во время загрузки какой-либо из категорий | ||||||
|  |         has_errors = any(status == 'error' for status in self.category_statuses.values()) | ||||||
|  |  | ||||||
|         self.loading_count -= 1 |         self.loading_count -= 1 | ||||||
|         if self.loading_count == 0: |         if self.loading_count == 0: | ||||||
|             self._update_ui_state() |             self._update_ui_state() | ||||||
|  |             if self.is_reloading_after_cache_clear: | ||||||
|  |                 if has_errors: | ||||||
|  |                     self._log("\n=== Ошибка при обновлении списков. Проверьте лог выше. ===", "red") | ||||||
|  |                 else: | ||||||
|  |                     self._log("\n=== Списки успешно обновлены ===") | ||||||
|  |                 self.is_reloading_after_cache_clear = False # Сбрасываем флаг | ||||||
|  |  | ||||||
|     def _on_item_changed(self, item): |     def _on_item_changed(self, item): | ||||||
|         """Обрабатывает изменение состояния чекбокса, предотвращая снятие галочки с установленных.""" |         """Обрабатывает изменение состояния чекбокса, предотвращая снятие галочки с установленных.""" | ||||||
| @@ -839,6 +888,9 @@ class WinetricksManagerDialog(QDialog): | |||||||
|                                    "Подробности смотрите в логе.", |                                    "Подробности смотрите в логе.", | ||||||
|                                    QMessageBox.Warning, |                                    QMessageBox.Warning, | ||||||
|                                    {"buttons": {"OK": QMessageBox.AcceptRole}}) |                                    {"buttons": {"OK": QMessageBox.AcceptRole}}) | ||||||
|  |             # Сбрасываем формат символов к значению по умолчанию. | ||||||
|  |             # Это гарантирует, что следующий вызов append() не унаследует красный цвет. | ||||||
|  |             self.log_output.setCurrentCharFormat(QTextCharFormat()) | ||||||
|             self.apply_button.setEnabled(True) |             self.apply_button.setEnabled(True) | ||||||
|             self.close_button.setEnabled(True) |             self.close_button.setEnabled(True) | ||||||
|             return |             return | ||||||
| @@ -856,8 +908,67 @@ class WinetricksManagerDialog(QDialog): | |||||||
|         # Перезагружаем данные, чтобы обновить состояние |         # Перезагружаем данные, чтобы обновить состояние | ||||||
|         self.initial_states.clear() |         self.initial_states.clear() | ||||||
|         self.load_all_categories() |         self.load_all_categories() | ||||||
|  |         self.installation_complete.emit() | ||||||
|         self.installation_finished = True |         self.installation_finished = True | ||||||
|  |  | ||||||
|  |     def clear_winetricks_cache(self): | ||||||
|  |         """Запускает очистку кэша Winetricks.""" | ||||||
|  |         reply = self._show_message_box( | ||||||
|  |             "Очистка кэша Winetricks", | ||||||
|  |             "Вы собираетесь удалить все скачанные установщики и списки компонентов Winetricks.\n\n" | ||||||
|  |             "Это действие может потребоваться, если у вас возникают проблемы со скачиванием или установкой компонентов.\n\n" | ||||||
|  |             "Продолжить?", | ||||||
|  |             QMessageBox.Question, | ||||||
|  |             {"buttons": {"Да": QMessageBox.YesRole, "Нет": QMessageBox.NoRole}, "default": "Нет"} | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         if reply != "Да": | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         # Блокируем UI на время выполнения | ||||||
|  |         self.tabs.setEnabled(False) | ||||||
|  |         self.clear_cache_button.setEnabled(False) | ||||||
|  |         self.apply_button.setEnabled(False) | ||||||
|  |         self.reinstall_button.setEnabled(False) | ||||||
|  |         self.close_button.setEnabled(False) | ||||||
|  |  | ||||||
|  |         self.log_output.clear() | ||||||
|  |  | ||||||
|  |         self.cache_clear_process = QProcess(self) | ||||||
|  |         self.cache_clear_process.setProcessChannelMode(QProcess.MergedChannels) | ||||||
|  |  | ||||||
|  |         def handle_output(): | ||||||
|  |             output = self.cache_clear_process.readAll().data().decode('utf-8', 'ignore').strip() | ||||||
|  |             if output: | ||||||
|  |                 self._log(output) | ||||||
|  |  | ||||||
|  |         def handle_finish(exit_code, exit_status): | ||||||
|  |             if exit_code == 0: | ||||||
|  |                 self.is_reloading_after_cache_clear = True # Устанавливаем флаг перед перезагрузкой | ||||||
|  |                 self.category_statuses.clear() # Очищаем статусы перед новой загрузкой | ||||||
|  |                 # Воссоздаем директорию кэша, так как скрипт ее полностью удалил | ||||||
|  |                 os.makedirs(self.cache_dir, exist_ok=True) | ||||||
|  |                 self._log("Обновление списков...") | ||||||
|  |                 self.initial_states.clear() | ||||||
|  |                 self.load_all_categories() | ||||||
|  |             else: | ||||||
|  |                 self._log(f"\n=== Ошибка (код: {exit_code}) ===", "red") | ||||||
|  |  | ||||||
|  |             # Восстанавливаем UI | ||||||
|  |             self.tabs.setEnabled(True) | ||||||
|  |             self.clear_cache_button.setEnabled(True) | ||||||
|  |             self.close_button.setEnabled(True) | ||||||
|  |             self._update_ui_state() # Обновляем состояние кнопок Применить/Переустановить | ||||||
|  |  | ||||||
|  |         self.cache_clear_process.readyRead.connect(handle_output) | ||||||
|  |         self.cache_clear_process.finished.connect(handle_finish) | ||||||
|  |  | ||||||
|  |         winehelper_path = self.parent().winehelper_path if hasattr(self.parent(), 'winehelper_path') else Var.RUN_SCRIPT | ||||||
|  |         args = ["clear-winetricks-cache", "--force"] | ||||||
|  |  | ||||||
|  |         self._log(f"Выполнение: {shlex.quote(winehelper_path)} {' '.join(args)}\n") | ||||||
|  |         self.cache_clear_process.start(winehelper_path, args) | ||||||
|  |  | ||||||
|     def closeEvent(self, event): |     def closeEvent(self, event): | ||||||
|         """Обрабатывает закрытие окна, чтобы предотвратить выход во время установки.""" |         """Обрабатывает закрытие окна, чтобы предотвратить выход во время установки.""" | ||||||
|         # Проверяем, запущен ли процесс установки/переустановки |         # Проверяем, запущен ли процесс установки/переустановки | ||||||
| @@ -901,6 +1012,8 @@ class WinetricksManagerDialog(QDialog): | |||||||
|         """Добавляет сообщение в лог с возможностью указания цвета.""" |         """Добавляет сообщение в лог с возможностью указания цвета.""" | ||||||
|         if color: |         if color: | ||||||
|             self.log_output.append(f'<span style="color:{color};">{message}</span>') |             self.log_output.append(f'<span style="color:{color};">{message}</span>') | ||||||
|  |             # Сбрасываем формат, чтобы следующий текст не наследовал цвет | ||||||
|  |             self.log_output.setCurrentCharFormat(QTextCharFormat()) | ||||||
|         else: |         else: | ||||||
|             self.log_output.append(message) |             self.log_output.append(message) | ||||||
|         self.log_output.moveCursor(QTextCursor.End) |         self.log_output.moveCursor(QTextCursor.End) | ||||||
| @@ -1590,10 +1703,34 @@ class WineHelperGUI(QMainWindow): | |||||||
|             "padding-left: 10px;", "padding-left: 15px;" |             "padding-left: 10px;", "padding-left: 15px;" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |         # Стиль для кнопок тестовых программ | ||||||
|  |         self.TEST_BUTTON_LIST_STYLE = """ | ||||||
|  |             QPushButton { | ||||||
|  |                 background-color: #ffdc64; /* Более темный желтый фон */ | ||||||
|  |                 color: black; /* Черный цвет текста для контраста */ | ||||||
|  |                 text-align: left; | ||||||
|  |                 padding-left: 10px; | ||||||
|  |                 padding-right: 10px; | ||||||
|  |                 height: 42px; min-height: 42px; max-height: 42px; | ||||||
|  |             } | ||||||
|  |             QPushButton::icon { padding-left: 10px; } | ||||||
|  |         """ | ||||||
|  |  | ||||||
|         # Стили для оберток кнопок (для рамки выделения) |         # Стили для оберток кнопок (для рамки выделения) | ||||||
|         self.FRAME_STYLE_DEFAULT = "QFrame { border: 2px solid transparent; border-radius: 8px; padding: 0px; }" |         self.FRAME_STYLE_DEFAULT = "QFrame { border: 2px solid transparent; border-radius: 8px; padding: 0px; }" | ||||||
|         self.FRAME_STYLE_SELECTED = "QFrame { border: 2px solid #0078d7; border-radius: 8px; padding: 0px; }" |         self.FRAME_STYLE_SELECTED = "QFrame { border: 2px solid #0078d7; border-radius: 8px; padding: 0px; }" | ||||||
|  |  | ||||||
|  |         # Стили для кнопок Запустить/Остановить | ||||||
|  |         self.RUN_BUTTON_STYLE = """ | ||||||
|  |             QPushButton { | ||||||
|  |                 background-color: #4CAF50; color: white; | ||||||
|  |                 font-weight: bold; | ||||||
|  |             } | ||||||
|  |         """ | ||||||
|  |         self.STOP_BUTTON_STYLE = """ | ||||||
|  |             QPushButton { background-color: #d32f2f; color: white; font-weight: bold; } | ||||||
|  |         """ | ||||||
|  |  | ||||||
|         # Основные переменные |         # Основные переменные | ||||||
|         self.winehelper_path = Var.RUN_SCRIPT |         self.winehelper_path = Var.RUN_SCRIPT | ||||||
|         self.process = None |         self.process = None | ||||||
| @@ -1636,8 +1773,8 @@ class WineHelperGUI(QMainWindow): | |||||||
|         self.main_layout.addLayout(content_layout) |         self.main_layout.addLayout(content_layout) | ||||||
|  |  | ||||||
|         # Фиксируем минимальные размеры |         # Фиксируем минимальные размеры | ||||||
|         self.stacked_widget.setMinimumWidth(520) |         self.stacked_widget.setMinimumWidth(535) | ||||||
|         self.info_panel.setMinimumWidth(415) |         self.info_panel.setMinimumWidth(395) | ||||||
|  |  | ||||||
|         # Вкладки |         # Вкладки | ||||||
|         self.create_auto_install_tab() |         self.create_auto_install_tab() | ||||||
| @@ -1678,6 +1815,18 @@ class WineHelperGUI(QMainWindow): | |||||||
|         self.raise_() |         self.raise_() | ||||||
|         self.activateWindow() |         self.activateWindow() | ||||||
|  |  | ||||||
|  |     def create_colorized_icon(self, icon_path, color): | ||||||
|  |         """Загружает иконку (SVG) и применяет к ней указанный цвет.""" | ||||||
|  |         target_pixmap = QPixmap(icon_path) | ||||||
|  |         if target_pixmap.isNull(): | ||||||
|  |             return QIcon() | ||||||
|  |  | ||||||
|  |         painter = QPainter(target_pixmap) | ||||||
|  |         painter.setCompositionMode(QPainter.CompositionMode_SourceIn) | ||||||
|  |         painter.fillRect(target_pixmap.rect(), QColor(color)) | ||||||
|  |         painter.end() | ||||||
|  |         return QIcon(target_pixmap) | ||||||
|  |  | ||||||
|     def create_tray_icon(self): |     def create_tray_icon(self): | ||||||
|         """Создает и настраивает иконку в системном трее.""" |         """Создает и настраивает иконку в системном трее.""" | ||||||
|         if not QSystemTrayIcon.isSystemTrayAvailable(): |         if not QSystemTrayIcon.isSystemTrayAvailable(): | ||||||
| @@ -1686,11 +1835,23 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|         self.tray_icon = QSystemTrayIcon(self) |         self.tray_icon = QSystemTrayIcon(self) | ||||||
|  |  | ||||||
|         icon_path = Var.WH_ICON_PATH |         # --- Определение цвета иконки в зависимости от темы --- | ||||||
|         if icon_path and os.path.exists(icon_path): |         if Var.WH_ICON_TRAY and os.path.exists(Var.WH_ICON_TRAY): | ||||||
|             pixmap = QPixmap(icon_path) |             # Получаем цвет текста окна из палитры приложения. | ||||||
|             if not pixmap.isNull(): |             # Это хороший индикатор для определения контрастного цвета. | ||||||
|                 self.tray_icon.setIcon(QIcon(pixmap)) |             window_text_color = self.palette().color(QPalette.WindowText) | ||||||
|  |  | ||||||
|  |             # Если цвет текста светлый (высокая яркость), значит, тема темная. | ||||||
|  |             # И наоборот: если цвет текста темный, тема светлая. | ||||||
|  |             # Яркость > 127 обычно указывает на светлый цвет. | ||||||
|  |             is_dark_theme = window_text_color.lightness() > 127 | ||||||
|  |  | ||||||
|  |             if is_dark_theme: | ||||||
|  |                 # Для темных тем используем белую иконку | ||||||
|  |                 self.tray_icon.setIcon(self.create_colorized_icon(Var.WH_ICON_TRAY, Qt.white)) | ||||||
|  |             else: | ||||||
|  |                 # Для светлых тем используем черную иконку | ||||||
|  |                 self.tray_icon.setIcon(self.create_colorized_icon(Var.WH_ICON_TRAY, Qt.black)) | ||||||
|  |  | ||||||
|         # Создаем и сохраняем меню как атрибут класса, чтобы оно не удалялось |         # Создаем и сохраняем меню как атрибут класса, чтобы оно не удалялось | ||||||
|         self.tray_menu = QMenu(self) |         self.tray_menu = QMenu(self) | ||||||
| @@ -1732,8 +1893,8 @@ class WineHelperGUI(QMainWindow): | |||||||
|         if tab_name == "Автоматическая установка": |         if tab_name == "Автоматическая установка": | ||||||
|             title = "Автоматическая установка" |             title = "Автоматическая установка" | ||||||
|             html_content = ("<h3>Автоматическая установка</h3>" |             html_content = ("<h3>Автоматическая установка</h3>" | ||||||
|                             "<p>Скрипты из этого списка скачают, установят и настроят приложение за вас.</p>" |                             "<p>Скрипты из этого списка скачают, установят и настроят приложение за вас. Просто выберите программу и нажмите «Установить».</p>" | ||||||
|                             "<p>Просто выберите программу и нажмите «Установить».</p>") |                             "<p>Для доступа к экспериментальным скриптам установки отметьте опцию <b>«Показать тестовые версии»</b> внизу списка.</p>") | ||||||
|             show_global = False |             show_global = False | ||||||
|         elif tab_name == "Ручная установка": |         elif tab_name == "Ручная установка": | ||||||
|             title = "Ручная установка" |             title = "Ручная установка" | ||||||
| @@ -1857,6 +2018,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|         # --- Верхний ряд кнопок --- |         # --- Верхний ряд кнопок --- | ||||||
|         top_buttons_layout = QHBoxLayout() |         top_buttons_layout = QHBoxLayout() | ||||||
|         self.run_button = QPushButton("Запустить") |         self.run_button = QPushButton("Запустить") | ||||||
|  |         self.run_button.setStyleSheet(self.RUN_BUTTON_STYLE) | ||||||
|         self.run_button.clicked.connect(self.toggle_run_stop_app) |         self.run_button.clicked.connect(self.toggle_run_stop_app) | ||||||
|         top_buttons_layout.addWidget(self.run_button) |         top_buttons_layout.addWidget(self.run_button) | ||||||
|         installed_action_layout.addLayout(top_buttons_layout) |         installed_action_layout.addLayout(top_buttons_layout) | ||||||
| @@ -2020,14 +2182,14 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|         return btn |         return btn | ||||||
|  |  | ||||||
|     def _populate_install_grid(self, grid_layout, scripts_list, script_folder, button_list): |     def _populate_install_grid(self, grid_layout, scripts_list, script_folder, button_list, start_index=None): | ||||||
|         """ |         """ | ||||||
|         Заполняет QGridLayout кнопками установщиков. |         Заполняет QGridLayout кнопками установщиков. | ||||||
|         Кнопки создаются только для скриптов, в которых найдена переменная PROG_NAME. |         Кнопки создаются только для скриптов, в которых найдена переменная PROG_NAME. | ||||||
|  |  | ||||||
|         :param grid_layout: QGridLayout для заполнения. |         :param grid_layout: QGridLayout для заполнения. | ||||||
|         :param scripts_list: Список имен скриптов. |         :param scripts_list: Список имен скриптов. | ||||||
|         :param script_folder: Имя папки со скриптами ('autoinstall' или 'manualinstall'). |         :param script_folder: Имя папки со скриптами ('autoinstall', 'manualinstall' или 'testinstall'). | ||||||
|         :param button_list: Список для хранения созданных кнопок. |         :param button_list: Список для хранения созданных кнопок. | ||||||
|         """ |         """ | ||||||
|         button_index = 0 |         button_index = 0 | ||||||
| @@ -2041,7 +2203,13 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|             icon_names = ScriptParser.extract_icons_from_script(script_path) |             icon_names = ScriptParser.extract_icons_from_script(script_path) | ||||||
|             icon_paths = [os.path.join(Var.DATA_PATH, "image", f"{name}.png") for name in icon_names] |             icon_paths = [os.path.join(Var.DATA_PATH, "image", f"{name}.png") for name in icon_names] | ||||||
|             btn = self._create_app_button(prog_name, icon_paths, self.BUTTON_LIST_STYLE) |  | ||||||
|  |             # Выбираем стиль в зависимости от папки | ||||||
|  |             if script_folder == 'testinstall': | ||||||
|  |                 style_sheet = self.TEST_BUTTON_LIST_STYLE | ||||||
|  |             else: | ||||||
|  |                 style_sheet = self.BUTTON_LIST_STYLE | ||||||
|  |             btn = self._create_app_button(prog_name, icon_paths, style_sheet) | ||||||
|  |  | ||||||
|             # Обертка для рамки выделения |             # Обертка для рамки выделения | ||||||
|             frame = QFrame() |             frame = QFrame() | ||||||
| @@ -2051,12 +2219,12 @@ class WineHelperGUI(QMainWindow): | |||||||
|             layout.addWidget(btn) |             layout.addWidget(btn) | ||||||
|  |  | ||||||
|             btn.clicked.connect(lambda _, s=script, b=btn: self.show_script_info(s, b)) |             btn.clicked.connect(lambda _, s=script, b=btn: self.show_script_info(s, b)) | ||||||
|             row, column = divmod(button_index, 2) |             row, column = divmod(len(button_list), 2) | ||||||
|             grid_layout.addWidget(frame, row, column) |             grid_layout.addWidget(frame, row, column) | ||||||
|             button_list.append(btn) |             button_list.append(btn) | ||||||
|             button_index += 1 |             button_index += 1 | ||||||
|  |  | ||||||
|     def _create_searchable_grid_tab(self, placeholder_text, filter_slot): |     def _create_searchable_grid_tab(self, placeholder_text, filter_slot, add_stretch=True): | ||||||
|         """ |         """ | ||||||
|         Создает стандартную вкладку с полем поиска и сеточным макетом с прокруткой. |         Создает стандартную вкладку с полем поиска и сеточным макетом с прокруткой. | ||||||
|         Возвращает кортеж (главный виджет вкладки, сеточный макет, поле поиска, область прокрутки). |         Возвращает кортеж (главный виджет вкладки, сеточный макет, поле поиска, область прокрутки). | ||||||
| @@ -2090,11 +2258,12 @@ class WineHelperGUI(QMainWindow): | |||||||
|         grid_layout.setColumnStretch(1, 1) |         grid_layout.setColumnStretch(1, 1) | ||||||
|  |  | ||||||
|         v_scroll_layout.addLayout(grid_layout) |         v_scroll_layout.addLayout(grid_layout) | ||||||
|  |         if add_stretch: | ||||||
|             v_scroll_layout.addStretch(1) |             v_scroll_layout.addStretch(1) | ||||||
|  |  | ||||||
|         return tab_widget, grid_layout, search_edit, scroll_area |         return tab_widget, grid_layout, search_edit, scroll_area | ||||||
|  |  | ||||||
|     def _create_and_populate_install_tab(self, tab_title, script_folder, search_placeholder, filter_slot): |     def _create_and_populate_install_tab(self, tab_title, script_folders, search_placeholder, filter_slot): | ||||||
|         """ |         """ | ||||||
|         Создает и заполняет вкладку для установки (автоматической или ручной). |         Создает и заполняет вкладку для установки (автоматической или ручной). | ||||||
|         Возвращает кортеж со скриптами, кнопками и виджетами. |         Возвращает кортеж со скриптами, кнопками и виджетами. | ||||||
| @@ -2104,16 +2273,17 @@ class WineHelperGUI(QMainWindow): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         scripts = [] |         scripts = [] | ||||||
|         script_path = os.path.join(Var.DATA_PATH, script_folder) |         buttons_list = [] | ||||||
|  |         for folder in script_folders: | ||||||
|  |             script_path = os.path.join(Var.DATA_PATH, folder) | ||||||
|             if os.path.isdir(script_path): |             if os.path.isdir(script_path): | ||||||
|                 try: |                 try: | ||||||
|                 scripts = sorted(os.listdir(script_path)) |                     folder_scripts = sorted(os.listdir(script_path)) | ||||||
|  |                     scripts.extend(folder_scripts) | ||||||
|  |                     self._populate_install_grid(grid_layout, folder_scripts, folder, buttons_list) | ||||||
|                 except OSError as e: |                 except OSError as e: | ||||||
|                     print(f"Не удалось прочитать директорию {script_path}: {e}") |                     print(f"Не удалось прочитать директорию {script_path}: {e}") | ||||||
|  |  | ||||||
|         buttons_list = [] |  | ||||||
|         self._populate_install_grid(grid_layout, scripts, script_folder, buttons_list) |  | ||||||
|  |  | ||||||
|         self.add_tab(tab_widget, tab_title) |         self.add_tab(tab_widget, tab_title) | ||||||
|  |  | ||||||
|         return scripts, buttons_list, grid_layout, search_edit, scroll_area |         return scripts, buttons_list, grid_layout, search_edit, scroll_area | ||||||
| @@ -2124,12 +2294,28 @@ class WineHelperGUI(QMainWindow): | |||||||
|             scripts, buttons, layout, |             scripts, buttons, layout, | ||||||
|             search_edit, scroll_area |             search_edit, scroll_area | ||||||
|         ) = self._create_and_populate_install_tab( |         ) = self._create_and_populate_install_tab( | ||||||
|             "Автоматическая установка", "autoinstall", "Поиск скрипта автоматической установки...", partial(self.filter_buttons, 'auto') |             "Автоматическая установка", ["autoinstall"], "Поиск скрипта автоматической установки...", partial(self.filter_buttons, 'auto') | ||||||
|         ) |         ) | ||||||
|         self.autoinstall_scripts = scripts |         self.autoinstall_scripts = scripts | ||||||
|         self.install_tabs_data['auto'] = { |         self.install_tabs_data['auto'] = { | ||||||
|             'buttons': buttons, 'layout': layout, 'search_edit': search_edit, 'scroll_area': scroll_area |             'buttons': buttons, 'layout': layout, 'search_edit': search_edit, 'scroll_area': scroll_area | ||||||
|         } |         } | ||||||
|  |         self.install_tabs_data['auto']['test_buttons'] = [] | ||||||
|  |  | ||||||
|  |         # Добавляем чекбокс для тестовых версий | ||||||
|  |         test_checkbox = QCheckBox("Показать тестовые версии") | ||||||
|  |         test_checkbox.setToolTip("Показать/скрыть экспериментальные скрипты установки") | ||||||
|  |  | ||||||
|  |         # Находим layout вкладки, чтобы добавить чекбокс | ||||||
|  |         tab_widget = self.stacked_widget.widget(self.stacked_widget.count() - 1) | ||||||
|  |         if tab_widget and tab_widget.layout(): | ||||||
|  |             tab_widget.layout().addWidget(test_checkbox) | ||||||
|  |  | ||||||
|  |         # Подключаем сигнал к слоту обновления | ||||||
|  |         test_checkbox.stateChanged.connect(self.update_auto_install_list) | ||||||
|  |  | ||||||
|  |         # Сохраняем чекбокс для доступа в будущем | ||||||
|  |         self.install_tabs_data['auto']['test_checkbox'] = test_checkbox | ||||||
|  |  | ||||||
|     def create_manual_install_tab(self): |     def create_manual_install_tab(self): | ||||||
|         """Создает вкладку для ручной установки программ""" |         """Создает вкладку для ручной установки программ""" | ||||||
| @@ -2137,17 +2323,86 @@ class WineHelperGUI(QMainWindow): | |||||||
|             scripts, buttons, layout, |             scripts, buttons, layout, | ||||||
|             search_edit, scroll_area |             search_edit, scroll_area | ||||||
|         ) = self._create_and_populate_install_tab( |         ) = self._create_and_populate_install_tab( | ||||||
|             "Ручная установка", "manualinstall", "Поиск скрипта ручной установки...", partial(self.filter_buttons, 'manual') |             "Ручная установка", ["manualinstall"], "Поиск скрипта ручной установки...", partial(self.filter_buttons, 'manual') | ||||||
|         ) |         ) | ||||||
|         self.manualinstall_scripts = scripts |         self.manualinstall_scripts = scripts | ||||||
|         self.install_tabs_data['manual'] = { |         self.install_tabs_data['manual'] = { | ||||||
|             'buttons': buttons, 'layout': layout, 'search_edit': search_edit, 'scroll_area': scroll_area |             'buttons': buttons, 'layout': layout, 'search_edit': search_edit, 'scroll_area': scroll_area | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     def update_auto_install_list(self): | ||||||
|  |         """Обновляет список на вкладке 'Автоматическая установка' при изменении чекбокса.""" | ||||||
|  |         data = self.install_tabs_data.get('auto') | ||||||
|  |         if not data: | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         is_checked = data['test_checkbox'].isChecked() | ||||||
|  |         test_buttons = data.get('test_buttons', []) | ||||||
|  |  | ||||||
|  |         # Если нужно показать тестовые версии и они еще не добавлены | ||||||
|  |         if is_checked and not test_buttons: | ||||||
|  |             test_script_folder = "testinstall" | ||||||
|  |             script_path = os.path.join(Var.DATA_PATH, test_script_folder) | ||||||
|  |             if os.path.isdir(script_path): | ||||||
|  |                 try: | ||||||
|  |                     folder_scripts = sorted(os.listdir(script_path)) | ||||||
|  |                     # Запоминаем, какие кнопки являются тестовыми | ||||||
|  |                     new_test_buttons = [] | ||||||
|  |                     self._populate_install_grid(data['layout'], folder_scripts, test_script_folder, new_test_buttons) | ||||||
|  |                     data['test_buttons'] = new_test_buttons | ||||||
|  |                     data['buttons'].extend(new_test_buttons) | ||||||
|  |                     self.autoinstall_scripts.extend(folder_scripts) | ||||||
|  |  | ||||||
|  |                     # Применяем фильтр и прокручиваем к первому новому элементу | ||||||
|  |                     self.filter_buttons('auto') | ||||||
|  |                     if new_test_buttons: | ||||||
|  |                         first_new_button = new_test_buttons[0] | ||||||
|  |                         frame = first_new_button.parent() | ||||||
|  |                         if isinstance(frame, QFrame): | ||||||
|  |                             # Даем время на отрисовку перед прокруткой | ||||||
|  |                             QTimer.singleShot(100, lambda: data['scroll_area'].ensureWidgetVisible(frame, 50, 50)) | ||||||
|  |  | ||||||
|  |                 except OSError as e: | ||||||
|  |                     print(f"Не удалось прочитать директорию {test_script_folder}: {e}") | ||||||
|  |  | ||||||
|  |         # Если нужно скрыть тестовые версии и они были добавлены | ||||||
|  |         elif not is_checked and test_buttons: | ||||||
|  |             # Если текущая активная кнопка находится среди удаляемых, сбрасываем ее | ||||||
|  |             if self.current_active_button in test_buttons: | ||||||
|  |                 self._reset_info_panel_to_default("Автоматическая установка") | ||||||
|  |                 self.current_active_button = None | ||||||
|  |  | ||||||
|  |             # Останавливаем анимацию и удаляем виджеты тестовых кнопок | ||||||
|  |             for btn in test_buttons: | ||||||
|  |                 if btn in self.icon_animators: | ||||||
|  |                     anim_data = self.icon_animators.pop(btn) | ||||||
|  |                     if 'main_timer' in anim_data: | ||||||
|  |                         anim_data['main_timer'].stop() | ||||||
|  |                     if 'animation' in anim_data and anim_data['animation']: | ||||||
|  |                         anim_data['animation'].stop() | ||||||
|  |  | ||||||
|  |                 # Удаляем кнопку из основного списка | ||||||
|  |                 if btn in data['buttons']: | ||||||
|  |                     data['buttons'].remove(btn) | ||||||
|  |  | ||||||
|  |                 # Удаляем фрейм кнопки из layout | ||||||
|  |                 frame = btn.parent() | ||||||
|  |                 if frame: | ||||||
|  |                     frame.deleteLater() | ||||||
|  |  | ||||||
|  |             # Очищаем список тестовых кнопок | ||||||
|  |             data['test_buttons'].clear() | ||||||
|  |             # Обновляем список скриптов | ||||||
|  |             self.autoinstall_scripts = [s for s in self.autoinstall_scripts if not os.path.exists(os.path.join(Var.DATA_PATH, "testinstall", s))] | ||||||
|  |  | ||||||
|  |         # В любом случае применяем фильтр, чтобы скрыть/показать кнопки в соответствии с поиском | ||||||
|  |         if data['test_checkbox'].isChecked(): | ||||||
|  |             self.filter_buttons('auto') | ||||||
|  |  | ||||||
|     def create_installed_tab(self): |     def create_installed_tab(self): | ||||||
|         """Создает вкладку для отображения установленных программ в виде кнопок""" |         """Создает вкладку для отображения установленных программ в виде кнопок""" | ||||||
|         installed_tab, self.installed_scroll_layout, self.installed_search_edit, self.installed_scroll_area = self._create_searchable_grid_tab( |         installed_tab, self.installed_scroll_layout, self.installed_search_edit, self.installed_scroll_area = self._create_searchable_grid_tab( | ||||||
|             "Поиск установленной программы...", self.filter_installed_buttons |             "Поиск установленной программы...", self.filter_installed_buttons, add_stretch=True | ||||||
|         ) |         ) | ||||||
|         self.add_tab(installed_tab, "Установленные") |         self.add_tab(installed_tab, "Установленные") | ||||||
|  |  | ||||||
| @@ -2389,7 +2644,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|             prefix_names = [] |             prefix_names = [] | ||||||
|  |  | ||||||
|         self.created_prefix_selector.blockSignals(True) |         self.created_prefix_selector.blockSignals(True) | ||||||
|         self.remove_all_button.setEnabled(bool(prefix_names)) |         self.remove_all_button.setEnabled(True) | ||||||
|         self.created_prefix_selector.clear() |         self.created_prefix_selector.clear() | ||||||
|         if prefix_names: |         if prefix_names: | ||||||
|             self.created_prefix_selector.addItems(prefix_names) |             self.created_prefix_selector.addItems(prefix_names) | ||||||
| @@ -2405,7 +2660,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|             self.current_managed_prefix_name = None |             self.current_managed_prefix_name = None | ||||||
|             self._setup_prefix_management_panel(None) |             self._setup_prefix_management_panel(None) | ||||||
|             self.delete_prefix_button.setEnabled(False) |             self.delete_prefix_button.setEnabled(False) | ||||||
|             self.remove_all_button.setEnabled(False) |             self.remove_all_button.setEnabled(True) | ||||||
|             self.create_base_pfx_button.setEnabled(False) |             self.create_base_pfx_button.setEnabled(False) | ||||||
|             self.open_prefix_folder_button.setEnabled(False) |             self.open_prefix_folder_button.setEnabled(False) | ||||||
|         else: |         else: | ||||||
| @@ -2601,19 +2856,39 @@ class WineHelperGUI(QMainWindow): | |||||||
|         self.esync_button.blockSignals(False) |         self.esync_button.blockSignals(False) | ||||||
|         self.fsync_button.blockSignals(False) |         self.fsync_button.blockSignals(False) | ||||||
|  |  | ||||||
|  |         # --- Чтение и отображение установленных компонентов Winetricks --- | ||||||
|  |         winetricks_log_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name, "winetricks.log") | ||||||
|  |         installed_verbs = [] | ||||||
|  |         if os.path.exists(winetricks_log_path): | ||||||
|  |             try: | ||||||
|  |                 with open(winetricks_log_path, 'r', encoding='utf-8') as f: | ||||||
|  |                     for line in f: | ||||||
|  |                         verb = line.split('#', 1)[0].strip() | ||||||
|  |                         if verb: | ||||||
|  |                             installed_verbs.append(verb) | ||||||
|  |             except IOError as e: | ||||||
|  |                 print(f"Ошибка чтения winetricks.log: {e}") | ||||||
|  |  | ||||||
|  |         # Фильтруем служебные компоненты, чтобы не засорять вывод | ||||||
|  |         verbs_to_ignore = { | ||||||
|  |             'isolate_home', 'winxp', 'win7', 'win10', 'win11', | ||||||
|  |             'vista', 'win2k', 'win2k3', 'win2k8', 'win8', 'win81', | ||||||
|  |             'workaround', 'internal' | ||||||
|  |         } | ||||||
|  |         display_verbs = sorted([v for v in installed_verbs if v not in verbs_to_ignore]) | ||||||
|  |  | ||||||
|         # Карта для красивого отображения известных переменных |         # Карта для красивого отображения известных переменных | ||||||
|         display_map = { |         display_map = { | ||||||
|             "WINEPREFIX": ("Путь", lambda v: v), |             "WINEPREFIX": ("Путь", lambda v: v), | ||||||
|             "WINEARCH": ("Архитектура", lambda v: "64-bit" if v == "win64" else "32-bit"), |             "WINEARCH": ("Архитектура", lambda v: "64-bit" if v == "win64" else "32-bit"), | ||||||
|             "WH_WINE_USE": ("Версия Wine", lambda v: "Системная" if v == "system" else v), |             "WH_WINE_USE": ("Версия Wine", lambda v: "Системная" if v == "system" else v), | ||||||
|             "BASE_PFX": ("Тип", lambda v: 'Чистый' if v == "none" else 'С рекомендуемыми библиотеками'), |  | ||||||
|             "DXVK_VER": ("Версия DXVK", lambda v: v if v else "Не установлено"), |             "DXVK_VER": ("Версия DXVK", lambda v: v if v else "Не установлено"), | ||||||
|             "VKD3D_VER": ("Версия VKD3D", lambda v: v if v else "Не установлено"), |             "VKD3D_VER": ("Версия VKD3D", lambda v: v if v else "Не установлено"), | ||||||
|             "WINEESYNC": ("ESync", lambda v: "Включен" if v == "1" else "Выключен"), |             "WINEESYNC": ("ESync", lambda v: "Включен" if v == "1" else "Выключен"), | ||||||
|             "WINEFSYNC": ("FSync", lambda v: "Включен" if v == "1" else "Выключен"), |             "WINEFSYNC": ("FSync", lambda v: "Включен" if v == "1" else "Выключен"), | ||||||
|             "WH_XDG_OPEN": ("Ассоциации файлов", lambda v: v if v and v != "0" else "Не заданы"), |             "WH_XDG_OPEN": ("Ассоциации файлов", lambda v: v if v and v != "0" else "Не заданы"), | ||||||
|         } |         } | ||||||
|         display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "BASE_PFX", "DXVK_VER", "VKD3D_VER", "WINEESYNC", "WINEFSYNC", "WH_XDG_OPEN"] |         display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "DXVK_VER", "VKD3D_VER", "WINEESYNC", "WINEFSYNC", "WH_XDG_OPEN"] | ||||||
|  |  | ||||||
|         html_content = f'<p style="line-height: 1.3; font-size: 9pt;">' |         html_content = f'<p style="line-height: 1.3; font-size: 9pt;">' | ||||||
|         html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>" |         html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>" | ||||||
| @@ -2635,6 +2910,15 @@ class WineHelperGUI(QMainWindow): | |||||||
|             html_content += "<br><b>Дополнительные параметры:</b><br>" |             html_content += "<br><b>Дополнительные параметры:</b><br>" | ||||||
|             html_content += other_vars_html |             html_content += other_vars_html | ||||||
|  |  | ||||||
|  |         html_content += "<br><b>Компоненты (Winetricks):</b> " | ||||||
|  |         if display_verbs: | ||||||
|  |             # Используем span вместо div, чтобы избежать лишних отступов | ||||||
|  |             html_content += '<span style="max-height: 120px; overflow-y: auto;">' | ||||||
|  |             html_content += ", ".join(html.escape(v) for v in display_verbs) | ||||||
|  |             html_content += '</span>' | ||||||
|  |         else: | ||||||
|  |             html_content += "Не установлены" | ||||||
|  |  | ||||||
|         html_content += "</p>" |         html_content += "</p>" | ||||||
|         self.prefix_info_display.setHtml(html_content) |         self.prefix_info_display.setHtml(html_content) | ||||||
|  |  | ||||||
| @@ -3075,17 +3359,44 @@ class WineHelperGUI(QMainWindow): | |||||||
|         help_subtabs = QTabWidget() |         help_subtabs = QTabWidget() | ||||||
|         help_layout.addWidget(help_subtabs) |         help_layout.addWidget(help_subtabs) | ||||||
|  |  | ||||||
|         # Подвкладка "Руководство" |         # Подвкладка "Общее" | ||||||
|         guide_tab = QWidget() |         general_tab = QWidget() | ||||||
|         guide_layout = QVBoxLayout(guide_tab) |         general_layout = QVBoxLayout(general_tab) | ||||||
|         guide_text = QTextBrowser() |         general_text = QTextBrowser() | ||||||
|         guide_text.setOpenExternalLinks(True) |         general_text.setOpenExternalLinks(True) | ||||||
|         guide_text.setHtml(""" |  | ||||||
|             <h2>Руководство пользователя</h2> |         try: | ||||||
|             <p>Подробное и актуальное руководство по использованию WineHelper смотрите на <a href="https://www.altlinux.org/Winehelper">https://www.altlinux.org/Winehelper</a></p> |             if not Var.GENERAL or not os.path.exists(Var.GENERAL): | ||||||
|         """) |                 raise FileNotFoundError | ||||||
|         guide_layout.addWidget(guide_text) |  | ||||||
|         help_subtabs.addTab(guide_tab, "Руководство") |             with open(Var.GENERAL, 'r', encoding='utf-8') as f: | ||||||
|  |                 general_content = f.read() | ||||||
|  |  | ||||||
|  |             html_content = "" | ||||||
|  |             url_re = re.compile(r'(https?://[^\s]+)') | ||||||
|  |  | ||||||
|  |             for line in general_content.splitlines(): | ||||||
|  |                 line = line.strip() | ||||||
|  |                 if not line: | ||||||
|  |                     html_content += "<br>" | ||||||
|  |                     continue | ||||||
|  |  | ||||||
|  |                 line = html.escape(line) | ||||||
|  |                 line = url_re.sub(r'<a href="\1">\1</a>', line) | ||||||
|  |  | ||||||
|  |                 if line.startswith('# '): | ||||||
|  |                     html_content += f'<h2>{line[2:]}</h2>' | ||||||
|  |                 elif line.startswith('Для '): | ||||||
|  |                     html_content += f'<p style="margin-left: 10px;">• {line}</p>' | ||||||
|  |                 else: | ||||||
|  |                     html_content += f'<p>{line}</p>' | ||||||
|  |  | ||||||
|  |             general_text.setHtml(html_content) | ||||||
|  |         except (FileNotFoundError, TypeError): | ||||||
|  |             general_text.setHtml(f'<h2>Ошибка</h2><p>Не удалось загрузить файл с общей информацией по пути:<br>{Var.GENERAL}</p>') | ||||||
|  |  | ||||||
|  |         general_layout.addWidget(general_text) | ||||||
|  |         help_subtabs.addTab(general_tab, "Общее") | ||||||
|  |  | ||||||
|         # Подвкладка "Авторы" |         # Подвкладка "Авторы" | ||||||
|         authors_tab = QWidget() |         authors_tab = QWidget() | ||||||
| @@ -3191,9 +3502,6 @@ class WineHelperGUI(QMainWindow): | |||||||
|         """Открывает диалог создания нового префикса.""" |         """Открывает диалог создания нового префикса.""" | ||||||
|         dialog = CreatePrefixDialog(self) |         dialog = CreatePrefixDialog(self) | ||||||
|         if dialog.exec_() == QDialog.Accepted: |         if dialog.exec_() == QDialog.Accepted: | ||||||
|             if not self._show_license_agreement_dialog(): |  | ||||||
|                 return |  | ||||||
|  |  | ||||||
|             self.start_prefix_creation( |             self.start_prefix_creation( | ||||||
|                 prefix_name=dialog.prefix_name, |                 prefix_name=dialog.prefix_name, | ||||||
|                 wine_arch=dialog.wine_arch, |                 wine_arch=dialog.wine_arch, | ||||||
| @@ -3410,11 +3718,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|                 self.current_selected_app['name'] = name |                 self.current_selected_app['name'] = name | ||||||
|                 self.current_selected_app['exec'] = exec_cmd |                 self.current_selected_app['exec'] = exec_cmd | ||||||
|  |  | ||||||
|                 # Состояния кнопки |                 self._set_run_button_state(desktop_path in self.running_apps) | ||||||
|                 if desktop_path in self.running_apps: |  | ||||||
|                     self.run_button.setText("Остановить") |  | ||||||
|                 else: |  | ||||||
|                     self.run_button.setText("Запустить") |  | ||||||
|  |  | ||||||
|                 # Показываем панель информации |                 # Показываем панель информации | ||||||
|                 self.info_panel.setVisible(True) |                 self.info_panel.setVisible(True) | ||||||
| @@ -3602,7 +3906,8 @@ class WineHelperGUI(QMainWindow): | |||||||
|         msg_box.setText( |         msg_box.setText( | ||||||
|             "Приложение будет запущено в режиме отладки.\n\n" |             "Приложение будет запущено в режиме отладки.\n\n" | ||||||
|             "После закрытия приложения лог будет сохранен в папке 'winehelper_backup_log' " |             "После закрытия приложения лог будет сохранен в папке 'winehelper_backup_log' " | ||||||
|             "в вашем домашнем каталоге под именем 'winehelper.log'." |             "в вашем домашнем каталоге под именем (пример: prefix_program.log).\n\n" | ||||||
|  |             "Продолжить?" | ||||||
|         ) |         ) | ||||||
|         msg_box.addButton(yes_button, QMessageBox.YesRole) |         msg_box.addButton(yes_button, QMessageBox.YesRole) | ||||||
|         msg_box.addButton(no_button, QMessageBox.NoRole) |         msg_box.addButton(no_button, QMessageBox.NoRole) | ||||||
| @@ -3644,6 +3949,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|         wine_executable = self._get_wine_executable_for_prefix(prefix_name) |         wine_executable = self._get_wine_executable_for_prefix(prefix_name) | ||||||
|         dialog = WinetricksManagerDialog(prefix_path, winetricks_path, self, wine_executable=wine_executable) |         dialog = WinetricksManagerDialog(prefix_path, winetricks_path, self, wine_executable=wine_executable) | ||||||
|  |         dialog.installation_complete.connect(lambda: self.update_prefix_info_display(prefix_name)) | ||||||
|         dialog.exec_() |         dialog.exec_() | ||||||
|  |  | ||||||
|     def _get_wine_executable_for_prefix(self, prefix_name): |     def _get_wine_executable_for_prefix(self, prefix_name): | ||||||
| @@ -3806,10 +4112,27 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|             # Если текущее выбранное приложение - то, что только что завершилось, обновляем кнопку |             # Если текущее выбранное приложение - то, что только что завершилось, обновляем кнопку | ||||||
|             if self.current_selected_app and self.current_selected_app.get('desktop_path') == desktop_path: |             if self.current_selected_app and self.current_selected_app.get('desktop_path') == desktop_path: | ||||||
|                 self.run_button.setText("Запустить") |                 self._set_run_button_state(False) | ||||||
|         else: |         else: | ||||||
|             print(f"Предупреждение: получен сигнал finished для неизвестного процесса {desktop_path}") |             print(f"Предупреждение: получен сигнал finished для неизвестного процесса {desktop_path}") | ||||||
|  |  | ||||||
|  |     def _set_run_button_state(self, is_running): | ||||||
|  |         """Устанавливает текст и стиль для кнопки Запустить/Остановить.""" | ||||||
|  |         if is_running: | ||||||
|  |             self.run_button.setText("Остановить") | ||||||
|  |             self.run_button.setStyleSheet(self.STOP_BUTTON_STYLE) | ||||||
|  |             self.create_log_button.setEnabled(False) | ||||||
|  |             self.backup_button.setEnabled(False) | ||||||
|  |             self.uninstall_button.setEnabled(False) | ||||||
|  |             self.restore_prefix_button_panel.setEnabled(False) | ||||||
|  |         else: | ||||||
|  |             self.run_button.setText("Запустить") | ||||||
|  |             self.run_button.setStyleSheet(self.RUN_BUTTON_STYLE) | ||||||
|  |             self.create_log_button.setEnabled(True) | ||||||
|  |             self.backup_button.setEnabled(True) | ||||||
|  |             self.uninstall_button.setEnabled(True) | ||||||
|  |             self.restore_prefix_button_panel.setEnabled(True) | ||||||
|  |  | ||||||
|     def _run_app_launcher(self, debug=False): |     def _run_app_launcher(self, debug=False): | ||||||
|         """Внутренний метод для запуска приложения (с отладкой или без) с использованием QProcess.""" |         """Внутренний метод для запуска приложения (с отладкой или без) с использованием QProcess.""" | ||||||
|         if not self.current_selected_app or 'exec' not in self.current_selected_app: |         if not self.current_selected_app or 'exec' not in self.current_selected_app: | ||||||
| @@ -3876,7 +4199,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|                     raise RuntimeError(f"Не удалось запустить процесс: {process.errorString()}") |                     raise RuntimeError(f"Не удалось запустить процесс: {process.errorString()}") | ||||||
|  |  | ||||||
|                 self.running_apps[desktop_path] = process |                 self.running_apps[desktop_path] = process | ||||||
|                 self.run_button.setText("Остановить") |                 self._set_run_button_state(True) | ||||||
|                 print(f"Запущено: {program} {' '.join(arguments)}") |                 print(f"Запущено: {program} {' '.join(arguments)}") | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 QMessageBox.critical(self, "Ошибка запуска", |                 QMessageBox.critical(self, "Ошибка запуска", | ||||||
| @@ -4154,6 +4477,8 @@ class WineHelperGUI(QMainWindow): | |||||||
|         if script_name in self.autoinstall_scripts: |         if script_name in self.autoinstall_scripts: | ||||||
|             script_path = os.path.join(Var.DATA_PATH, "autoinstall", script_name) |             script_path = os.path.join(Var.DATA_PATH, "autoinstall", script_name) | ||||||
|             tab_type = 'auto' |             tab_type = 'auto' | ||||||
|  |             if not os.path.exists(script_path): # Проверяем в testinstall, если не нашли в autoinstall | ||||||
|  |                 script_path = os.path.join(Var.DATA_PATH, "testinstall", script_name) | ||||||
|             self.manual_install_path_widget.setVisible(False) |             self.manual_install_path_widget.setVisible(False) | ||||||
|         else: |         else: | ||||||
|             script_path = os.path.join(Var.DATA_PATH, "manualinstall", script_name) |             script_path = os.path.join(Var.DATA_PATH, "manualinstall", script_name) | ||||||
| @@ -4319,7 +4644,9 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|         winehelper_path = self.winehelper_path |         winehelper_path = self.winehelper_path | ||||||
|         script_path = os.path.join(Var.DATA_PATH, |         script_path = os.path.join(Var.DATA_PATH, | ||||||
|                                    "autoinstall" if self.current_script in self.autoinstall_scripts else "manualinstall", |                                    "autoinstall" if os.path.exists(os.path.join(Var.DATA_PATH, "autoinstall", self.current_script)) | ||||||
|  |                                    else "testinstall" if os.path.exists(os.path.join(Var.DATA_PATH, "testinstall", self.current_script)) | ||||||
|  |                                    else "manualinstall", | ||||||
|                                    self.current_script) |                                    self.current_script) | ||||||
|  |  | ||||||
|         if not os.path.exists(winehelper_path): |         if not os.path.exists(winehelper_path): | ||||||
| @@ -4636,6 +4963,7 @@ class WineHelperGUI(QMainWindow): | |||||||
|             self.command_process.deleteLater() |             self.command_process.deleteLater() | ||||||
|             self.command_process = None |             self.command_process = None | ||||||
|         self.command_close_button.setEnabled(True) |         self.command_close_button.setEnabled(True) | ||||||
|  |         self.command_log_output.ensureCursorVisible() | ||||||
|  |  | ||||||
|     def _handle_launcher_creation_finished(self, exit_code, exit_status): |     def _handle_launcher_creation_finished(self, exit_code, exit_status): | ||||||
|         """Обрабатывает завершение создания ярлыка.""" |         """Обрабатывает завершение создания ярлыка.""" | ||||||
| @@ -4727,7 +5055,7 @@ def main(): | |||||||
|         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 |     return 1 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user