Compare commits

...

37 Commits

Author SHA1 Message Date
Mikhail Tergoev
dfc6c1c836 added var WH_ICON_TRAY path to winehelper-symbolic.svg 2025-10-21 15:09:46 +03:00
Mikhail Tergoev
04187e9463 GUI: updated compatibility links and certificates 2025-10-21 15:00:53 +03:00
Mikhail Tergoev
5f915ab58d Merge branch 'minergenon-devel' 2025-10-21 14:11:22 +03:00
Sergey Palcheh
0e8ee7788a fixed: the Delete all WineHelper data button is active by default 2025-10-21 14:45:27 +06:00
Sergey Palcheh
49c1ac6846 fixed the text color change after an error in the log 2025-10-21 14:36:47 +06:00
Mikhail Tergoev
971bcd0f5a wine_run: added automatic detection of .reg and .dll 2025-10-21 11:30:48 +03:00
Sergey Palcheh
5b21015aee added compatibility links and certificates 2025-10-21 12:25:53 +06:00
Mikhail Tergoev
7dee08bcfb updated changelog to 0.7.0 2025-10-20 15:30:47 +03:00
Mikhail Tergoev
633deaf1c1 hided abc-*, ais and commfort-* scripts 2025-10-20 15:28:21 +03:00
Mikhail Tergoev
4df9508547 Merge branch 'minergenon-devel' 2025-10-20 15:07:30 +03:00
Sergey Palcheh
989f04cdd8 added a test list to the auto-installation 2025-10-20 17:59:40 +06:00
Mikhail Tergoev
95b189f5a2 less in used for print install list 2025-10-20 14:16:54 +03:00
Mikhail Tergoev
371553277a added WH_TESTINSTALL_DIR to scripts list 2025-10-20 13:09:42 +03:00
Mikhail Tergoev
dabf50103d hided unverifed install scripts 2025-10-20 12:45:39 +03:00
Mikhail Tergoev
590b37f1a3 rename var: INSTALL_MODE -> WH_INSTALL_MODE 2025-10-20 12:43:52 +03:00
Mikhail Tergoev
1f9b4a9146 added more info for daobit-cservice 2025-10-20 12:40:31 +03:00
Mikhail Tergoev
39f21373f1 added version for spravki-bk 2025-10-20 12:39:48 +03:00
Mikhail Tergoev
e984ffdb8c fixed: always return to DRIVE_C 2025-10-20 11:43:19 +03:00
Mikhail Tergoev
48834dc078 Merge branch 'minergenon-devel' 2025-10-20 11:35:11 +03:00
Sergey Palcheh
b62d06ed71 fixed typos 2025-10-19 15:39:43 +06:00
Sergey Palcheh
9a1b78276e added button lock in the Installed tab when the Run button is pressed 2025-10-18 16:52:22 +06:00
Sergey Palcheh
f788307f05 added color for the Run button/Stop it 2025-10-18 16:39:22 +06:00
Sergey Palcheh
14273f723b the error of determining the current directory has been fixed 2025-10-18 16:24:06 +06:00
Mikhail Tergoev
a8e0fdce0a added var: WH_DEVEL 2025-10-17 15:34:29 +03:00
Mikhail Tergoev
da3d5cd7af refactored master func: wine_run 2025-10-17 13:55:55 +03:00
Mikhail Tergoev
3ee499c758 Merge branch 'minergenon-devel' 2025-10-17 11:41:20 +03:00
Mikhail Tergoev
6286cccbab fixed typos 2025-10-17 11:39:44 +03:00
Mikhail Tergoev
e8d462b665 Merge branch 'minergenon-tflex18' 2025-10-17 11:38:57 +03:00
Sergey Palcheh
6476a84ce7 increased the width of the application button panel 2025-10-17 10:52:23 +06:00
Sergey Palcheh
db7e3f5220 added autoinstall:
t-flex-cad18-applications
t-flex-cad18-resources
t-flex-cad2d+18
t-flex-viewer18
2025-10-17 10:08:09 +06:00
Mikhail Tergoev
a817d1a6f5 added UNIX path conversion 2025-10-16 21:25:58 +03:00
Mikhail Tergoev
e1fc25bb72 used tmp_winedlloverride_update in scadoffice script 2025-10-16 11:14:48 +03:00
Mikhail Tergoev
7c90da2088 added func: tmp_winedlloverride_update 2025-10-16 11:13:58 +03:00
Sergey Palcheh
108316148a added a unique name for the application startup log being created 2025-10-16 12:54:21 +06:00
Mikhail Tergoev
9029f4d0e8 added autoinstall ksamu (without CryptoPro) 2025-10-15 13:18:42 +03:00
Mikhail Tergoev
cedebe73c1 fixed long wait after installing 2025-10-15 13:17:06 +03:00
Mikhail Tergoev
e04811446c added script for T-FLEX CAD 18 2025-10-14 17:46:29 +03:00
33 changed files with 542 additions and 123 deletions

