Compare commits

..

2 Commits

Author SHA1 Message Date
Sergey Palcheh
61fb7d9847 a typo has been fixed 2025-09-17 13:38:19 +06:00
Sergey Palcheh
443c040edd the winemenubuilder is disabled so that it does not create unnecessary shortcuts in the Wine system menu 2025-09-17 13:35:47 +06:00
8 changed files with 102 additions and 120 deletions

View File

@@ -6,10 +6,10 @@ export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="scadoffice"
export PROG_NAME="SCAD Office"
export PROG_ICON="scadoffice"
export BASE_PFX="scadaoffice_pfx_x64_v04"
export BASE_PFX="scadaoffice_pfx_x64_v03"
export WH_WINDOWS_VER="10"
export WINEARCH="win64"
export INSTALL_DLL="dotnet20 dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6"
export INSTALL_DLL="dotnet20 dotnet472 dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6"
export WH_XDG_OPEN="rtf"
AUTOINSTALL_EXE="${WH_TMP_DIR}/SCADOffice_installer.exe"
SCADOFFICE_ADDONS_URL="https://cloud.linux-gaming.ru/portproton/scadoffice_addons_v02.tar.xz"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env bash
# info_ru: Установщик программного комплекса NetTest (демо-версия)
########################################################################
export PROG_URL="https://www.kpolyakov.spb.ru/prog/nettest/nettget.htm"
export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="nettest"
export PROG_NAME="NetTest"
export PROG_ICON="nettest"
export BASE_PFX="none"
export WINEARCH="win64"
export INSTALL_DLL=""
export WH_WINDOWS_VER="10"
ZIP_FILE="$2"
if [[ -f "$ZIP_FILE" ]] \
&& [[ $ZIP_FILE =~ ".zip" ]]
then
prepair_wine
PROG_PATH="$DRIVE_C/nettest"
unpack "$2" "$PROG_PATH"
cp -fr "$PROG_PATH/fonts/"* "$DRIVE_C/windows/Fonts/"
create_desktop "$PROG_NAME (Сервер)" "$PROG_PATH/testser.exe" "nettest_server"
create_desktop "$PROG_NAME (Клиент)" "$PROG_PATH/testcli.exe" "nettest_client"
else
fatal "Не найден файл архива для $PROG_NAME. Перезапустите по примеру:
winehelper install $1 \"/путь/до/архива\""
fi

View File

@@ -5,7 +5,6 @@
fb7fdfde96de10a1b3b051bdf2727b6a7c1768b878483726454dd6726e9e0193 wine-9.0.14-alt1-i586-spravkibk.tar.xz
e0a84bb4908c3927954d7eef6b8ac7212e442b8c107d000c6890fec340f96183 wine-9.0.14-alt1-amd64.tar.xz
6f86d2220b65b709bf88c6f829a4998de3b929cc2091cd1333a51c32e1491b79 wine-9.0.9-alt1-i586.tar.xz
f1bf1261550ca2928cefacdb724926d3d6d103433d0ff6882ee9783a50d8f4e4 wine-8.8-staging-amd64.tar.xz
61bec1230b37b8fcc69fd45f848b44fd88cc41fcdd5dc3080336d7da63660f40 wine-7.16.1-alt1-amd64.tar.xz
6fea17fd131f57c2ebf7ca4c60d3c5a9e819afe16e5d0b77ecb750da99ae0e38 wine-7.16.1-alt1-i586.tar.xz
@@ -212,8 +211,8 @@ dfb44ce5e5af7dba1686932c63d6b05e5dd6919a21c78130a7d1d0271b93958e audiorecstatio
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks arial dotnet7 dotnetdesktop7 renderer=gdi
4fa93434c5c15440014357323257ddcee7d28b94ad6a56bd6f5a08b33ae4c3cb scadaoffice_pfx_x64_v04.tar.xz
# create with wine-8.8-staging-amd64
25e277c7afa4a9afc5f013cb05f872c12a7f381c4f0503a423dcacccca9a14c6 scadaoffice_pfx_x64_v03.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6 dotnet20
# + addons with ODBC, SSH, *.reg
0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb scadoffice_addons_v02.tar.xz

View File

