@ -29,6 +29,9 @@ else
check_variables DEBUG "0"
fi
##### WINETRICKS VERSION #####
WINETRICKS_VERSION="20250102"
##### DEFAULT VARIABLES #####
SCRIPT_NAME="$(basename "$0")"
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
@ -50,6 +53,7 @@ WH_IMAGE_PATH="$DATA_PATH/image"
WH_DB_DIR="$DATA_PATH/database"
WH_AUTOINSTALL_DIR="$DATA_PATH/autoinstall"
WH_MANUALINSTALL_DIR="$DATA_PATH/manualinstall"
WH_WINETRICKS="$DATA_PATH/winetricks_$WINETRICKS_VERSION"
WH_MENU_DIR="$HOME/.local/share/applications/WineHelper"
WH_MENU_CATEGORY="$HOME/.local/share/desktop-directories/WineHelper.directory"
@ -63,6 +67,9 @@ check_variables WINEFSYNC "0"
check_variables WINEARCH "win64" # or "win32"
check_variables WH_WINE_USE "wine_x_tkg_10-0_amd64" # or system
check_variables WH_USE_CPCSP_PROXY "0"
check_variables CPCSP_PROXY_VER "0.6.1-alt1"
check_variables STAGING_SHARED_MEMORY "1"
check_variables WINE_LARGE_ADDRESS_AWARE "1"
check_variables WINE_FULLSCREEN_FSR "1"
@ -99,19 +106,15 @@ fi
##### ROOT #####
su_run () {
print_info "Для продолжения установки зависимостей введите root пароль..."
print_info "Для продолжения установки введите root пароль..."
su - -c "$@"
}
##### CHECK DEPENDENCIES #####
# yad zenity cups-pdf
if rpm -q {i586-,}{wine,glibc-core,libstdc++6,glibc-pthread,glibc-nss,libOSMesa,\
if ! rpm -q {i586-,}{wine,glibc-core,libstdc++6,glibc-pthread,glibc-nss,libOSMesa,\
libnss-mdns,libunixODBC2,ocl-icd,libfreetype,libfontconfig1,libgnutls30,libGL,\
libEGL,xorg-dri-swrast,xorg-dri-intel,xorg-dri-radeon,libvulkan1,libcups} \
winetricks ca-certificates cups-pdf 1>/dev/null
then : # Зависимости установлены. Пропускаем...
else
libEGL,xorg-dri-swrast,xorg-dri-intel,xorg-dri-radeon,libvulkan1,libcups} 1>/dev/null
then
if su_run "$DATA_PATH/dependencies.sh"
then print_info "Зависимости успешно установлены. Продолжаем работу $SCRIPT_NAME"
else fatal "Н е удалось установить зависимости. Работа $SCRIPT_NAME прервана."
@ -119,15 +122,6 @@ else
fi
##### HELPER FUNCTIONS #####
check_command () {
if command -v "$1" &>/dev/null ; then
return 0
else
print_warning "command: $1 - not found!"
return 1
fi
}
add_to_var () {
if ! echo ${!1} | grep "$2" &>/dev/null
then export $1="${!1} $2"
@ -155,9 +149,9 @@ try_remove_dir () {
}
try_copy_file () {
if [[ ! -f "$1" ]] ; then print_info "file $1 not found for copy " && return 1
elif [[ -z "$2" ]] ; then print_error "no way to copy file $1" && return 1
elif [[ -L "$2" ]] ; then print_warning "$2 is a file with a symbolic link"
if [[ ! -f "$1" ]] ; then print_info "файла $1 не существует для копирования " && return 1
elif [[ -z "$2" ]] ; then fatal "нет пути для копирования файла $1"
elif [[ -L "$2" ]] ; then
try_remove_file "$2"
cp -f "$1" "$2" && return 0 || return 1
else
@ -167,24 +161,24 @@ try_copy_file () {
}
try_copy_dir () {
if [[ ! -d "$1" ]] ; then print_info "directory $1 not found for copy "
elif [[ -z "$2" ]] ; then print_error "no way to copy directory $1"
if [[ ! -d "$1" ]] ; then print_info "каталога $1 не существует для копирования "
elif [[ -z "$2" ]] ; then fatal "нет пути для копирования каталога $1"
else
cp -fr "$1" "$2"
[[ "$?" != 0 ]] && print_error "failed to copy directory $1 to $2" || return 0
[[ "$?" != 0 ]] && print_error "не удалось скопировать каталог $1 в $2" || return 0
fi
return 1
}
try_force_link_file () {
if [[ ! -f "$1" ]] ; then
print_warning "file not found for link : $1"
print_warning "нет файла для создания символьной ссылки : $1"
if [[ -f "$2" ]] ; then
try_remove_file "$2"
print_warning "removed old link : $2"
print_warning "удаляем символьную ссылку : $2"
fi
return 1
elif [[ -z "$2" ]] ; then print_error "no way to link file $1" && return 1
elif [[ -z "$2" ]] ; then fatal "нет пути для создания символьной ссылки на файл $1"
else
try_remove_file "$2"
ln -s -f -r "$1" "$2"
@ -193,25 +187,12 @@ try_force_link_file () {
return 1
}
check_symlink () {
local CHK_SYMLINK_FILE="$(file "$1")"
if [[ -n "$(echo "$CHK_SYMLINK_FILE" | grep -v "broken" | grep "symbolic link to" | awk '{print $1}')" ]] ; then
return 0
elif [[ -n "$(echo "$CHK_SYMLINK_FILE" | grep "broken symbolic link to" | awk '{print $1}')" ]] ; then
print_error "remove broken symlink: $CHK_SYMLINK_FILE"
rm -fr "$CHK_SYMLINK_FILE"
return 1
else
return 1
fi
}
try_force_link_dir () {
if [[ ! -d "$1" ]] ; then print_info "directory $1 not found for link "
elif [[ -z "$2" ]] ; then print_error "no way to link directory $1"
if [[ ! -d "$1" ]] ; then print_info "каталога $1 не существует для создания символьной сссылки "
elif [[ -z "$2" ]] ; then fatal "не указан путь для создания символьной ссылки на каталог $1"
else
ln -s -f -r "$1" "$2"
[[ "$?" != 0 ]] && print_error "failed to link directory $1 to $2" || return 0
[[ "$?" != 0 ]] && print_error "не удалось сделать символьную ссылку на каталог $1 по пути $2" || return 0
fi
return 1
}
@ -311,7 +292,6 @@ try_copy_wine_dll_to_pfx_32() {
fi
}
##### OVERRIDE VARIABLES FUNCTIONS #####
var_winedlloverride_update () {
if [[ -n "${WINEDLLOVERRIDES}" ]]
then export WINEDLLOVERRIDES="${1};${WINEDLLOVERRIDES}"
@ -357,7 +337,6 @@ var_ld_library_path_update () {
return 0
}
##### CREATE DESKTOP FILE #####
create_desktop () {
local name_desktop="$1"
local exe_file="$2"
@ -384,11 +363,9 @@ create_desktop () {
fi
fi
create_new_dir "$WH_MENU_DIR"
[[ ! -f "$icon_file" ]] && icon_file=wine
# создаем .desktop файл
create_new_dir "$WH_MENU_DIR"
[[ ! -f "$icon_file" ]] && icon_file=wine
{
echo "[Desktop Entry]"
echo "Name=$name_desktop"
@ -403,9 +380,9 @@ create_desktop () {
cp -f "$USER_WORK_PATH/$desktop_filename.desktop" "$WH_MENU_DIR/"
# добавляем информацию о приложении в "$WINEPREFIX/desktop.list"
if grep -qe "^${name_desktop}=" "$WINEPREFIX/desktop.list"
if [[ -f "$WINEPREFIX/desktop.list" ]] \
&& grep -qe "^${name_desktop}=" "$WINEPREFIX/desktop.list"
then sed -i "/^$name_desktop=/d" "$WINEPREFIX/desktop.list"
fi
echo "$name_desktop=${exe_file//$WINEPREFIX/}" >> "$WINEPREFIX/desktop.list"
@ -441,9 +418,7 @@ EOF
fi
# Обновляем кэш desktop файлов
if check_command update-desktop-database ; then
update-desktop-database "$HOME/.local/share/applications"
fi
update-desktop-database "$HOME/.local/share/applications"
if [[ $4 != "nocopy" ]] ; then
if [[ -n $4 ]] ; then
@ -473,7 +448,6 @@ EOF
fi
}
##### REMOVE DESKTOP FILE #####
remove_desktop () {
if [[ -n "$1" ]] ; then
try_remove_file "$USER_WORK_PATH/$1.desktop"
@ -490,12 +464,10 @@ remove_desktop () {
fi
# Обновляем кэш desktop файлов
if check_command update-desktop-database ; then
update-desktop-database "$HOME/.local/share/applications"
fi
update-desktop-database "$HOME/.local/share/applications"
}
##### INSTALLED PROGRAMS #####
check_installed_programs () {
for desktop_file in "$USER_WORK_PATH"/*.desktop ; do
if [[ ! -f "$desktop_file" ]] ; then
@ -534,7 +506,6 @@ run_installed_programs () {
fi
}
##### USED WINED3D LIBRARY #####
init_wined3d () {
if [[ "$USE_RENDERER" != "proton" ]] ; then
WINED3D_FILES="d3d8 d3d9 d3d10_1 d3d10 d3d10core d3d11 dxgi d3d12 d3d12core"
@ -552,7 +523,6 @@ init_wined3d () {
fi
}
##### CHECK VULKAN LIBRARY #####
init_dxvk () {
check_variables USE_DXVK_VER "$1"
@ -620,27 +590,19 @@ init_vkd3d () {
done
}
##### DOWNLOAD WINE #####
download_wine () {
if [[ ! -d "$WH_DIST_DIR/$WH_WINE_USE" ]] ; then
WINE_URL="$CLOUD_URL/$WH_WINE_USE.tar.xz"
local WINE_PACKAGE="$WH_TMP_DIR/${WH_WINE_USE}.tar.xz"
if try_download "$WINE_URL" "$WINE_PACKAGE" check256sum ; then
if unpack "$WINE_PACKAGE" "$WH_DIST_DIR/" ; then
echo "$WH_WINE_USE" > "$WH_DIST_DIR/$WH_WINE_USE/version"
try_remove_file "$WINE_PACKAGE"
fi
fi
fi
}
##### INITIAL WINE SETTINGS #####
init_wine_ver () {
if [[ "$WH_WINE_USE" != system* ]] ; then
export WINEDIR="$WH_DIST_DIR/$WH_WINE_USE"
if [[ ! -d "$WINEDIR" ]] ; then
download_wine
WINE_URL="$CLOUD_URL/$WH_WINE_USE.tar.xz"
local WINE_PACKAGE="$WH_TMP_DIR/${WH_WINE_USE}.tar.xz"
if try_download "$WINE_URL" "$WINE_PACKAGE" check256sum ; then
if unpack "$WINE_PACKAGE" "$WH_DIST_DIR/" ; then
echo "$WH_WINE_USE" > "$WH_DIST_DIR/$WH_WINE_USE/version"
try_remove_file "$WINE_PACKAGE"
fi
fi
fi
export WINE="${WINEDIR}/bin/wine"
@ -663,7 +625,14 @@ init_wine_ver () {
export GST_PLUGIN_SYSTEM_PATH_1_0="${WINEDIR}/lib/gstreamer-1.0"
fi
if [[ "${WINEARCH}" == "win64" ]] ; then
[[ ! -f "${WINEDIR}/version" ]] && echo "${WH_WINE_USE}" > "${WINEDIR}/version"
if [[ ! -d "${WINEDIR}/lib64/wine" ]] && [[ -d "${WINEDIR}/lib/wine/x86_64-unix" ]] ; then
create_new_dir "${WINEDIR}/lib64/"
try_force_link_dir "${WINEDIR}/lib/wine/" "${WINEDIR}/lib64/"
fi
if [[ -d "${WINEDIR}/lib64" ]] ; then
export LD_LIBRARY_PATH+=":${WINEDIR}/lib64"
export WINEDLLPATH+=":${WINEDIR}/lib64/wine"
if [[ -d "${WINEDIR}/lib64/gstreamer-1.0" ]] ; then
@ -671,12 +640,28 @@ init_wine_ver () {
fi
fi
[[ ! -f "${WINEDIR}/version" ]] && echo "${WH_WINE_USE}" > "${WINEDIR}/version"
if [[ $WH_USE_CPCSP_PROXY == "1" ]] \
&& ! grep -q "$CPCSP_PROXY_VER" "${WINEDIR}/cpcsp_proxy.ver"
then
CPCSP_PROXY_NAME="wine-cpcsp_proxy-$CPCSP_PROXY_VER"
CPCSP_PROXY_URL="$CLOUD_URL/$CPCSP_PROXY_NAME.tar.xz"
if [[ ! -d "${WINEDIR}/lib64/" ]] && [[ -d "${WINEDIR}/lib/wine/x86_64-unix " ]] ; then
create_new_dir "${WINEDIR}/lib64/wine "
mv -f "${WINEDIR}/lib/wine/x86_64-unix" "${WINEDIR}/lib64/wine/"
mv -f "${WINEDIR}/lib/wine/x86_64-windows" "${WINEDIR}/lib64/wine/ "
if [[ ! -f "$WH_TMP_DIR/$CPCSP_PROXY_NAME " ]] ; then
print_info "Загрузка $CPCSP_PROXY_NAME.tar.xz "
if try_download "$CPCSP_PROXY_URL" "$WH_TMP_DIR/$CPCSP_PROXY_NAME.tar.xz" check256sum
then unpack "$WH_TMP_DIR/$CPCSP_PROXY_NAME.tar.xz" "$WH_TMP_DIR "
else try_remove_file "$WH_TMP_DIR/$CPCSP_PROXY_NAME.tar.xz"
fi
else
unpack "$WH_TMP_DIR/$CPCSP_PROXY_NAME.tar.xz" "$WH_TMP_DIR"
fi
cp -fr "$WH_TMP_DIR/$CPCSP_PROXY_NAME/"i386-* "${WINEDIR}/lib/wine/"
if [[ -d "${WINEDIR}/lib64" ]] ; then
cp -fr "$WH_TMP_DIR/$CPCSP_PROXY_NAME/"x86_64-* "${WINEDIR}/lib64/wine/"
fi
try_remove_dir "$WH_TMP_DIR/$CPCSP_PROXY_NAME"
echo "$CPCSP_PROXY_VER" > "${WINEDIR}/cpcsp_proxy.ver"
fi
else
# use system WINE
@ -712,9 +697,8 @@ init_wine_ver () {
print_info "Используется версия wine: $WH_WINE_USE"
}
##### INITIAL WINEPREFIX SETTINGS #####
get_and_set_reg_file () {
convert_dec_and_hex () {
local type=$1
local num=$2
@ -822,10 +806,6 @@ get_and_set_reg_file () {
}
wait_wineserver () {
# while [[ -n "$(ls -l /proc/*/exe 2>/dev/null | grep -ie portproton | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')" ]] ; do
# sleep 1
# done
"$WINESERVER" -w
}
@ -880,7 +860,7 @@ check_prefix_var () {
print_info "Выбран префикс: $WINEPREFIX"
fi
if echo "$WINEPREFIX" | grep -v '/' ; then
if echo "$WINEPREFIX" | grep -q v '/' ; then
export WINEPREFIX="$WH_PREFIXES_DIR/$WINEPREFIX"
fi
@ -906,8 +886,8 @@ init_wineprefix () {
fi
print_info "Обновление префикса $WINEPREFIX."
if [[ -d "$WINEPREFIX/drive_c/windows" ]]
then env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" wineboot -u
else env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" wineboot -i
then "$WINELOADER" wineboot -u
else "$WINELOADER" wineboot -i
fi
touch "$WINEPREFIX/.firstboot"
wait_wineserver
@ -920,7 +900,7 @@ init_wineprefix () {
&& [[ "$WINEARCH" != "win32" ]]
then export WH_WINDOWS_VER="xp64"
fi
env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" winecfg -v $(echo "win${WH_WINDOWS_VER}" | sed 's/.*/\L&/')
"$WINELOADER" winecfg -v $(echo "win${WH_WINDOWS_VER}" | sed 's/.*/\L&/')
wait_wineserver
print_info "Windows версия изменена на win${WH_WINDOWS_VER}"
fi
@ -984,6 +964,29 @@ init_wineprefix () {
try_remove_file "$WRAPPER"
fi
# настраиваем префикс для работы с cpcsp_proxy
if [[ $WH_USE_CPCSP_PROXY == "1" ]] ; then
for cpcsp_proxy_file in "cpcsp_proxy.dll" "cpcsp_proxy_setup.exe" ; do
try_copy_wine_dll_to_pfx_64 "$cpcsp_proxy_file"
try_copy_wine_dll_to_pfx_32 "$cpcsp_proxy_file"
done
if ! grep -q "cpcsp_proxy.dll" "$WINEPREFIX/system.reg" ; then
if [[ "$WINEARCH" == "win32" ]]
then cpcsp_proxy_cmd=("$WINELOADER" "cpcsp_proxy_setup.exe")
else cpcsp_proxy_cmd=("${WINELOADER}64" "cpcsp_proxy_setup.exe")
fi
print_info "Запускаем настройку cpcsp_proxy:"
echo "${cpcsp_proxy_cmd[*]}"
if "${cpcsp_proxy_cmd[@]}"
then print_info "Настройка cpcsp_proxy успешно завершена."
else fatal "Ошибка во время настройки cpcsp_proxy."
fi
wait_wineserver
fi
fi
echo "# переменные последнего использования префикса:" > "$WINEPREFIX/last.conf"
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 \
@ -993,7 +996,6 @@ init_wineprefix () {
done
}
##### KILL AUTOSTART AFTER INSTALLING #####
kill_autostart () {
[[ -z "${1}" ]] && fatal "Нет аргумента для функции kill_autostart."
[[ -z "${2}" ]] && SWAIT=3 || SWAIT="${2}"
@ -1010,25 +1012,6 @@ kill_autostart () {
done
}
update_winetricks () {
W_TRX_URL="https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks"
W_TRX_EXT_VER="$(curl -s --list-only "$W_TRX_URL" | grep -i 'WINETRICKS_VERSION=' | sed 's/WINETRICKS_VERSION=//')"
print_info "Актуальная версия winetricks: $W_TRX_EXT_VER"
if [[ -f "$WH_TMP_DIR/winetricks" ]] ; then
W_TRX_INT_VER="$(cat "$WH_TMP_DIR/winetricks" | grep -i 'WINETRICKS_VERSION=' | sed 's/WINETRICKS_VERSION=//')"
print_info "Установленная портативная версия winetricks: $W_TRX_INT_VER"
fi
if [[ -n "$W_TRX_EXT_VER" ]] && [[ "$W_TRX_INT_VER" != "$W_TRX_EXT_VER" ]] ; then
if try_download "$W_TRX_URL" "$WH_TMP_DIR/winetricks_new" ; then
mv -f "$WH_TMP_DIR/winetricks_new" "$WH_TMP_DIR/winetricks"
W_TRX_INT_VER="$(cat "$WH_TMP_DIR/winetricks" | grep -i 'WINETRICKS_VERSION=' | sed 's/_VERSION=//')"
print_info "Портативная версия winetricks обновлена до (${W_TRX_INT_VER})"
chmod u+x "$WH_TMP_DIR/winetricks"
fi
fi
export WINETRICKS="$WH_TMP_DIR/winetricks"
}
use_winetricks () {
if [[ -n "$INSTALL_DLL" ]] ; then
WH_DLL_INSTALL="$(echo "$INSTALL_DLL $WH_DLL_INSTALL" | awk '{ for(i=1;i<=NF;i++){a[$i]++} }END{ for(i in a){printf("%s ",i)} }' )"
@ -1051,13 +1034,11 @@ use_winetricks () {
fi
done
if [[ "$USE_WT_FROM_DB" == "1" ]] ; then
if update_winetricks ; then
print_info "Пробуем установить библиотеки: ${WH_DLL_NEED_INSTALL} "
print_info "Запускаем WINETRICKS... "
export WINETRICKS_DOWNLOADER="curl"
env WINEDLLOVERRIDES="winegstreamer=" "$WH_TMP_DIR/winetricks" -q ${WH_DLL_NEED_INSTALL}
wait_wineserver
fi
print_info "Пробуем установить компоненты: ${WH_DLL_NEED_INSTALL}"
print_info "Запускаем WINETRICKS... "
export WINETRICKS_DOWNLOADER="curl "
"$WH_WINETRICKS" -q ${WH_DLL_NEED_INSTALL}
wait_wineserver
fi
fi
}
@ -1079,10 +1060,8 @@ init_database () {
if [[ -f "$WIN_FILE_EXEC".whdb ]] ; then
WHDB_FILE="$WIN_FILE_EXEC".whdb
else
orig_IFS="$IFS"
IFS=$'\n'
WH_FIND_DB_FILE="$(grep -ilw "#$WHDB.exe" "$WH_DB_DIR"/* )"
if [[ $(echo "$WH_FIND_DB_FILE" | wc -l) -eq 1 ]] ; then
orig_IFS="$IFS" && IFS=$'\n'
if WH_FIND_DB_FILE="$(grep -ilw "#$WHDB.exe" "$WH_DB_DIR"/* )" ; then
WHDB_FILE="$WH_FIND_DB_FILE"
fi
IFS="$orig_IFS"
@ -1093,8 +1072,7 @@ init_database () {
print_info "Используется файл настроек: $WHDB_FILE"
. "$WHDB_FILE"
elif check_prefix_var && [[ -f "$WINEPREFIX/last.conf" ]] ; then
print_info "Найдены настройки из предыдущего использования префикса. "
echo "$WINEPREFIX/last.conf"
print_info "Найдены настройки из предыдущего использования префикса: $WINEPREFIX "
cat "$WINEPREFIX/last.conf"
. "$WINEPREFIX/last.conf"
else
@ -1215,57 +1193,285 @@ run_autoinstall () {
echo
}
##### REMOVE WINEHELPER #####
backup_prefix() {
local prefix_name="$1"
local prefix_path="$WH_PREFIXES_DIR/$prefix_name"
local backup_base_dir="$(xdg-user-dir DESKTOP)"
local timestamp
timestamp=$(date +%Y.%m.%d)
local backup_archive_name="backup_${prefix_name}_${timestamp}.whpack"
local backup_dest_path="$backup_base_dir/$backup_archive_name"
local temp_backup_dir="$WH_TMP_DIR/backup_${prefix_name}_${timestamp}"
if [[ -z "$prefix_name" ]]; then
print_error "Н е указано имя префикса для резервного копирования."
echo "Использование: $SCRIPT_NAME backup-prefix [имя_пр е фикс а ]"
echo "Доступные префиксы:"
ls -1 "$WH_PREFIXES_DIR"
return 1
fi
if [[ ! -d "$prefix_path" ]]; then
print_error "Префикс \"$prefix_name\" не найден по пути $prefix_path."
return 1
fi
print_info "Начало резервного копирования префикса: $prefix_name"
create_new_dir "$backup_base_dir"
try_remove_dir "$temp_backup_dir"
create_new_dir "$temp_backup_dir"
# создание файла с информацией о бэкапе
local backup_info_file="$temp_backup_dir/backup_info.txt"
{
echo "Информация о резервном копировании"
echo "------------------"
echo "Имя префикса: $prefix_name"
echo "Дата копирования: $(date)"
echo "Исходный путь префикса: $prefix_path"
echo ""
echo "Содержимое $prefix_name/last.conf:"
if [[ -f "$prefix_path/last.conf" ]]; then
cat "$prefix_path/last.conf"
else
echo " - $prefix_path/last.conf не найдено."
fi
echo "------------------"
} > "$backup_info_file"
# копирование префикса во временную директорию
print_info "Подготовка префикса к упаковке..."
if cp -a "$prefix_path" "$temp_backup_dir/${prefix_name}"; then
print_ok "Директория префикса подготовлена."
else
print_error "Н е удалось подготовить директорию префикса."
try_remove_dir "$temp_backup_dir"
return 1
fi
# упаковка префикса с помощью mksquashfs
print_info "Создание squashfs архива..."
if command -v mksquashfs >/dev/null; then
if mksquashfs "$temp_backup_dir" "$backup_dest_path" -comp zstd; then
print_ok "Архив успешно создан: $backup_dest_path"
else
print_error "Н е удалось создать архив."
try_remove_dir "$temp_backup_dir"
return 1
fi
else
print_error "mksquashfs не установлен. Необходимо установить squashfs-tools."
try_remove_dir "$temp_backup_dir"
return 1
fi
try_remove_dir "$temp_backup_dir"
print_info "Резервное копирование завершено."
return 0
}
restore_prefix() {
local backup_archive_path="$1"
local new_prefix_name="$2"
local temp_extract_dir
local original_prefix_name_from_info
local new_prefix_path
if [[ -z "$backup_archive_path" ]]; then
read -e -p "Укажите путь к архиву резервной копии (.whpack): " backup_archive_path
if [[ -z "$backup_archive_path" ]]; then
print_error "Путь к архиву не указан. Восстановление отменено."
return 1
fi
fi
backup_archive_path=$(echo "$backup_archive_path" | sed "s/'//g; s/\"//g")
if [[ ! -f "$backup_archive_path" ]]; then
print_error "Файл архива не найден: $backup_archive_path"
return 1
fi
print_info "Восстановление из резервной копии: $backup_archive_path"
temp_extract_dir="$WH_TMP_DIR/restore_$(basename "$backup_archive_path" .whpack)_$(date +%s)"
create_new_dir "$temp_extract_dir"
print_info "Распаковка архива..."
if ! unsquashfs -f -d "$temp_extract_dir" "$backup_archive_path"; then
print_error "Н е удалось распаковать архив."
try_remove_dir "$temp_extract_dir"
return 1
fi
local backup_info_file="$temp_extract_dir/backup_info.txt"
if [[ ! -f "$backup_info_file" ]]; then
print_error "Файл backup_info.txt не найден в архиве."
try_remove_dir "$temp_extract_dir"
return 1
fi
original_prefix_name_from_info=$(grep "Имя префикса:" "$backup_info_file" | cut -d':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [[ -z "$original_prefix_name_from_info" ]]; then
print_error "Н е удалось определить имя оригинального префикса."
try_remove_dir "$temp_extract_dir"
return 1
fi
[[ -z "$new_prefix_name" ]] && new_prefix_name="$original_prefix_name_from_info"
new_prefix_path="$WH_PREFIXES_DIR/$new_prefix_name"
if [[ -d "$new_prefix_path" ]]; then
read -p "Префикс \"$new_prefix_name\" уже существует. Перезаписать? (y/N): " answer
if [[ ! "$answer" =~ ^[YyДд]$ ]]; then
print_info "Восстановление отменено."
try_remove_dir "$temp_extract_dir"
return 0
fi
try_remove_dir "$new_prefix_path"
fi
# восстановление префикса
local extracted_prefix_dir="$temp_extract_dir/$original_prefix_name_from_info"
if [[ ! -d "$extracted_prefix_dir" ]]; then
print_error "Директория префикса не найдена в архиве."
try_remove_dir "$temp_extract_dir"
return 1
fi
print_info "Восстановление директории префикса..."
if mv "$extracted_prefix_dir" "$new_prefix_path"; then
print_ok "Директория префикса восстановлена."
else
print_error "Н е удалось восстановить директорию префикса."
try_remove_dir "$temp_extract_dir"
return 1
fi
# восстановление ярлыков из desktop.list
if [[ -f "$new_prefix_path/desktop.list" ]]; then
print_info "Восстановление ярлыков из desktop.list..."
while IFS='=' read -r name_desktop relative_exe_path || [[ -n "$name_desktop" ]]; do
relative_exe_path=$(echo "$relative_exe_path" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [[ -n "$relative_exe_path" ]]; then
local full_exe_path="$new_prefix_path/$relative_exe_path"
if [[ -f "$full_exe_path" ]]; then
local png_name="$(basename "$full_exe_path" .exe | tr '[:upper:]' '[:lower:]')"
create_desktop "$name_desktop" "$full_exe_path" "$png_name"
else
print_warning "Файл $full_exe_path не найден, пропускаем создание ярлыка"
fi
fi
done < "$new_prefix_path/desktop.list"
fi
try_remove_dir "$temp_extract_dir"
print_ok "Восстановление префикса \"$new_prefix_name\" завершено."
return 0
}
remove_prefix() {
local prefix_name="$1"
local prefix_path="$WH_PREFIXES_DIR/$prefix_name"
if [[ -z "$prefix_name" ]]; then
print_error "Н е указано имя префикса для удаления."
echo "Использование: $SCRIPT_NAME remove-prefix [имя_пр е фикс а ]"
echo "Доступные префиксы:"
ls -1 "$WH_PREFIXES_DIR"
return 1
fi
if [[ ! -d "$prefix_path" ]]; then
print_error "Префикс "$prefix_name" не найден."
return 1
fi
if [[ ! $2 =~ --force|-y ]] ; then
echo "======================================================"
print_warning "Вы собираетесь удалить префикс "$prefix_name"."
echo "Это приведёт к:"
echo " - Полному удалению всех данных префикса"
echo " - Удалению всех программ, установленных в этом префиксе"
echo " - Удалению связанных ярлыков из меню и рабочего стола"
echo "======================================================"
read -p "Продолжить удаление? (y/N): " answer
if [[ ! "$answer" =~ ^[YyДд]$ ]]; then
print_info "Удаление префикса отменено."
return 0
fi
fi
try_remove_dir "$prefix_path"
if [[ $? -eq 0 ]]; then
print_ok "Префикс "$prefix_name" успешно удален."
for desktop_file in "$WH_MENU_DIR"/*.desktop; do
if grep -q "$prefix_path" "$desktop_file"; then
desktop_name=$(basename "$desktop_file")
remove_desktop "${desktop_name%.*}"
fi
done
return 0
else
print_error "Н е удалось удалить префикс "$prefix_name"."
return 1
fi
}
remove_winehelper () {
local answer
echo "====================================================== "
print_warning "Вы собираетесь удалить WineHelper и все связанные с ним данные."
echo " Это удалит: "
echo " - В с е настройки WineHelper "
echo " - В с е приложения/программы, установленные через WineHelper "
echo " - В с е ярлыки из меню и с рабочего стола созданные с помощью WineHelper"
echo "====================================================== "
echo "Продолжить? (y/N) "
read -r answer
if [[ "$answer" =~ ^[YyДд]$ ]]; then
# Второе подтверждение
echo "----------------------------------------------"
print_warning " ВЫ ТОЧНО УВЕРЕНЫ?"
echo "----------------------------------------------"
if [[ $1 =~ --force|-y ]] ; then
answer="y "
else
echo "====================================================== "
print_warning "Вы собираетесь удалить WineHelper и все связанные с ним данные. "
echo " Это удалит: "
echo " - В с е настройки WineHelper"
echo " - В с е приложения/программы, установленные через WineHelper "
echo " - В с е ярлыки из меню и с рабочего стола созданные с помощью WineHelper "
echo "======================================================"
echo "Продолжить? (y/N)"
read -r answer
if [[ "$answer" =~ ^[YyДд]$ ]]; then
# Удаление рабочих каталогов
try_remove_dir "$USER_WORK_PATH "
# Удаление файлов меню
try_remove_dir "$WH_MENU_DIR"
try_remove_file "$WH_MENU_CATEGORY"
try_remove_file "$WH_MENU_CONFIG"
# Удаление desktop-файлов
for desktop_file in "$(xdg-user-dir DESKTOP)"/*.desktop; do
if grep -q "Exec=env \"$RUN_SCRIPT\"" "$desktop_file"; then
try_remove_file "$desktop_file"
fi
done
# Обновление кэша desktop-файлов
if check_command update-desktop-database; then
update-desktop-database "$HOME/.local/share/applications"
fi
# Удаление символических ссылок
try_remove_file "$HOME/.winehelper"
print_info "WineHelper и все связанные данные успешно удалены."
if [[ "$answer" =~ ^[YyДд]$ ]] ; then
# Второе подтверждение
echo "----------------------------------------------"
print_warning " ВЫ ТОЧНО УВЕРЕНЫ? "
echo "----------------------------------------------"
echo "Продолжить? (y/N)"
read -r answer
else
print_info "Удаление отменено."
return 1
fi
fi
if [[ "$answer" =~ ^[YyДд]$ ]] ; then
# Удаление рабочих каталогов
try_remove_dir "$USER_WORK_PATH"
# Удаление файлов меню
try_remove_dir "$WH_MENU_DIR"
try_remove_file "$WH_MENU_CATEGORY"
try_remove_file "$WH_MENU_CONFIG"
# Удаление desktop-файлов
for desktop_file in "$(xdg-user-dir DESKTOP)"/*.desktop; do
if grep -q "Exec=env \"$RUN_SCRIPT\"" "$desktop_file"; then
try_remove_file "$desktop_file"
fi
done
# Обновление кэша desktop-файлов
update-desktop-database "$HOME/.local/share/applications"
# Удаление символических ссылок
try_remove_file "$HOME/.winehelper"
print_info "WineHelper и все связанные данные успешно удалены."
else
print_info "Удаление отменено."
fi
@ -1281,7 +1487,10 @@ wh_info () {
installed список установленных программ
run [программа.exe] запуск программы (отладка)
remove удалить WineHelper и все связанные данные
backup-prefix [имя_пр е фикс а ] создать резервную копию префикса
restore-prefix восстановить резервную копию префикса
remove-all удалить WineHelper и все связанные данные
remove-prefix [имя_пр е фикс а ] удалить префикс и все связанные данные
Параметры:
--help показать эту справку и выйти
@ -1310,12 +1519,15 @@ case "${1,,}" in
winereg|regedit) prepair_wine ; wine_run "regedit" ;;
winefile|explorer) prepair_wine ; wine_run "winefile" ;;
wineconsole|cmd) prepair_wine ; wine_run "wineconsole" ;;
winetricks) shift ; update_winetricks ; prepair_wine ; "$WINETRICKS" -q "$@" ;;
winetricks) shift ; prepair_wine ; "$WINETRICKS" -q "$@" ;;
desktop) shift ; create_desktop "$@" ; exit 0 ;;
install|-i) shift ; run_autoinstall "$@" ;;
installed) shift ; check_installed_programs "$1" ;;
run|-r) shift ; run_installed_programs "$1" ;;
remove|--remove) remove_winehelper ;;
backup-prefix) shift ; backup_prefix "$@" ;;
restore-prefix) shift ; restore_prefix "$@" ;;
remove-all) shift ; remove_winehelper "$@ ";;
remove-prefix) shift ; remove_prefix "$@" ;;
*)
if [[ -f "$1" ]] ; then
WIN_FILE_EXEC="$(readlink -f "$1")"