View File

@@ -1,5 +1,16 @@
История изменений: История изменений:
0.7.0
* обновлен графический режим Qt5
- добавлена кнопка открытия каталога с резервными копиями и логами
- добавлена кнопка открытия каталога с префиксом
- добавлена блокировка кнопок для установленного приложения, если оно уже запущено
- добавлено отображения процесса установки сторонних компонентов с помощью winetricks
- добавлена возможность отображения и установки тестовых скриптов (выключено по умолчанию)
* добавлены скрипты установки для t-flex версии 18
* добавлен список тестовых скриптов установки ПО
* добавлена возможность ассоциации файлов для передачи в приложения запускаемых в WineHelper
0.6.0 0.6.0
* обновлен графический режим Qt5 * обновлен графический режим Qt5
* добавлен иконка в трее для графического режима Qt5 * добавлен иконка в трее для графического режима Qt5

View File

@@ -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"

View File

@@ -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
View 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

View 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}"

View 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}"

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -218,3 +218,8 @@ dfb44ce5e5af7dba1686932c63d6b05e5dd6919a21c78130a7d1d0271b93958e audiorecstatio
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

17
testinstall/ksamu Normal file
View 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"

View File

@@ -62,6 +62,8 @@ 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"
# временно запрещаем запуск hasplms.exe, hasplmv.exe для успешного завершения установки
tmp_winedlloverride_update "hasplms.exe,hasplmv.exe=d"
wine_run_install "$AUTOINSTALL_EXE" wine_run_install "$AUTOINSTALL_EXE"
try_remove_file "$AUTOINSTALL_EXE" try_remove_file "$AUTOINSTALL_EXE"

View File

@@ -17,6 +17,7 @@ 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"
@@ -28,9 +29,11 @@ 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"
WH_DEVEL="1"
# минимальная проверка синтаксиса скриптов # минимальная проверка синтаксиса скриптов
for self_check_script in "$RUN_SCRIPT" \ for self_check_script in "$RUN_SCRIPT" \
@@ -101,16 +104,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"
@@ -485,6 +478,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}"
@@ -1287,7 +1284,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
@@ -1348,23 +1346,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
@@ -1389,40 +1389,89 @@ prepair_wine () {
[[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud" [[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud"
} }
wine_run () { wine_regfile () {
if [[ $WINEARCH == "win32" ]] \ print_info "Запускаем команду: $WINELOADER $@"
&& file "$WIN_FILE_EXEC" | grep -q "x86-64" "$WINELOADER" "$@" && print_ok "Выполнено." || fatal "Не выполнено: $WINELOADER $@"
then fatal "Нельзя запустить 64-битное приложение в 32-битном префиксе!"
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
$MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS
fi
wait_wineserver 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 () {
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" ]] \
&& file "$win_file_exec" | grep -q "x86-64"
then fatal "Нельзя запустить 64-битное приложение в 32-битном префиксе!"
fi
else
fatal "Команда введена не правильно или не найден исполняемый файл $1"
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
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 () {
@@ -1440,46 +1489,49 @@ 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 '
FNR==1 {
awk ' if (progname) {
FNR==1 { printf "\n%s - %s\n%s\n", filename, progname, info
if (progname) { }
printf "\n%s - %s\n%s\n", filename, progname, info progname=""; info=""; filename=FILENAME
sub(".*/", "", filename)
} }
progname=""; info=""; filename=FILENAME /info_ru:/ { sub(/.*info_ru: /, ""); info=$0 }
sub(".*/", "", filename) /PROG_NAME=/ { sub(/.*PROG_NAME=/, ""); progname=$0 }
} END {
/info_ru:/ { sub(/.*info_ru: /, ""); info=$0 } if (progname) {
/PROG_NAME=/ { sub(/.*PROG_NAME=/, ""); progname=$0 } printf "\n%s - %s\n%s\n", filename, progname, info
END { }
if (progname) {
printf "\n%s - %s\n%s\n", filename, progname, info
} }
} ' "$parse_dir"/*
' "$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" ]]
@@ -2151,20 +2203,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
@@ -2172,21 +2225,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
@@ -2194,15 +2253,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
} }
@@ -2221,9 +2285,7 @@ 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."
} }
@@ -2263,7 +2325,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
@@ -2309,12 +2372,14 @@ case "$arg1" in
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