@@ -617,7 +617,6 @@ create_desktop () {
echo "StartupNotify=true"
echo "Path=$DATA_PATH"
echo "Icon=$icon_file"
echo "StartupWMClass=$(basename "$exe_file")"
} > "$USER_WORK_PATH/$desktop_filename.desktop"
chmod +x "$USER_WORK_PATH/$desktop_filename.desktop"
@@ -653,7 +652,7 @@ create_desktop () {
[Desktop Entry]
Type=Directory
Name=WineHelper
Icon=winehelper
Icon=wine
EOF
fi
@@ -1111,11 +1110,6 @@ init_wineprefix () {
export DRIVE_C="$WINEPREFIX/drive_c"
export XUSER_PATH="$DRIVE_C/users/xuser"
if [[ -d "$XUSER_PATH" ]] \
&& [[ ! -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$XUSER_PATH" "$DRIVE_C/users/$USER"
fi
if [[ ! -f "$WINEPREFIX/.firstboot" ]] ; then
create_new_dir "$WINEPREFIX"
if [[ "$CLEAR_PREFIX" == "1" ]]
@@ -1361,6 +1355,8 @@ init_database () {
}
prepair_wine () {
var_winedlloverride_update "winemenubuilder.exe=d"
if [[ -n "$INSTALL_SCRIPT_NAME" ]]
then print_info "Используются настройки из скрипта установки: $INSTALL_SCRIPT_NAME"
else init_database
@@ -1818,9 +1814,9 @@ create_base_pfx () {
&& [[ ! -L "$users_dir/$USER" ]]
then
if [[ -L "$users_dir/xuser" ]]
then try_remove_dir "$users_dir/xuser"
then try_remove_dir "$users_dir/xuser/"
fi
create_new_dir "$users_dir/xuser"
create_new_dir "$users_dir/xuser/"
cp -fr "$users_dir/$USER"/* "$users_dir/xuser/"
fi
@@ -2131,19 +2127,6 @@ select_component_version() {
done
}
run_install_to_prefix() {
export WINEPREFIX="$1"
local WIN_FILE_EXEC="$2"
if [[ -z "$WINEPREFIX" ]] || [[ -z "$WIN_FILE_EXEC" ]]; then
fatal "Использование: $SCRIPT_NAME install-to-prefix <имя_префикса> <путь_к_установщику>"
fi
check_prefix_var
prepair_wine
wine_run_install "$WIN_FILE_EXEC"
}
run_install_dxvk() {
local version="$1"
if [[ -z "$version" ]] ; then
@@ -2260,10 +2243,6 @@ else
arg1="--help"
fi
# отключаем создание .desktop файлов средствами wine
# и отключаем winebth, так как может сломать winedevice.exe
var_winedlloverride_update "winemenubuilder.exe,winebth.sys=d"
case "$arg1" in
--version|version) rpm -qi "$SCRIPT_NAME" ; exit 0 ;;
--help|help) wh_info ; exit 0 ;;
@@ -2276,7 +2255,6 @@ case "$arg1" in
winetricks) prepair_wine ; "$WH_WINETRICKS" -q "$@" ;;
desktop) create_desktop "$@" ; exit 0 ;;
install|-i) run_autoinstall "$@" ;;
install-to-prefix) run_install_to_prefix "$@" ;;
install-dxvk) run_install_dxvk "$@" ;;
install-vkd3d) run_install_vkd3d "$@" ;;
change-wine) run_change_wine_version "$@" ;;

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env xdg-open
[Desktop Entry]
Name=WineHelper
Exec=winehelper gui %F
@@ -8,4 +7,3 @@ Type=Application
Categories=WineHelper;Utility;Emulator;
StartupNotify=true
Icon=winehelper
StartupWMClass=winehelper

View File

@@ -594,6 +594,7 @@ class WinetricksManagerDialog(QDialog):
env.insert("WINEPREFIX", self.prefix_path)
env.insert("WINE", self.wine_executable)
# Отключаем winemenubuilder, чтобы избежать зависаний, связанных с 'wineserver -w'.
env.insert("WINEDLLOVERRIDES", "winemenubuilder.exe=d")
# Это известная проблема при запуске winetricks из ГУИ.
process.setProcessEnvironment(env)
@@ -834,6 +835,8 @@ class WinetricksManagerDialog(QDialog):
env = QProcessEnvironment.systemEnvironment()
env.insert("WINEPREFIX", self.prefix_path)
env.insert("WINE", self.wine_executable)
# Отключаем winemenubuilder, чтобы он не создавал лишние ярлыки в системном меню Wine.
env.insert("WINEDLLOVERRIDES", "winemenubuilder.exe=d")
self.apply_process.setProcessEnvironment(env)
self.apply_process.readyReadStandardOutput.connect(lambda: self.log_output.append(self.apply_process.readAllStandardOutput().data().decode('utf-8', 'ignore').strip()))
self.apply_process.finished.connect(self.on_apply_finished)
@@ -2142,49 +2145,61 @@ class WineHelperGUI(QMainWindow):
self.vkd3d_manage_button.setToolTip("Установка или удаление определенной версии vkd3d-proton в префиксе.")
management_layout.addWidget(self.vkd3d_manage_button, 5, 1)
# --- Правая сторона: Информационный блок и кнопки установки ---
right_column_widget = QWidget()
right_column_layout = QVBoxLayout(right_column_widget)
right_column_layout.setContentsMargins(0, 0, 0, 0)
right_column_layout.setSpacing(10)
# --- Правая сторона: Информационный блок ---
self.prefix_info_display = QTextBrowser()
self.prefix_info_display.setReadOnly(True)
self.prefix_info_display.setFrameStyle(QFrame.StyledPanel)
right_column_layout.addWidget(self.prefix_info_display)
# Увеличиваем rowspan, чтобы охватить все строки с кнопками
management_layout.addWidget(self.prefix_info_display, 0, 2, 6, 1)
management_layout.setColumnStretch(0, 1)
management_layout.setColumnStretch(1, 1)
management_layout.setColumnStretch(2, 2)
separator = QFrame()
separator.setFrameShape(QFrame.HLine)
separator.setFrameShadow(QFrame.Sunken)
management_layout.addWidget(separator, 6, 0, 1, 3)
install_group = QWidget()
install_layout = QVBoxLayout(install_group)
install_layout.setContentsMargins(0, 0, 0, 0)
install_layout.setContentsMargins(0, 5, 0, 0)
install_layout.setSpacing(5)
install_path_layout = QHBoxLayout()
self.prefix_install_path_edit = QLineEdit()
self.prefix_install_path_edit.setPlaceholderText("Укажите путь к установочному файлу .exe или .msi...")
install_path_layout.addWidget(self.prefix_install_path_edit)
self.prefix_browse_button = QPushButton("Обзор...")
self.prefix_browse_button.clicked.connect(self.browse_for_prefix_installer)
install_path_layout.addWidget(self.prefix_browse_button)
install_layout.addLayout(install_path_layout)
# Layout для кнопок установки и создания ярлыка
action_buttons_layout = QHBoxLayout()
self.prefix_install_button = QPushButton("Установить приложение в префикс")
self.prefix_install_button.setEnabled(False)
self.prefix_install_button.clicked.connect(self.browse_and_run_prefix_installer)
install_layout.addWidget(self.prefix_install_button)
self.prefix_install_button.clicked.connect(self.run_prefix_installer)
action_buttons_layout.addWidget(self.prefix_install_button)
self.create_launcher_button = QPushButton("Создать ярлык для приложения в префиксе")
self.create_launcher_button.setToolTip(
"Создает ярлык в меню и на вкладке 'Установленные' для .exe файла внутри префикса.")
self.create_launcher_button.clicked.connect(self.create_launcher_for_prefix)
self.create_launcher_button.setEnabled(False) # Изначально неактивна
install_layout.addWidget(self.create_launcher_button)
right_column_layout.addWidget(install_group)
right_column_layout.setStretch(0, 1) # Информационное окно растягивается
right_column_layout.setStretch(1, 0) # Группа кнопок не растягивается
management_layout.addWidget(right_column_widget, 0, 2, 6, 1)
management_layout.setColumnStretch(0, 1)
management_layout.setColumnStretch(1, 1)
management_layout.setColumnStretch(2, 2)
action_buttons_layout.addWidget(self.create_launcher_button)
install_layout.addLayout(action_buttons_layout)
management_layout.addWidget(install_group, 7, 0, 1, 3)
container_layout.addWidget(self.prefix_management_groupbox)
layout.addWidget(self.management_container_groupbox)
layout.addStretch()
self.add_tab(self.prefix_tab, "Менеджер префиксов")
self.prefix_install_path_edit.textChanged.connect(self.update_prefix_install_button_state)
def _get_current_prefixes(self):
"""Возвращает множество имен существующих префиксов."""
prefixes_root_path = os.path.join(Var.USER_WORK_PATH, "prefixes")
@@ -2310,6 +2325,7 @@ class WineHelperGUI(QMainWindow):
# Успешное удаление, обновляем GUI
self._remove_prefix_from_gui_state(prefix_name)
self.update_installed_apps()
QMessageBox.information(self, "Успех", f"Префикс '{prefix_name}' и все связанные с ним данные были успешно удалены.")
else:
QMessageBox.critical(self, "Ошибка удаления", f"Не удалось удалить префикс '{prefix_name}'.\nПодробности смотрите в логе.")
@@ -2318,16 +2334,18 @@ class WineHelperGUI(QMainWindow):
is_prefix_selected = bool(prefix_name)
self.prefix_management_groupbox.setEnabled(is_prefix_selected)
self.create_launcher_button.setEnabled(is_prefix_selected)
self.prefix_install_button.setEnabled(is_prefix_selected)
if is_prefix_selected:
self.update_prefix_info_display(prefix_name)
else:
self.prefix_info_display.clear()
self.prefix_install_path_edit.clear()
# Сбрасываем состояние кнопок, когда префикс не выбран
self.esync_button.setChecked(False)
self.fsync_button.setChecked(False)
self.update_prefix_install_button_state()
def update_prefix_info_display(self, prefix_name):
"""Обновляет информационный блок для созданного префикса, читая данные из last.conf."""
if not prefix_name:
@@ -2407,13 +2425,8 @@ class WineHelperGUI(QMainWindow):
html_content += "</p>"
self.prefix_info_display.setHtml(html_content)
def browse_and_run_prefix_installer(self):
"""Открывает диалог выбора файла и запускает установку в созданный префикс."""
prefix_name = self.current_managed_prefix_name
if not prefix_name:
QMessageBox.warning(self, "Ошибка", "Сначала выберите префикс для установки.")
return
def browse_for_prefix_installer(self):
"""Открывает диалог выбора файла для установки в созданный префикс."""
file_path, _ = QFileDialog.getOpenFileName(
self,
"Выберите установочный файл",
@@ -2421,11 +2434,18 @@ class WineHelperGUI(QMainWindow):
"Исполняемые файлы (*.exe *.msi);;Все файлы (*)"
)
if file_path:
self.run_prefix_installer(file_path)
self.prefix_install_path_edit.setText(file_path)
def run_prefix_installer(self, installer_path):
"""Запускает установку файла в выбранный префикс через скрипт winehelper."""
def update_prefix_install_button_state(self):
"""Обновляет состояние кнопки установки в префикс."""
path_ok = bool(self.prefix_install_path_edit.text().strip())
prefix_selected = self.current_managed_prefix_name is not None
self.prefix_install_button.setEnabled(path_ok and prefix_selected)
def run_prefix_installer(self):
"""Запускает установку файла в выбранный префикс."""
prefix_name = self.current_managed_prefix_name
installer_path = self.prefix_install_path_edit.text().strip()
if not prefix_name:
QMessageBox.warning(self, "Ошибка", "Не выбран префикс для установки.")
@@ -2434,6 +2454,9 @@ class WineHelperGUI(QMainWindow):
QMessageBox.warning(self, "Ошибка", "Указан неверный путь к установочному файлу.")
return
prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name)
wine_executable = self._get_wine_executable_for_prefix(prefix_name)
self.command_dialog = QDialog(self)
self.command_dialog.setWindowTitle(f"Установка в префикс: {prefix_name}")
self.command_dialog.setMinimumSize(750, 400)
@@ -2457,12 +2480,15 @@ class WineHelperGUI(QMainWindow):
self.command_process.readyReadStandardOutput.connect(self._handle_command_output)
self.command_process.finished.connect(self._handle_prefix_install_finished)
# Окружение полностью настраивается скриптом winehelper
self.command_process.setProcessEnvironment(QProcessEnvironment.systemEnvironment())
env = QProcessEnvironment.systemEnvironment()
env.insert("WINEPREFIX", prefix_path)
# Отключаем winemenubuilder, чтобы установщик не создавал ярлыки в обход WineHelper.
env.insert("WINEDLLOVERRIDES", "winemenubuilder.exe=d")
self.command_process.setProcessEnvironment(env)
args = ["install-to-prefix", prefix_name, installer_path]
self.command_log_output.append(f"Выполнение: {shlex.quote(self.winehelper_path)} {' '.join(shlex.quote(a) for a in args)}")
self.command_process.start(self.winehelper_path, args)
args = [installer_path]
self.command_log_output.append(f"Запуск установки: {shlex.quote(wine_executable)} {shlex.quote(installer_path)}")
self.command_process.start(wine_executable, args)
self.command_dialog.exec_()
def _get_prefix_component_version(self, prefix_name, component_key):
@@ -2934,6 +2960,8 @@ class WineHelperGUI(QMainWindow):
env.insert("WH_WINE_USE", wine_use)
if base_pfx:
env.insert("BASE_PFX", base_pfx)
# Отключаем winemenubuilder, чтобы при инициализации префикса не создавались стандартные ярлыки Wine.
env.insert("WINEDLLOVERRIDES", "winemenubuilder.exe=d")
self.command_process.setProcessEnvironment(env)
args = ["init-prefix"]
@@ -2970,6 +2998,10 @@ class WineHelperGUI(QMainWindow):
if not self.management_container_groupbox.isVisible():
self.management_container_groupbox.setVisible(True)
QMessageBox.information(self, "Успех",
f"Префикс '{prefix_name}' успешно создан.\n"
"Теперь вы можете управлять им, выбрав его из выпадающего списка.")
def update_installed_apps(self):
"""Обновляет список установленных приложений в виде кнопок"""
# Если активная кнопка находится в списке удаляемых, сбрасываем ее
@@ -3038,6 +3070,7 @@ class WineHelperGUI(QMainWindow):
self.command_process.deleteLater()
self.command_process = None
self.command_close_button.setEnabled(True)
self.prefix_install_path_edit.clear()
self.update_installed_apps()
def _set_active_button(self, button_widget):
@@ -3058,13 +3091,11 @@ class WineHelperGUI(QMainWindow):
def show_installed_app_info(self, desktop_path, button_widget):
"""Показывает информацию об установленном приложении в правой панели."""
self._set_active_button(button_widget)
# Если в поиске был текст, очищаем его и перерисовываем список.
# Это предотвращает "прыжок", если список не был отфильтрован.
if self.installed_search_edit.text():
self.installed_search_edit.blockSignals(True)
self.installed_search_edit.clear()
self.installed_search_edit.blockSignals(False)
self.filter_installed_buttons()
# Очищаем поле поиска и принудительно обновляем список, чтобы показать все приложения
self.installed_search_edit.blockSignals(True)
self.installed_search_edit.clear()
self.installed_search_edit.blockSignals(False)
self.filter_installed_buttons()
# Прокручиваем к выбранному элементу
frame = button_widget.parent()
@@ -3734,14 +3765,11 @@ class WineHelperGUI(QMainWindow):
search_edit = tab_data['search_edit']
scroll_area = tab_data['scroll_area']
# Если в поиске был текст, очищаем его и перерисовываем список.
# Это предотвращает "прыжок", если список не был отфильтрован.
if search_edit.text():
search_edit.blockSignals(True)
search_edit.clear()
search_edit.blockSignals(False)
self.filter_buttons(tab_type)
# Общая логика: очищаем поиск, обновляем список и прокручиваем к элементу
search_edit.blockSignals(True)
search_edit.clear()
search_edit.blockSignals(False)
self.filter_buttons(tab_type)
frame = button_widget.parent()
if isinstance(frame, QFrame):
QTimer.singleShot(0, lambda: scroll_area.ensureWidgetVisible(frame))
@@ -4103,6 +4131,18 @@ class WineHelperGUI(QMainWindow):
self.created_prefix_selector.setCurrentIndex(0)
# --- Конец обновления списка префиксов ---
# Создаем кастомный диалог, чтобы кнопка была на русском
success_box = QMessageBox(self.install_dialog)
success_box.setWindowTitle("Успех")
title_name = self._get_current_app_title()
success_text = f"Программа «{title_name}» установлена успешно!"
if new_prefix_name:
success_text += f"\n\nНовый префикс '{new_prefix_name}' был автоматически выбран в списке управления на вкладке 'Менеджер префиксов'."
success_box.setText(success_text)
success_box.setIcon(QMessageBox.Information)
success_box.addButton("Готово", QMessageBox.AcceptRole)
success_box.exec_()
self.update_installed_apps()
# Кнопка закрыть
@@ -4202,6 +4242,7 @@ class WineHelperGUI(QMainWindow):
"""Обрабатывает завершение создания ярлыка."""
self._handle_command_finished(exit_code, exit_status)
if exit_code == 0:
QMessageBox.information(self, "Успех", "Ярлык успешно создан.")
self.update_installed_apps()
# Переключаемся на вкладку "Установленные"
for i in range(self.tab_bar.count()):