winehelper/winehelper
2025-05-05 13:29:04 +06:00

1248 lines
46 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
##### CHECK ROOT #####
if [[ $(id -u) -eq 0 ]] ; then
echo "Перезапустите скрипт $0 от обычного пользователя!"
exit 1
fi
##### MESSAGES FUNCTIONS #####
print_error () { printf "\E[31m%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_ok () { printf "\E[35m%s Успех: $@ %s\e[0m\n" ;}
print_var () { for vp in $@ ; do echo "${vp}=${!vp}" ; done ;}
fatal () { print_error "$@" ; exit 1 ;}
##### CHECK VARIABLES #####
check_variables () { [[ -z ${!1} ]] && export $1="$2" ;}
##### CHECK DEBUG #####
if [[ "$1" == "--debug" ]] ; then
export DEBUG="full"
export LOG_FILE="$HOME/winehelper.log"
shift
print_warning "Включен режим подробного логирования работы WINE."
print_warning "Лог будет сохранен по пути: $LOG_FILE"
sleep 3
else
check_variables DEBUG "0"
fi
##### DEFAULT VARIABLES #####
SCRIPT_NAME="$(basename "$0")"
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
USER_WORK_PATH="$HOME/.local/share/$SCRIPT_NAME"
RUN_SCRIPT="/usr/bin/$SCRIPT_NAME"
DATA_PATH="/usr/share/$SCRIPT_NAME"
else
USER_WORK_PATH="$HOME/test-$SCRIPT_NAME"
RUN_SCRIPT="$(realpath "$0")"
DATA_PATH="$(dirname "$RUN_SCRIPT")"
fi
WH_VULKAN_LIBDIR="$USER_WORK_PATH/vulkan"
WH_PREFIXES_DIR="$USER_WORK_PATH/prefixes"
WH_DIST_DIR="$USER_WORK_PATH/dist"
WH_TMP_DIR="$USER_WORK_PATH/tmp"
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_MENU_DIR="$HOME/.local/share/applications/WineHelper"
WH_MENU_CATEGORY="$HOME/.local/share/desktop-directories/WineHelper.directory"
WH_MENU_CONFIG="$HOME/.config/menus/applications-merged/WineHelper.menu"
# export WINEDLLOVERRIDES=mshtml,mscoree="
check_variables WINEESYNC "0"
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 STAGING_SHARED_MEMORY "1"
check_variables WINE_LARGE_ADDRESS_AWARE "1"
check_variables WINE_FULLSCREEN_FSR "1"
check_variables WINE_DO_NOT_CREATE_DXGI_DEVICE_MANAGER "0"
check_variables WINE_HEAP_DELAY_FREE "0"
check_variables WINE_ALLOW_XIM "0"
check_variables WH_WINDOWS_VER "10"
# check_variables WH_USE_GSTREAMER "1"
# check_variables WH_USE_D3D_EXTRAS "1"
check_variables WH_USE_SHADER_CACHE "1"
check_variables WH_USE_WINE_DXGI "0"
check_variables WH_DLL_INSTALL ""
check_variables WINE_WIN_START "start /wait /high /unix"
check_variables WINE_CPU_TOPOLOGY "8"
check_variables USE_RENDERER "opengl" # opengl, damavand, proton
check_variables DXVK_VER "1.10.3-28"
# check_variables DXVK_CONFIG_FILE "path/to/dxvk.conf"
check_variables VKD3D_VER "1.1-2602"
# check_variables VKD3D_LIMIT_TESS_FACTORS 64
# check_variables VKD3D_FEATURE_LEVEL "12_0"
export CLOUD_URL="https://cloud.linux-gaming.ru/portproton"
##### CHECK NOEXEC FOR /HOME #####
if grep "/home" /etc/fstab | grep -q "noexec" ; then
fatal "/home примонтирован в /etc/fstab с аргументом noexec.\nЗапуск портативной версии wine не возможен из домашнего каталога."
fi
##### ROOT #####
su_run () {
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,\
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
if su_run "$DATA_PATH/dependencies.sh"
then print_info "Зависимости успешно установлены. Продолжаем работу $SCRIPT_NAME"
else fatal "Не удалось установить зависимости. Работа $SCRIPT_NAME прервана."
fi
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"
fi
}
rm_from_var () {
if echo ${!1} | grep "$2" &>/dev/null
then export $1="$(echo "${!1//$2/}" | tr -s " ")"
fi
}
try_remove_file () {
if [[ -f "$1" ]] || [[ ! -e "$1" ]] ; then
rm -f "$1"
[[ "$?" == 0 ]] && return 0 || return 1
fi
}
try_remove_dir () {
if [[ -d "$1" ]] ; then
rm -fr "$1"
[[ "$?" == 0 ]] && return 0 || return 1
fi
}
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"
try_remove_file "$2"
cp -f "$1" "$2" && return 0 || return 1
else
[[ -e "$2/$(basename "$1")" ]] && rm -f "$2/$(basename "$1")"
cp -f "$1" "$2" && return 0 || return 1
fi
}
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"
else
cp -fr "$1" "$2"
[[ "$?" != 0 ]] && print_error "failed to copy directory $1 to $2" || return 0
fi
return 1
}
try_force_link_file () {
if [[ ! -f "$1" ]] ; then
print_warning "file not found for link: $1"
if [[ -f "$2" ]] ; then
try_remove_file "$2"
print_warning "removed old link: $2"
fi
return 1
elif [[ -z "$2" ]] ; then print_error "no way to link file $1" && return 1
else
try_remove_file "$2"
ln -s -f -r "$1" "$2"
return 0
fi
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"
else
ln -s -f -r "$1" "$2"
[[ "$?" != 0 ]] && print_error "failed to link directory $1 to $2" || return 0
fi
return 1
}
create_new_dir () {
if [[ ! -d "$1" ]] ; then
mkdir -p "$1"
fi
return 0
}
unpack () {
print_info "Запуск распаковки архива $1"
case $1 in
*.tar.xz) local command="tar -Jxhf";;
*.tar.gz) local command="tar -xhzf" ;;
*.tar.zst) local command="tar -I zstd -xhf" ;;
*.tar) local command="tar -xhf" ;;
esac
create_new_dir "$2"
if $command "$1" -C "$2" ; then
print_ok "Архив $1 распакован."
return 0
else
print_error "Распаковать архив $1 не удалось!"
return 1
fi
}
try_download () {
local DOWNLOAD_FILE_URL="$1"
local OUTPUT_FILE="$2"
local OUTPUT_FILE_NAME="$(basename "$OUTPUT_FILE")"
print_info "Скачивание файла $OUTPUT_FILE_NAME..."
if curl -f --progress-bar -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" \
-L "$DOWNLOAD_FILE_URL" -o "$OUTPUT_FILE"
then
print_ok "Скачивание файла $OUTPUT_FILE_NAME прошло успешно."
if [[ "$3" == check256sum ]] ; then
SHA256SUM_EXT=$(sha256sum "$OUTPUT_FILE" | awk '{print $1}')
SHA256SUM_INT="$(grep "$OUTPUT_FILE_NAME" "$DATA_PATH/sha256sum.list" | awk '{print $1}')"
if [[ "$SHA256SUM_EXT" == "$SHA256SUM_INT" ]] ; then
print_ok "Хэш-сумма файла $OUTPUT_FILE_NAME успешно проверена."
return 0
else
fatal "Хэш-сумма файла $OUTPUT_FILE_NAME не совподает!"
return 1
fi
fi
return 0
else
fatal "Скачивание файла: $OUTPUT_FILE_NAME завершилось с ошибкой!"
return 1
fi
}
try_copy_other_dll_to_pfx_64 () {
if [[ "$WINEARCH" == "win64" ]] ; then
cmp -s "$1" "${WINEPREFIX}/drive_c/windows/system32/$(basename $1)" && return 0
try_copy_file "$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
try_copy_other_dll_to_pfx_32() {
if [[ "$WINEARCH" == "win64" ]] ; then
cmp -s "$1" "${WINEPREFIX}/drive_c/windows/syswow64/$(basename $1)" && return 0
try_copy_file "$1" "${WINEPREFIX}/drive_c/windows/syswow64/" && return 0 || return 1
else
cmp -s "$1" "${WINEPREFIX}/drive_c/windows/system32/$(basename $1)" && return 0
try_copy_file "$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
try_copy_wine_dll_to_pfx_64 () {
if [[ "$WINEARCH" == "win64" ]] ; then
if [[ -d "${WINEDIR}/lib64/wine/x86_64-windows" ]]
then WINE_BUILD_DLL_64="${WINEDIR}/lib64/wine/x86_64-windows"
else WINE_BUILD_DLL_64="${WINEDIR}/lib64/wine"
fi
cmp -s "$WINE_BUILD_DLL_64/$1" "${WINEPREFIX}/drive_c/windows/system32/$(basename $1)" && return 0
try_copy_file "$WINE_BUILD_DLL_64/$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
try_copy_wine_dll_to_pfx_32() {
if [[ -d "${WINEDIR}/lib/wine/i386-windows" ]]
then WINE_BUILD_DLL_32="${WINEDIR}/lib/wine/i386-windows"
else WINE_BUILD_DLL_32="${WINEDIR}/lib/wine"
fi
if [[ "$WINEARCH" == "win64" ]] ; then
cmp -s "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/syswow64/$1" && return 0
try_copy_file "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/syswow64/" && return 0 || return 1
else
cmp -s "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/system32/$1" && return 0
try_copy_file "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
##### OVERRIDE VARIABLES FUNCTIONS #####
var_winedlloverride_update () {
if [[ -n "${WINEDLLOVERRIDES}" ]]
then export WINEDLLOVERRIDES="${1};${WINEDLLOVERRIDES}"
else export WINEDLLOVERRIDES="${1}"
fi
}
var_vkd3d_config_update () {
if [[ -n "${DXVK_CONFIG}" ]]
then export DXVK_CONFIG="${1}; ${DXVK_CONFIG}"
else export DXVK_CONFIG="${1}"
fi
}
var_vkd3d_config_update () {
if [[ -n "${VKD3D_CONFIG}" ]]
then export VKD3D_CONFIG="${1};${VKD3D_CONFIG}"
else export VKD3D_CONFIG="${1}"
fi
}
var_radv_perftest_config_update () {
if [[ -n "${RADV_PERFTEST}" ]]
then export RADV_PERFTEST="${1};${RADV_PERFTEST}"
else export RADV_PERFTEST="${1}"
fi
}
var_vk_istance_layers_config_update () {
if [[ -n "${VK_INSTANCE_LAYERS}" ]]
then export VK_INSTANCE_LAYERS="${1}:${VK_INSTANCE_LAYERS}"
else export VK_INSTANCE_LAYERS="${1}"
fi
}
var_ld_library_path_update () {
if echo "$LD_LIBRARY_PATH" | grep "$1"
then return 0
elif [[ -n "$LD_LIBRARY_PATH" ]]
then export LD_LIBRARY_PATH="$1:$LD_LIBRARY_PATH"
else export LD_LIBRARY_PATH="$1"
fi
return 0
}
##### CREATE DESKTOP FILE #####
create_desktop () {
local name_desktop="$1"
local exe_file="$2"
local desktop_filename="$(basename "$exe_file" .exe | sed "s| |_|")"
local icon_file="$WH_IMAGE_PATH/$3.png"
if [[ -z "$name_desktop" ]] || [[ -z "$exe_file" ]] ; then
fatal "Used: $SCRIPT_NAME --desktop \"desktop_name\" \"path_to_exe\" \"name_png_from_image\""
elif [[ ! -f "$exe_file" ]] ; then
print_warning "Для создания ярлыка не найден исполняемый файл: $exe_file"
BASENAME_EXE="$(basename "$exe_file")"
print_info "Запускаем поиск $BASENAME_EXE"
if [[ -z "$DRIVE_C" ]] || [[ ! -d "$DRIVE_C" ]]
then FIND_PATH="$WH_PREFIXES_DIR"
else FIND_PATH="$DRIVE_C"
fi
exe_file="$(find "$FIND_PATH" -type f -not -type l \
-not -path "*/windows/*" -not -path "*/dosdevices/*" \
-iname "$BASENAME_EXE")"
if [[ -z "$exe_file" ]] || [[ ! -f "$exe_file" ]]
then fatal "Для создания ярлыка не найден исполняемый файл: $BASENAME_EXE"
else print_ok "Исполняемый файл $BASENAME_EXE найден по пути $(dirname "$exe_file")/"
fi
fi
create_new_dir "$WH_MENU_DIR"
[[ ! -f "$icon_file" ]] && icon_file=wine
# Создаем .desktop файл
{
echo "[Desktop Entry]"
echo "Name=$name_desktop"
echo "Exec=env \"$RUN_SCRIPT\" \"$exe_file\" %F"
echo "Type=Application"
echo "Categories=WineHelper;"
echo "StartupNotify=true"
echo "Path=$DATA_PATH"
echo "Icon=$icon_file"
} > "$USER_WORK_PATH/$desktop_filename.desktop"
chmod +x "$USER_WORK_PATH/$desktop_filename.desktop"
cp -f "$USER_WORK_PATH/$desktop_filename.desktop" "$WH_MENU_DIR/"
# Создаем файл категории для меню
create_new_dir "$HOME/.local/share/desktop-directories"
if [[ ! -f "$WH_MENU_CATEGORY" ]] ; then
cat > "$WH_MENU_CATEGORY" <<EOF
[Desktop Entry]
Type=Directory
Name=WineHelper
Icon=wine
EOF
fi
# Создаем файл меню для всех приложений
create_new_dir "$HOME/.config/menus/applications-merged"
if [[ ! -f "$WH_MENU_CONFIG" ]] ; then
cat > "$WH_MENU_CONFIG" <<EOF
<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
"http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
<Menu>
<Name>Applications</Name>
<Menu>
<Name>WineHelper</Name>
<Directory>WineHelper.directory</Directory>
<Include>
<Category>WineHelper</Category>
</Include>
</Menu>
</Menu>
EOF
# Обновляем меню
if check_command update-menus ; then
update-menus
fi
fi
# Обновляем кэш desktop файлов
if check_command update-desktop-database ; then
update-desktop-database "$HOME/.local/share/applications"
fi
if [[ $4 != "nocopy" ]] ; then
if [[ -n $4 ]] ; then
local desktop_path="$(xdg-user-dir DESKTOP)/$4"
create_new_dir "$desktop_path"
print_info "В меню создан $desktop_filename.desktop и скопирован на рабочий стол в каталог $4"
else
local desktop_path="$(xdg-user-dir DESKTOP)"
print_info "В меню и на рабочем столе создан $desktop_filename.desktop"
fi
cp -f "$USER_WORK_PATH/$desktop_filename.desktop" "$desktop_path"
else
print_info "В меню создан $desktop_filename.desktop"
fi
if [[ -n "$INSTALL_SCRIPT_NAME" ]] \
&& [[ -f "$exe_file" ]]
then
{
echo '#!/usr/bin/env bash'
echo "# cmd_name: $INSTALL_SCRIPT_NAME"
} > "$exe_file".whdb
grep -e "info_" -e "#####" -e "export" -e "var_" "$INSTALL_SCRIPT" \
| grep -vE "LAUNCH_PARAMETERS|AUTOINSTALL|WIN_FILE_EXEC|echo" \
| awk '{$1=$1;print}' >> "$exe_file".whdb
print_info "Создан файл настроек для $exe_file"
fi
}
##### REMOVE DESKTOP FILE #####
remove_desktop () {
if [[ -n "$1" ]] ; then
try_remove_file "$USER_WORK_PATH/$1.desktop"
try_remove_file "$WH_MENU_DIR/$1.desktop"
try_remove_file "$HOME/.local/share/applications/$1.desktop"
try_remove_file "$(xdg-user-dir DESKTOP)/$1.desktop"
fi
# Удаляем категорию если она пуста
if [[ -d "$WH_MENU_DIR" ]] && [[ -z "$(ls -A "$WH_MENU_DIR")" ]]; then
try_remove_dir "$WH_MENU_DIR"
try_remove_file "$WH_MENU_CATEGORY"
try_remove_file "$WH_MENU_CONFIG"
# Обновляем меню
if check_command update-menus ; then
update-menus
fi
fi
# Обновляем кэш desktop файлов
if check_command update-desktop-database ; then
update-desktop-database "$HOME/.local/share/applications"
fi
}
##### INSTALLED PROGRAMS #####
check_installed_programs () {
for desktop_file in "$USER_WORK_PATH"/*.desktop ; do
if [[ ! -f "$desktop_file" ]] ; then
print_info "Установленные программы не найдены."
return 1
fi
EXE_PATH="$(grep "Exec" "$desktop_file" | awk -F'"' '{print $4}')"
case "$1" in
check_only)
if [[ -z $2 ]] ; then
print_error "Нет аргумента для проверки файла запуска!"
print_info "Список установленных программ:"
check_installed_programs
exit 1
elif [[ "$EXE_PATH" =~ ${2}$ ]] ; then
export EXE_PATH
return 0
fi
;;
*)
if [[ -f "$EXE_PATH.whdb" ]] ; then
WH_INFO_RU="$(grep "info_ru:" "$EXE_PATH.whdb" | awk -F"info_ru: " '{print $2}')"
printf "\E[36m%s $SCRIPT_NAME run $(basename "$EXE_PATH") - $(basename "$desktop_file") %s\e[0m\n"
echo -e "$WH_INFO_RU\n"
fi
;;
esac
done
[[ -n $2 ]] && fatal "Не найден файл запуска для $2"
}
run_installed_programs () {
if check_installed_programs check_only "$1" ; then
/usr/bin/env bash -c "\"$RUN_SCRIPT\" \"$EXE_PATH\"" &
exit 0
fi
}
##### USED WINED3D LIBRARY #####
init_wined3d () {
if [[ "$USE_RENDERER" != "proton" ]] ; then
WINED3D_FILES="d3d8 d3d9 d3d10_1 d3d10 d3d10core d3d11 dxgi d3d12 d3d12core"
for wined3dfiles in $WINED3D_FILES ; do
try_copy_wine_dll_to_pfx_64 "$wined3dfiles.dll"
try_copy_wine_dll_to_pfx_32 "$wined3dfiles.dll"
done
# if [[ "$USE_RENDERER" == "damavand" ]]
# then export WINE_D3D_CONFIG="renderer=vulkan"
# else export WINE_D3D_CONFIG="renderer=gl"
# fi
return 0
else
return 1
fi
}
##### CHECK VULKAN LIBRARY #####
init_dxvk () {
check_variables USE_DXVK_VER "$1"
get_dxvk () {
DXVK_URL="$1"
DXVK_PACKAGE="${WH_VULKAN_LIBDIR}/dxvk-${DXVK_VAR_VER}.tar.$(echo ${DXVK_URL#*.tar.})"
if try_download "$DXVK_URL" "$DXVK_PACKAGE" check256sum \
&& unpack "$DXVK_PACKAGE" "$WH_VULKAN_LIBDIR"
then
try_remove_file "$DXVK_PACKAGE"
return 0
fi
return 1
}
for DXVK_VAR_VER in "$USE_DXVK_VER" $@ ; do
if [[ ! -d "${WH_VULKAN_LIBDIR}/dxvk-$DXVK_VAR_VER" ]] ; then
get_dxvk "$CLOUD_URL/dxvk-${DXVK_VAR_VER}.tar.xz"
fi
done
if [[ "${WH_USE_WINE_DXGI}" == 1 ]] ; then
DXVK_FILES="d3d9 d3d10_1 d3d10 d3d11" # dxvk_config openvr_api_dxvk"
try_copy_wine_dll_to_pfx_64 "dxgi.dll"
try_copy_wine_dll_to_pfx_32 "dxgi.dll"
else
DXVK_FILES="d3d9 d3d10_1 d3d10 d3d11 dxgi" # dxvk_config openvr_api_dxvk"
fi
for dxvkfiles in $DXVK_FILES ; do
try_copy_other_dll_to_pfx_64 "${WH_VULKAN_LIBDIR}/dxvk-$USE_DXVK_VER/x64/$dxvkfiles.dll"
if try_copy_other_dll_to_pfx_32 "${WH_VULKAN_LIBDIR}/dxvk-$USE_DXVK_VER/x32/$dxvkfiles.dll"
then var_winedlloverride_update "$dxvkfiles=n"
fi
done
}
init_vkd3d () {
check_variables USE_VKD3D_VER "$1"
get_vkd3d () {
VKD3D_URL="$1"
VKD3D_PACKAGE="${WH_VULKAN_LIBDIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.$(echo ${VKD3D_URL#*.tar.})"
if try_download "$VKD3D_URL" "$VKD3D_PACKAGE" check256sum \
&& unpack "$VKD3D_PACKAGE" "$WH_VULKAN_LIBDIR"
then
try_remove_file "$VKD3D_PACKAGE"
return 0
fi
return 1
}
for VKD3D_VAR_VER in "$USE_VKD3D_VER" $@ ; do
if [[ ! -d "${WH_VULKAN_LIBDIR}/vkd3d-proton-$VKD3D_VAR_VER" ]] ; then
get_vkd3d "$CLOUD_URL/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz"
fi
done
VKD3D_FILES="d3d12 d3d12core libvkd3d-shader-1 libvkd3d-1" # libvkd3d-proton-utils-3
for vkd3dfiles in $VKD3D_FILES ; do
try_copy_other_dll_to_pfx_64 "${WH_VULKAN_LIBDIR}/vkd3d-proton-$USE_VKD3D_VER/x64/$vkd3dfiles.dll"
if try_copy_other_dll_to_pfx_32 "${WH_VULKAN_LIBDIR}/vkd3d-proton-$USE_VKD3D_VER/x86/$vkd3dfiles.dll"
then var_winedlloverride_update "$vkd3dfiles=n"
fi
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
fi
export WINE="${WINEDIR}/bin/wine"
export WINELOADER="${WINEDIR}/bin/wine"
export WINESERVER="${WINEDIR}/bin/wineserver"
if [[ -n "${PATH}" ]]
then export PATH="${WINEDIR}/bin:${PATH}"
else export PATH="${WINEDIR}/bin"
fi
if [[ -n "${LD_LIBRARY_PATH}" ]]
then export LD_LIBRARY_PATH="${WINEDIR}/lib:${LD_LIBRARY_PATH}"
else export LD_LIBRARY_PATH="${WINEDIR}/lib"
fi
export WINEDLLPATH="${WINEDIR}/lib/wine"
if [[ -d "${WINEDIR}/lib/gstreamer-1.0" ]] ; then
export GST_PLUGIN_SYSTEM_PATH_1_0="${WINEDIR}/lib/gstreamer-1.0"
fi
if [[ "${WINEARCH}" == "win64" ]] ; then
export LD_LIBRARY_PATH+=":${WINEDIR}/lib64"
export WINEDLLPATH+=":${WINEDIR}/lib64/wine"
if [[ -d "${WINEDIR}/lib64/gstreamer-1.0" ]] ; then
export GST_PLUGIN_SYSTEM_PATH_1_0+=":${WINEDIR}/lib64/gstreamer-1.0"
fi
fi
[[ ! -f "${WINEDIR}/version" ]] && echo "${WH_WINE_USE}" > "${WINEDIR}/version"
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/"
fi
else
# use system WINE
if ! command -v "wine" &>/dev/null ; then
fatal "system WINE - not found."
fi
export WINEDIR="/usr"
export WINELOADER="wine"
export WINESERVER="wineserver"
fi
check_variables DXVK_LOG_LEVEL "none"
check_variables VKD3D_SHADER_DEBUG "none"
check_variables VKD3D_DEBUG "none"
check_variables DXVK_LOG_PATH "none"
check_variables VKBASALT_LOG_LEVEL "none"
check_variables DXVK_NVAPI_LOG_LEVEL "none"
if [[ $DEBUG == "0" ]] ; then
check_variables WINEDEBUG "-all"
elif [[ $DEBUG == "full" ]] ; then
check_variables WINEDEBUG "+loaddll,+seh"
export DXVK_LOG_LEVEL="error"
export VKD3D_DEBUG "error"
export WINE_MONO_TRACE "E:System.NotImplementedException"
export VK_LOADER_DEBUG "error"
export VKBASALT_LOG_LEVEL "error"
export DXVK_NVAPI_LOG_LEVEL "error"
else
check_variables WINEDEBUG "err+all"
fi
print_info "Используется версия wine: $WH_WINE_USE"
}
##### INITIAL WINEPREFIX SETTINGS #####
get_and_set_reg_file () {
convert_dec_and_hex () {
local type=$1
local num=$2
case "$type" in
--dec)
# Преобразование из десятичного в шестнадцатеричный
echo -n "$(printf "%08x" "$num")" ;;
--hex)
# Преобразование из шестнадцатеричного в десятичный
echo $(( 0x$num )) ;;
*)
echo "Неверный тип преобразования. Используйте --dec или --hex." ;;
esac
}
local name_block name_for_find find_block find_file find_line count name_for_new_block name_for_find_old
local line_reg find_number_line find_check_file name_for_set name_type_reg name_fatal name_add_or_del
name_add_or_del=$1
name_block=$2
name_for_find=$3
name_type_reg=$4
name_for_set=$5
name_for_new_block=$6
name_for_find_old=$name_for_find
name_fatal="$name_block $name_for_find"
case $name_type_reg in
REG_DWORD)
name_for_find="\"$name_for_find\"=dword:"
name_for_set=$(convert_dec_and_hex --dec "$name_for_set") ;;
REG_SZ)
name_for_find="\"$name_for_find\"="
name_for_set="\"$name_for_set\"" ;;
*)
if [[ $name_add_or_del == --delete ]] ; then
name_for_find="\"$name_for_find\""
else
print_error "не задан тип ветки реестра: $name_fatal"
return 1
fi ;;
esac
name_block=${name_block//\\/\\\\\\\\}
if [[ -n $name_for_new_block ]] ; then
find_block=$(grep -n "\[$name_block\]" "$WINEPREFIX/$name_for_new_block.reg")
else
find_block=$(grep -n "\[$name_block\]" "$WINEPREFIX/"*.reg)
fi
if [[ -n $find_block ]] ; then
if [[ -n $name_for_new_block ]] ; then
find_file="$WINEPREFIX/$name_for_new_block.reg"
find_line=${find_block//:*/}
else
find_file=${find_block//:*/}
find_line=${find_block//$find_file:/}
find_line=${find_line//:*/}
fi
count=-1
while read -r line_reg ; do
((count++))
if [[ $line_reg =~ $name_for_find ]] ; then
if [[ $line_reg == $name_for_find$name_for_set ]] ; then
return 0
fi
find_number_line=$(( count + find_line ))
find_check_file=1
break
fi
[[ -z $line_reg ]] && break
done <<< "$(sed -n "$find_line"',$p' "$find_file")"
fi
if [[ $name_add_or_del == --add ]] ; then
if [[ -z $find_block ]] ; then
if [[ -n $name_for_new_block ]] ; then
sed -i '$a\\n'\["$name_block"\] "$WINEPREFIX/$name_for_new_block.reg"
find_file="$WINEPREFIX/$name_for_new_block.reg"
find_line=$(wc -l "$find_file" | awk -F" " '{print $1}')
find_line=$(( find_line - 1 ))
else
print_error "$name_fatal не найден в файле реестра"
return 1
fi
fi
if [[ $find_check_file == 1 ]] ; then
print_info "Меняем $name_for_find_old в файле реестра"
sed -i "${find_number_line}s|$name_for_find.*|$name_for_find$name_for_set|" "$find_file"
else
print_info "Добавляем $name_for_find_old в файл реестра"
sed -i "$(( find_line + 1 ))a$name_for_find$name_for_set" "$find_file"
fi
elif [[ $name_add_or_del == --delete ]] ; then
[[ $find_check_file != 1 ]] && return 0
print_info "Удаляем $name_for_find_old из файла реестра"
sed -i "${find_number_line}d" "$find_file"
fi
}
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
}
get_base_pfx () {
local FILE_NAME_PFX="$1"
local PFX_URL="$CLOUD_URL/${FILE_NAME_PFX}.tar.xz"
local PFX_TMP="$WH_TMP_DIR/pfx"
create_new_dir "$PFX_TMP"
if [[ ! -f "$PFX_TMP/$FILE_NAME_PFX.tar.xz" ]] ; then
print_info "Загрузка базового префикса: ${FILE_NAME_PFX}"
if try_download "$PFX_URL" "$PFX_TMP/$FILE_NAME_PFX.tar.xz" check256sum
then unpack "$PFX_TMP/$FILE_NAME_PFX.tar.xz" "$WINEPREFIX/"
else try_remove_file "$PFX_TMP/$FILE_NAME_PFX.tar.xz"
fi
else
if ! unpack "$PFX_TMP/$FILE_NAME_PFX.tar.xz" "$WINEPREFIX/" ; then
try_remove_file "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz"
get_base_pfx "$FILE_NAME_PFX"
fi
fi
}
init_wineprefix () {
if [[ -z "$WINEPREFIX" ]] ; then
print_warning "Префикс не выбран, используйте пееременную: WINEPREFIX=имя_префикса"
print_info "Список существующих префиксов:"
ls -1 "$WH_PREFIXES_DIR"
echo
exit 1
else
if echo "$WINEPREFIX" | grep -v '/' ; then
export WINEPREFIX="$WH_PREFIXES_DIR/$WINEPREFIX"
fi
fi
if [[ "$WINEARCH" == "win32" ]]
then check_variables BASE_PFX "defpfx_x86_v01"
else check_variables BASE_PFX "defpfx_x64_v01"
fi
export DRIVE_C="$WINEPREFIX/drive_c"
if [[ ! -f "$WINEPREFIX/.firstboot" ]] ; then
create_new_dir "$WINEPREFIX"
if [[ "$CLEAR_PREFIX" == "1" ]]
then print_warning "Используется переменная \"CLEAR_PREFIX=1\" что принудительно создает чистый префикс с установкой компонентов с помощью winetricks."
elif [[ "$BASE_PFX" != "none" ]]
then get_base_pfx "$BASE_PFX"
fi
print_info "Обновление префикса $WINEPREFIX."
if [[ -d "$WINEPREFIX/drive_c/windows" ]]
then env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" wineboot -u
else env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" wineboot -i
fi
touch "$WINEPREFIX/.firstboot"
wait_wineserver
fi
if [[ -f "$WINEPREFIX/system.reg" ]] \
&& [[ -z $(grep "Windows $WH_WINDOWS_VER" "$WINEPREFIX/system.reg") ]]
then
if [[ $(echo "$WH_WINDOWS_VER" | sed 's/.*/\L&/') == "xp" ]] \
&& [[ "$WINEARCH" != "win32" ]]
then export WH_WINDOWS_VER="xp64"
fi
env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" winecfg -v $(echo "win${WH_WINDOWS_VER}" | sed 's/.*/\L&/')
wait_wineserver
print_info "Windows версия изменена на win${WH_WINDOWS_VER}"
fi
if [[ -d "$DRIVE_C/users/xuser" ]] && [[ ! -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$DRIVE_C/users/xuser" "$DRIVE_C/users/$USER"
elif [[ ! -d "$DRIVE_C/users/xuser" ]] && [[ -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$DRIVE_C/users/$USER" "$DRIVE_C/users/xuser"
fi
if [[ ! -L "$WINEPREFIX/dosdevices/h:" ]]
then try_force_link_dir "$HOME" "$WINEPREFIX/dosdevices/h:"
fi
try_remove_file "$DRIVE_C/windows/system32/winemenubuilder.exe"
# хак для XRDP сессии
if [[ $DISPLAY == *:10.0 ]] ; then
print_warning "Обнаружена сессия XRDP, настраиваем реестр:"
get_and_set_reg_file --add 'Software\Wine\X11 Driver' 'UseXRandR' 'REG_SZ' "N" "user"
get_and_set_reg_file --add 'Software\Wine\X11 Driver' 'UseXVidMode' 'REG_SZ' "N" "user"
else
get_and_set_reg_file --delete 'Software\Wine\X11 Driver' 'UseXRandR'
get_and_set_reg_file --delete 'Software\Wine\X11 Driver' 'UseXVidMode'
fi
}
##### KILL AUTOSTART AFTER INSTALLING #####
kill_autostart () {
[[ -z "${1}" ]] && fatal "Нет аргумента для функции kill_autostart."
[[ -z "${2}" ]] && SWAIT=3 || SWAIT="${2}"
sleep 5
while ps aux | grep -m 1 -i "$WINESERVER" | grep -v grep &>/dev/null ; do
if [[ -z "$(ps aux | grep -m 1 -i "$1" | grep -v grep | awk '{print $2}')" ]] ; then
print_info "PID для $1 не найден. Ожидаем окончания установки..."
sleep "${SWAIT}"
else
print_ok "PID для $1 найден. Завершаем работу автозапуска приложения."
"$WINESERVER" -k
break
fi
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)} }' )"
fi
if [[ -n "$WH_DLL_INSTALL" ]] ; then
WH_DLL_NEED_INSTALL=""
USE_WT_FROM_DB=0
[[ ! -f "$WINEPREFIX/winetricks.log" ]] && touch "$WINEPREFIX/winetricks.log"
for need_install_dll_to_pfx in $WH_DLL_INSTALL "isolate_home" ; do
if [[ "$need_install_dll_to_pfx" == vcrun201[5-9] ]] ; then
sed -i "/${need_install_dll_to_pfx}/d" "$WINEPREFIX/winetricks.log"
need_install_dll_to_pfx="vcrun2022"
fi
if ! grep "$need_install_dll_to_pfx" "$WINEPREFIX/winetricks.log" &>/dev/null ; then
if [[ -z "$WH_DLL_NEED_INSTALL" ]]
then WH_DLL_NEED_INSTALL="$need_install_dll_to_pfx"
else WH_DLL_NEED_INSTALL="$need_install_dll_to_pfx $WH_DLL_NEED_INSTALL"
fi
USE_WT_FROM_DB=1
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
fi
fi
}
kill_wine () {
wine_pids=$(ls -l /proc/*/exe 2>/dev/null | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')
for pw_kill_pids in ${wine_pids}; do
if ps cax | grep "${pw_kill_pids}" ; then
kill -n 9 "${pw_kill_pids}" &>/dev/null
fi
done
}
init_database () {
if [[ -f "$WIN_FILE_EXEC" ]] ; then
WHDB="$(basename "$WIN_FILE_EXEC" .exe)"
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) -gt 1 ]] ; then
print_error "Найдено более одного файла настроек: $WHDB.exe"
WHDB_FILE="$(echo "$WH_FIND_DB_FILE" | head -n1)"
else
WHDB_FILE="$WH_FIND_DB_FILE"
fi
IFS="$orig_IFS"
fi
if [[ "$WHDB_FILE" ]] ; then
print_info "Используется файл настроек: $WHDB_FILE"
. "$WHDB_FILE"
else
print_warning "Файл настроек не найден. Пропускаем."
fi
fi
}
prepair_wine () {
if [[ -n "$INSTALL_SCRIPT_NAME" ]] \
&& [[ "$FORCE_INSTALL" != "1" ]]
then
print_warning "Лицензионные соглашения использования сторонних компонентов:
Некоторые компоненты, установленные в префикс и необходимые для запуска приложений, могут
быть защищены авторским правом или лицензионными соглашениями. Вы обязаны самостоятельно
убедиться в законности использования этих компонентов в вашей юрисдикции.
Мы не несём ответственности за нарушение лицензионных соглашений, связанное с использованием
подготовленного префикса.
Продолжая использовать данное ПО вы подтверждаете, что ознакомились с данным отказом от
ответственности и принимаете все риски, связанные с его использованием.
"
print_info "Для продолжения нажмите любую клавишу на клавиатуре."
read -s -n 1
fi
var_winedlloverride_update "winemenubuilder.exe=d"
init_database
init_wine_ver
init_wineprefix
use_winetricks
if init_wined3d ; then
:
else
init_dxvk "$DXVK_VER"
init_vkd3d "$VKD3D_VER"
fi
[[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud"
}
wine_run () {
WIN_FILE_PATH="$(dirname "$WIN_FILE_EXEC")"
[[ -d "$WIN_FILE_PATH" ]] && cd "$WIN_FILE_PATH"
if [[ $DEBUG == "0" ]] ; then
$MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS
else
print_var WH_WINE_USE WINEARCH WINEPREFIX WINEDLLOVERRIDES WH_WINDOWS_VER | tee "$LOG_FILE"
$MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$LOG_FILE"
fi
wait_wineserver
}
wine_run_install () {
print_info "Запускаем установку приложения $PROG_NAME."
if [[ "$INSTALL_MODE" == "manual" ]]
then print_warning "Рекомендуется не менять пути для установки приложения!"
fi
[[ ! -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
wait_wineserver
}
run_autoinstall () {
if [[ $1 == "--clear-pfx" ]] ; then
export CLEAR_PREFIX="1"
shift
elif [[ $2 == "--clear-pfx" ]] ; then
export CLEAR_PREFIX="1"
fi
INSTALL_SCRIPT_NAME="${1,,}"
if [[ -f "$WH_AUTOINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then
INSTALL_SCRIPT="$WH_AUTOINSTALL_DIR/$INSTALL_SCRIPT_NAME"
WH_INSTALL_MODE="auto"
elif [[ -f "$WH_MANUALINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then
INSTALL_SCRIPT="$WH_MANUALINSTALL_DIR/$INSTALL_SCRIPT_NAME"
WH_INSTALL_MODE="manual"
else
INSTALL_SCRIPT="0"
fi
export INSTALL_SCRIPT INSTALL_MODE
if [[ $INSTALL_SCRIPT_NAME == "list" ]] || [[ -z "$INSTALL_SCRIPT_NAME" ]] ; then
print_info "Список программ с возможностью автоматической установки:"
for list in $(ls "$WH_AUTOINSTALL_DIR") ; do
AI_INFO="$(grep "info_ru:" "$WH_AUTOINSTALL_DIR/$list" | awk -F"info_ru: " '{print $2}')"
AI_PROGNAME="$(grep "PROG_NAME=" "$WH_AUTOINSTALL_DIR/$list" | awk -F"PROG_NAME=" '{print $2}')"
echo -e "\n$list - $AI_PROGNAME"
echo "$AI_INFO"
done
echo
print_info "Список программ с возможностью установки из существующего дистрибутива:"
for list in $(ls "$WH_MANUALINSTALL_DIR") ; do
AI_INFO="$(grep "info_ru:" "$WH_MANUALINSTALL_DIR/$list" | awk -F"info_ru: " '{print $2}')"
AI_PROGNAME="$(grep "PROG_NAME=" "$WH_MANUALINSTALL_DIR/$list" | awk -F"PROG_NAME=" '{print $2}')"
echo -e "\n$list - $AI_PROGNAME"
echo "$AI_INFO"
done
elif [[ "$INSTALL_SCRIPT" != "0" ]] ; then
source "$INSTALL_SCRIPT" "$@"
print_info "Завершена установка $INSTALL_SCRIPT_NAME"
else
fatal "Скрипт автоматической установки для $INSTALL_SCRIPT_NAME не найден!"
fi
echo
}
##### REMOVE WINEHELPER #####
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 "----------------------------------------------"
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 и все связанные данные успешно удалены."
else
print_info "Удаление отменено."
fi
else
print_info "Удаление отменено."
fi
}
wh_info () {
echo "Использование: $SCRIPT_NAME [команда]
Команды:
install list список возможных установочных скриптов
install [скрипт] запустить скрипт установки программы
install [скрипт] --clear-pfx не использовать подготовленный префикс для установки ПО
installed список установленных программ
run [программа.exe] запуск программы (отладка)
remove удалить WineHelper и все связанные данные
Параметры:
--help показать эту справку и выйти
--version показать информацию о пакете и его версии
--debug [команда] включить режим логирования работы WINE
"
}
##### MAIN #####
create_new_dir "$WH_TMP_DIR"
create_new_dir "$WH_DIST_DIR"
create_new_dir "$WH_PREFIXES_DIR"
create_new_dir "$WH_VULKAN_LIBDIR"
if [[ -d "$HOME/.local/share/$SCRIPT_NAME" ]] \
&& [[ ! -L "$HOME/.winehelper" ]]
then try_force_link_dir "$HOME/.local/share/$SCRIPT_NAME" "$HOME/.winehelper"
fi
case "${1,,}" in
--version) rpm -qi "$SCRIPT_NAME" ; exit 0 ;;
--help) wh_info ; exit 0 ;;
killall) kill_wine ;;
winecfg) prepair_wine ; wine_run "winecfg" ;;
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 "$@" ;;
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 ;;
*)
if [[ -f "$1" ]] ; then
WIN_FILE_EXEC="$(readlink -f "$1")"
WIN_FILE_NAME="$(basename "$WIN_FILE_EXEC")"
shift
case "${WIN_FILE_NAME,,}" in
*.exe) prepair_wine ; wine_run $WINE_WIN_START "$WIN_FILE_EXEC" "$@" ;;
*.msi) prepair_wine ; wine_run msiexec /i "$WIN_FILE_EXEC" "$@" ;;
*.bat|*.cmd) prepair_wine ; wine_run start "$WIN_FILE_EXEC" "$@" ;;
*) fatal "Тип файла не поддерживается." ;;
esac
else
wh_info
exit 1
fi
;;
esac