View File

@@ -14,7 +14,7 @@ from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QH
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, pyqtSignal from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve, pyqtSignal
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor, QTextCharFormat
from PyQt5.QtNetwork import QLocalServer, QLocalSocket from PyQt5.QtNetwork import QLocalServer, QLocalSocket
@@ -870,6 +870,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
@@ -1622,10 +1625,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
@@ -1668,8 +1695,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()
@@ -1764,8 +1791,11 @@ 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>"
"<br><h3>Совместимость с дистрибутивами Альт</h3>"
"<p>С полным списком совместимого ПО и сертификатами (не только для WineHelper) можно ознакомиться по следующим ссылкам:<br>"
"<a href='https://www.basealt.ru/fileadmin/user_upload/compatibility/P10-view2.html'>Для 10 платформы</a> | <a href='https://www.basealt.ru/fileadmin/user_upload/compatibility/P11-view2.html'>Для 11 платформы</a></p>")
show_global = False show_global = False
elif tab_name == "Ручная установка": elif tab_name == "Ручная установка":
title = "Ручная установка" title = "Ручная установка"
@@ -1889,6 +1919,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)
@@ -2052,14 +2083,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
@@ -2073,7 +2104,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()
@@ -2083,12 +2120,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):
""" """
Создает стандартную вкладку с полем поиска и сеточным макетом с прокруткой. Создает стандартную вкладку с полем поиска и сеточным макетом с прокруткой.
Возвращает кортеж (главный виджет вкладки, сеточный макет, поле поиска, область прокрутки). Возвращает кортеж (главный виджет вкладки, сеточный макет, поле поиска, область прокрутки).
@@ -2122,11 +2159,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)
v_scroll_layout.addStretch(1) if add_stretch:
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):
""" """
Создает и заполняет вкладку для установки (автоматической или ручной). Создает и заполняет вкладку для установки (автоматической или ручной).
Возвращает кортеж со скриптами, кнопками и виджетами. Возвращает кортеж со скриптами, кнопками и виджетами.
@@ -2136,15 +2174,16 @@ class WineHelperGUI(QMainWindow):
) )
scripts = [] scripts = []
script_path = os.path.join(Var.DATA_PATH, script_folder)
if os.path.isdir(script_path):
try:
scripts = sorted(os.listdir(script_path))
except OSError as e:
print(f"Не удалось прочитать директорию {script_path}: {e}")
buttons_list = [] buttons_list = []
self._populate_install_grid(grid_layout, scripts, script_folder, buttons_list) for folder in script_folders:
script_path = os.path.join(Var.DATA_PATH, folder)
if os.path.isdir(script_path):
try:
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:
print(f"Не удалось прочитать директорию {script_path}: {e}")
self.add_tab(tab_widget, tab_title) self.add_tab(tab_widget, tab_title)
@@ -2156,30 +2195,89 @@ 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
} }
# Добавляем чекбокс для тестовых версий
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):
"""Создает вкладку для ручной установки программ""" """Создает вкладку для ручной установки программ"""
( (
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
script_folders = ["autoinstall"]
if data['test_checkbox'].isChecked():
script_folders.append("testinstall")
# Перед удалением кнопок останавливаем все связанные с ними таймеры анимации
for btn in data['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 self.current_active_button in data['buttons']:
self.current_active_button = None
# Очищаем старые кнопки и layout
for btn in data['buttons']:
btn.parent().deleteLater()
data['buttons'].clear()
# Заполняем layout новыми кнопками
scripts = []
for folder in script_folders:
script_path = os.path.join(Var.DATA_PATH, folder)
if os.path.isdir(script_path):
try:
folder_scripts = sorted(os.listdir(script_path))
self._populate_install_grid(data['layout'], folder_scripts, folder, data['buttons'])
scripts.extend(folder_scripts)
except OSError as e:
print(f"Не удалось прочитать директорию {script_path}: {e}")
self.autoinstall_scripts = scripts
# Применяем текущий фильтр поиска к обновленному списку
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, "Установленные")
@@ -2421,7 +2519,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)
@@ -2437,7 +2535,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:
@@ -3468,11 +3566,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)
@@ -3660,7 +3754,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)
@@ -3865,10 +3960,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:
@@ -3935,7 +4047,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, "Ошибка запуска",
@@ -4213,6 +4325,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)
@@ -4378,7 +4492,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):