Compare commits

..

1 Commits

Author SHA1 Message Date
Sergey Palcheh
799185a132 test 2025-10-03 11:31:26 +06:00
36 changed files with 347 additions and 832 deletions

View File

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

368
README.md
View File

@@ -8,28 +8,28 @@
<img src="image/handbook/auto_install.png" alt="WineHelper GUI" width="80%"> <img src="image/handbook/auto_install.png" alt="WineHelper GUI" width="80%">
</p> </p>
## Основные возможности <h2>Основные возможности</h2>
* **Простая установка**: Устанавливайте Windows-приложения с помощью готовых скриптов, как в автоматическом, так и в ручном режиме. <ul>
* **Изолированные окружения**: Каждое приложение устанавливается в свой собственный, изолированный префикс, что предотвращает конфликты. <li><b>Простая установка</b>: Устанавливайте Windows-приложения с помощью готовых скриптов, как в автоматическом, так и в ручном режиме.</li>
* **Управление версиями Wine**: Легко переключайтесь между различными версиями Wine и Proton для достижения наилучшей совместимости. <li><b>Изолированные окружения</b>: Каждое приложение устанавливается в свой собственный, изолированный префикс, что предотвращает конфликты.</li>
* **Графический и консольный интерфейсы**: Используйте удобный GUI для повседневных задач или мощный CLI для автоматизации. <li><b>Управление версиями Wine</b>: Легко переключайтесь между различными версиями Wine и Proton для достижения наилучшей совместимости.</li>
* **Резервное копирование**: Создавайте и восстанавливайте полные резервные копии ваших префиксов. <li><b>Графический и консольный интерфейсы</b>: Используйте удобный GUI для повседневных задач или мощный CLI для автоматизации.</li>
* **Встроенные утилиты**: Быстрый доступ к `winecfg`, `regedit`, `Winetricks` и другим инструментам для каждого префикса. <li><b>Резервное копирование</b>: Создавайте и восстанавливайте полные резервные копии ваших префиксов.</li>
<li><b>Встроенные утилиты</b>: Быстрый доступ к <code>winecfg</code>, <code>regedit</code>, <code>Winetricks</code> и другим инструментам для каждого префикса.</li>
--- </ul>
<hr>
<!-- Описание установки WineHelper--> <!-- Описание установки WineHelper-->
<details> <details>
<summary style="font-size: 35px; font-weight: bold;">Установка</summary> <summary style="font-size: 35px; font-weight: bold;">Установка</summary>
``` <pre><code> $ su -
$ su -
# apt-get update && apt-get dist-upgrade # apt-get update && apt-get dist-upgrade
# apt-get install winehelper # apt-get install winehelper
# exit # exit
``` </code></pre>
</details> </details>
@@ -37,160 +37,162 @@
<details> <details>
<summary style="font-size: 35px; font-weight: bold;">Использование WineHelper (CLI)</summary> <summary style="font-size: 35px; font-weight: bold;">Использование WineHelper (CLI)</summary>
### Список приложений для установки <h3>Список приложений для установки</h3>
Вывод списка приложений, доступных к установке: <p>Вывод списка приложений, доступных к установке:</p>
``` <pre><code> $ winehelper install list
$ winehelper install list </code></pre>
``` <p>или сокращенная команда:</p>
или сокращенная команда: <pre><code> $ winehelper -i
``` </code></pre>
$ winehelper -i
```
### Запуск установки приложений <h3>Запуск установки приложений</h3>
Скрипты установки разделены на два типа: <p>Скрипты установки разделены на два типа:</p>
1. **Список программ с возможностью автоматической установки** — содержит полностью автоматизированные скрипты установок программ у которыx есть дистрибутивы (установщики) в свободном доступе. <ol>
<li><b>Список программ с возможностью автоматической установки</b> — содержит полностью автоматизированные скрипты установок программ у которыx есть дистрибутивы (установщики) в свободном доступе.
Процесс полностью автоматизирован. Процесс полностью автоматизирован.
Пример: Пример:
``` <pre><code> $ winehelper install spravki-bk
$ winehelper install spravki-bk </code></pre>
```
или сокращенная команда: или сокращенная команда:
``` <pre><code> $ winehelper -i spravki-bk
$ winehelper -i spravki-bk </code></pre>
``` </li>
2. **Список программ с возможностью установки из существующего дистрибутива** — содержит скрипты установок для программ, которых нет в свободном доступе. <li><b>Список программ с возможностью установки из существующего дистрибутива</b> — содержит скрипты установок для программ, которых нет в свободном доступе.
Пример: Пример:
``` <pre><code> $ winehelper install is-record-station "/путь/до/установочногоайла"
$ winehelper install is-record-station "/путь/до/установочногоайла" </code></pre>
```
или сокращенная команда: или сокращенная команда:
``` <pre><code> $ winehelper -i is-record-station "/путь/до/установочногоайла"
$ winehelper -i is-record-station "/путь/до/установочногоайла" </code></pre>
``` </li>
</ol>
### Процесс установки приложений <h3>Процесс установки приложений</h3>
При первом запуске **WineHelper** проверяются и при необходимости устанавливаются дополнительные зависимости (запрашиваются права root). <p>При первом запуске <b>WineHelper</b> проверяются и при необходимости устанавливаются дополнительные зависимости (запрашиваются права root).</p>
Процесс установки приложений: <p>Процесс установки приложений:</p>
1. Отображаются лицензионные соглашения на сторонние компоненты. Для продолжения введите **y** и нажмите **Enter**. <ol>
2. Далее процесс проходит автоматически с подробным выводом в терминал: <li>Отображаются лицензионные соглашения на сторонние компоненты. Для продолжения введите <b>y</b> и нажмите <b>Enter</b>.</li>
- Загрузка и проверка хэш-суммы нужной версии Wine. <li>Далее процесс проходит автоматически с подробным выводом в терминал:
- Загрузка и проверка хэш-суммы базового префикса. <ul>
- Инициализация и подготовка префикса. <li>Загрузка и проверка хэш-суммы нужной версии Wine.</li>
- Скачивание дистрибутива (установщика) программы с официального сайта (если применимо). <li>Загрузка и проверка хэш-суммы базового префикса.</li>
- Установка приложения. <li>Инициализация и подготовка префикса.</li>
- Создание .desktop-файла (ярлыка) на рабочем столе и в меню приложений. <li>Скачивание дистрибутива (установщика) программы с официального сайта (если применимо).</li>
<li>Установка приложения.</li>
<li>Создание .desktop-файла (ярлыка) на рабочем столе и в меню приложений.</li>
</ul>
</li>
</ol>
Если устанавливаемое приложение требует дополнительных действий от пользователя (ввод лицензии, настройка), это будет явно указано в терминале. <p>Если устанавливаемое приложение требует дополнительных действий от пользователя (ввод лицензии, настройка), это будет явно указано в терминале.</p>
### Удаление префикса с приложением <h3>Удаление префикса с приложением</h3>
Для удаления префикса выполните команду: <p>Для удаления префикса выполните команду:</p>
``` <pre><code> $ winehelper remove-prefix [имя_префикса]
$ winehelper remove-prefix [имя_префикса] </code></pre>
``` <p>Если имя префикса не указано, будет выведен список существующих префиксов:</p>
Если имя префикса не указано, будет выведен список существующих префиксов: <pre><code> 0 - Отмена
```
0 - Отмена
1 - Префикс1 1 - Префикс1
2 - Префикс2 2 - Префикс2
Выберите префикс (0-2): Выберите префикс (0-2):
``` </code></pre>
Необходимо указать номер удаляемого префикса и нажать клавишу **Enter**.Далее потребуется подтвердить удаление префикса вводом **y**. <p>Необходимо указать номер удаляемого префикса и нажать клавишу <b>Enter</b>.Далее потребуется подтвердить удаление префикса вводом <b>y</b>.</p>
В результате будут удалены: <p>В результате будут удалены:</p>
- сам префикс; <ul>
- установленное ПО; <li>сам префикс;</li>
- desktop-файлы (ярлыки для установленного ПО в префиксе). <li>установленное ПО;</li>
<li>desktop-файлы (ярлыки для установленного ПО в префиксе).</li>
</ul>
### <h3>Резервное копирование префикса</h3>
Команда создания резервной копии префикса: <p>Команда создания резервной копии префикса:</p>
``` <pre><code> $ winehelper backup-prefix [имя_префикса]
$ winehelper backup-prefix [имя_префикса] </code></pre>
``` <p>Если имя префикса не указано, будет выведен список существующих префиксов:</p>
Если имя префикса не указано, будет выведен список существующих префиксов: <pre><code> 0 - Отмена
```
0 - Отмена
1 - Префикс1 1 - Префикс1
2 - Префикс2 2 - Префикс2
Выберите префикс (0-2): Выберите префикс (0-2):
``` </code></pre>
Необходимо указать номер удаляемого префикса и нажать клавишу **Enter**. <p>Необходимо указать номер удаляемого префикса и нажать клавишу <b>Enter</b>.<br>
После выбора префикса автоматически: После выбора префикса автоматически:</p>
- Создаётся копия префикса. <ul>
- Внутри префикса сохраняется используемая версия WINE. <li>Создаётся копия префикса.</li>
- Копируются иконки для ярлыков (.desktop-файлов). <li>Внутри префикса сохраняется используемая версия WINE.</li>
- Сохраняется информация о ярлыках (.desktop-файлах) для будущей распаковки/восстановления префикса. <li>Копируются иконки для ярлыков (.desktop-файлов).</li>
- Резервная копия сохраняется на рабочем столе с именем: {{path|backup_имя_префиксаата_создания.whpack}} <li>Сохраняется информация о ярлыках (.desktop-файлах) для будущей распаковки/восстановления префикса.</li>
<li>Резервная копия сохраняется на рабочем столе с именем: <code>backup_имя_префиксаата_создания.whpack</code></li>
</ul>
### Восстановление префикса из резервной копии <h3>Восстановление префикса из резервной копии</h3>
Команда восстановления префикса из резервной копии: <p>Команда восстановления префикса из резервной копии:</p>
``` <pre><code> $ winehelper restore-prefix "путь/до/файла.whpack"
$ winehelper restore-prefix "путь/до/файла.whpack" </code></pre>
``` <p>Восстановление префикса не требует подключение к интернету и происходит в автоматическом режиме:</p>
Восстановление префикса не требует подключение к интернету и происходит в автоматическом режиме: <ul>
- Распаковка префикса. <li>Распаковка префикса.</li>
- Восстановление версии WINE. <li>Восстановление версии WINE.</li>
- Восстановление ярлыков (.desktop-файdлов). <li>Восстановление ярлыков (.desktop-файdлов).</li>
</ul>
После завершения восстановления приложение будет доступно для запуска через меню или рабочий стол. <p>После завершения восстановления приложение будет доступно для запуска через меню или рабочий стол.</p>
### Использование команд WINE в WineHelper <h3>Использование команд WINE в WineHelper</h3>
WineHelper предоставляет доступ к основным инструментам WINE: <p>WineHelper предоставляет доступ к основным инструментам WINE:</p>
``` <pre><code> winehelper winefile # запуск файлового менеджера wine
winehelper winefile # запуск файлового менеджера wine
winehelper winecfg # запуск wine конфигуратора для префикса winehelper winecfg # запуск wine конфигуратора для префикса
winehelper winereg # запуск редактора реестра для префикса winehelper winereg # запуск редактора реестра для префикса
winehelper wineconsole # запуск терминала wine (cmd.exe) winehelper wineconsole # запуск терминала wine (cmd.exe)
winehelper winetricks # запуск графического интерфейса winetricks winehelper winetricks # запуск графического интерфейса winetricks
winehelper winetricks [компонент] # автоматическая установка дополнительного компонента в префикс winehelper winetricks [компонент] # автоматическая установка дополнительного компонента в префикс
``` </code></pre>
После выполнения любой из вышеперечисленных команд отображается список существующих префиксов: <p>После выполнения любой из вышеперечисленных команд отображается список существующих префиксов:</p>
``` <pre><code>0 - Отмена
1 - Префикс1
2 - Префикс2
Выберите префикс (0-2):
</code></pre>
<p>Команда выполняется в выбранном вами префиксе.</p>
<h3>Запуск стороннего *.exe файла в WineHelper</h3>
<p>Есть два варианта:</p>
<ol>
<li>В командной строке выполнить команду:
<pre><code> $ winehelper "путь/до/файла.exe"
0 - Отмена 0 - Отмена
1 - Префикс1 1 - Префикс1
2 - Префикс2 2 - Префикс2
Выберите префикс (0-2): Выберите префикс (0-2):
``` </code></pre>
Команда выполняется в выбранном вами префиксе. <p>Файл будет запущен в выбранном префиксе.</p>
</li>
### Запуск стороннего *.exe файла в WineHelper <li>С помощью файлового менеджера WINE:
<pre><code> $ winehelper winefile
Есть два варианта:
1. В командной строке выполнить команду:
```
$ winehelper "путь/до/файла.exe"
0 - Отмена 0 - Отмена
1 - Префикс1 1 - Префикс1
2 - Префикс2 2 - Префикс2
Выберите префикс (0-2): Выберите префикс (0-2):
``` </code></pre>
Файл будет запущен в выбранном префиксе. <p>В файловом менеджере найти и запустить нужный exe-файл.</p>
</li>
</ol>
2. С помощью файлового менеджера WINE:''' <h3>Дополнительные команды</h3>
```
$ winehelper winefile
0 - Отмена
1 - Префикс1
2 - Префикс2
Выберите префикс (0-2):
```
В файловом менеджере найти и запустить нужный exe-файл.
### Дополнительные команды <pre><code> $ winehelper help
</code></pre>
``` <p>Вывод:</p>
$ winehelper help
```
Вывод:
<pre> <pre>
Использование: winehelper [команда] Использование: winehelper [команда]
@@ -225,9 +227,9 @@ WineHelper предоставляет доступ к основным инст
<details> <details>
<summary style="font-size: 35px; font-weight: bold;">Использование WineHelper (GUI)</summary> <summary style="font-size: 35px; font-weight: bold;">Использование WineHelper (GUI)</summary>
### Вкладки «Автоматическая установка» и «Ручная установка» <h3>Вкладки «Автоматическая установка» и «Ручная установка»</h3>
При использовании графического интерфейса списки приложений расположены во вкладках **Автоматическая установка** и **Ручная установка**. <p>При использовании графического интерфейса списки приложений расположены во вкладках <b>Автоматическая установка</b> и <b>Ручная установка</b>.</p>
<div align="center"> <div align="center">
<img src="image/handbook/auto_install.png"> <img src="image/handbook/auto_install.png">
@@ -239,30 +241,30 @@ WineHelper предоставляет доступ к основным инст
<p><em>Вкладка "Ручная установка"</em></p> <p><em>Вкладка "Ручная установка"</em></p>
</div> </div>
Для поиска нужной программы введите название в поле поиска. <p>Для поиска нужной программы введите название в поле поиска.</p>
<div align="center"> <div align="center">
<img src="image/handbook/search.png"> <img src="image/handbook/search.png">
<p><em>Поле поиска</em></p> <p><em>Поле поиска</em></p>
</div> </div>
При выборе программы из списка слева, в правой части окна отображается подробная информация о ней: описание, иконка и ссылка на официальный сайт. <p>При выборе программы из списка слева, в правой части окна отображается подробная информация о ней: описание, иконка и ссылка на официальный сайт.</p>
<div align="center"> <div align="center">
<img src="image/handbook/info.png"> <img src="image/handbook/info.png">
<p><em>Информация о выбранной программе</em></p> <p><em>Информация о выбранной программе</em></p>
</div> </div>
Для установки программы нажмите кнопку **Установить**. <p>Для установки программы нажмите кнопку <b>Установить</b>.</p>
Для **ручной установки** дополнительно потребуется указать путь к установочному файлу (`.exe` или `.msi`), который вы скачали самостоятельно. <p>Для <b>ручной установки</b> дополнительно потребуется указать путь к установочному файлу (<code>.exe</code> или <code>.msi</code>), который вы скачали самостоятельно.</p>
<div align="center"> <div align="center">
<img src="image/handbook/manual_install_1.png"> <img src="image/handbook/manual_install_1.png">
<p><em>Вкладка "Ручная установка" с указанием пути к дистрибутиву</em></p> <p><em>Вкладка "Ручная установка" с указанием пути к дистрибутиву</em></p>
</div> </div>
После нажатия кнопки **Установить** появится окно с лицензионным соглашением. После его принятия начнется процесс установки, который будет подробно логироваться в отдельном окне. <p>После нажатия кнопки <b>Установить</b> появится окно с лицензионным соглашением. После его принятия начнется процесс установки, который будет подробно логироваться в отдельном окне.</p>
<div align="center"> <div align="center">
<img src="image/handbook/license_agreement.png"> <img src="image/handbook/license_agreement.png">
@@ -271,91 +273,105 @@ WineHelper предоставляет доступ к основным инст
<div align="center"> <div align="center">
<img src="image/handbook/log.png"> <img src="image/handbook/log.png">
<p><em>Окно установки с логом</em></м</em></p> <p><em>Окно установки с логом</em></p>
</div> </div>
После установки приложения и нажатия кнопки **Закрыть** в окне установки приложения, ярлык приложения появится в списке установленных приложений во вкладке **Установленные** а также в меню приложений и на рабочем столе если это разрешено в рабочем окружении. <p>После установки приложения и нажатия кнопки <b>Закрыть</b> в окне установки приложения, ярлык приложения появится в списке установленных приложений во вкладке <b>Установленные</b> а также в меню приложений и на рабочем столе если это разрешено в рабочем окружении.</p>
### Вкладка «Установленные» <h3>Вкладка «Установленные»</h3>
На этой вкладке отображаются все приложения, которые были установлены с помощью WineHelper. <p>На этой вкладке отображаются все приложения, которые были установлены с помощью WineHelper.</p>
<div align="center"> <div align="center">
<img src="image/handbook/installed.png"> <img src="image/handbook/installed.png">
<p><em>Вкладка "Установленные"</em></p> <p><em>Вкладка "Установленные"</em></p>
</div> </div>
При выборе приложения в правой панели становятся доступны следующие действия: <p>При выборе приложения в правой панели становятся доступны следующие действия:</p>
* **Запустить/Остановить**: Запускает или останавливает/закрывает выбранное приложение. <ul>
* **Создать лог запуска программы**: Запускает приложение в режиме отладки. После закрытия приложения в вашем домашнем каталоге будет создан файл `winehelper.log`. <li><b>Запустить/Остановить</b>: Запускает или останавливает/закрывает выбранное приложение.</li>
* **Создать резервную копию префикса**: Создает полный бэкап префикса приложения (включая версию Wine) в формате `.whpack` на вашем рабочем столе если это разрешено в рабочем окружении. <li><b>Создать лог запуска программы</b>: Запускает приложение в режиме отладки. После закрытия приложения в вашем домашнем каталоге будет создан файл <code>winehelper.log</code>.</li>
* **Удалить префикс**: Полностью удаляет приложение вместе с его префиксом и всеми связанными ярлыками. <li><b>Создать резервную копию префикса</b>: Создает полный бэкап префикса приложения (включая версию Wine) в формате <code>.whpack</code> на вашем рабочем столе если это разрешено в рабочем окружении.</li>
<li><b>Удалить префикс</b>: Полностью удаляет приложение вместе с его префиксом и всеми связанными ярлыками.</li>
</ul>
Также на этой вкладке доступна кнопка **«Восстановить префикс из резервной копии»**, которая позволяет восстановить любое приложение из ранее созданного `.whpack` файла. <p>Также на этой вкладке доступна кнопка <b>«Восстановить префикс из резервной копии»</b>, которая позволяет восстановить любое приложение из ранее созданного <code>.whpack</code> файла.</p>
<div align="center"> <div align="center">
<img src="image/handbook/election_installed.png"> <img src="image/handbook/election_installed.png">
<p><em>Выбранное приложение во вкладке "Установленные"</em></p> <p><em>Выбранное приложение во вкладке "Установленные"</em></p>
</div> </div>
Расположения лога запуска программы а также резервной копии префикса можно просмотреть с помощью кнопки **«Открыть папку с логом/резервной копией префикса»** которая появляется автоматически после создания лога или резервной копии. <p>Расположения лога запуска программы а также резервной копии префикса можно просмотреть с помощью кнопки <b>«Открыть папку с логом/резервной копией префикса»</b> которая появляется автоматически после создания лога или резервной копии.</p>
<div align="center"> <div align="center">
<img src="image/handbook/folder_log_backup.png"> <img src="image/handbook/folder_log_backup.png">
<p><em>Кнопка "Открыть папку с логом/резервной копией префикса"</em></p> <p><em>Кнопка "Открыть папку с логом/резервной копией префикса"</em></p>
</div> </div>
### Вкладка «Менеджер префиксов» <h3>Вкладка «Менеджер префиксов»</h3>
Эта вкладка предоставляет мощные инструменты для управления префиксами Wine. <p>Эта вкладка предоставляет мощные инструменты для управления префиксами Wine.</p>
<div align="center"> <div align="center">
<img src="image/handbook/prefix_manager.png"> <img src="image/handbook/prefix_manager.png">
<p><em>Вкладка "Менеджер префиксов"</em></p> <p><em>Вкладка "Менеджер префиксов"</em></p>
</div> </div>
#### Создание нового префикса <h4>Создание нового префикса</h4>
Нажав кнопку **«Создать новый префикс»**, вы откроете диалог, где можно задать: <p>Нажав кнопку <b>«Создать новый префикс»</b>, вы откроете диалог, где можно задать:</p>
* **Имя префикса**. <ul>
* **Разрядность** (32-bit или 64-bit). <li><b>Имя префикса</b>.</li>
* **Наполнение** (чистый префикс или с рекомендуемыми библиотеками). <li><b>Разрядность</b> (32-bit или 64-bit).</li>
* **Версию Wine/Proton** из доступного списка. <li><b>Наполнение</b> (чистый префикс или с рекомендуемыми библиотеками).</li>
<li><b>Версию Wine/Proton</b> из доступного списка.</li>
</ul>
<div align="center"> <div align="center">
<img src="image/handbook/create_prefix.png"> <img src="image/handbook/create_prefix.png">
<p><em>Диалог создания нового префикса</em></p> <p><em>Диалог создания нового префикса</em></p>
</div> </div>
#### Управление существующим префиксом <h4>Управление существующим префиксом</h4>
Выбрав префикс из выпадающего списка, вы получаете доступ к панели управления, которая позволяет: <p>Выбрав префикс из выпадающего списка, вы получаете доступ к панели управления, которая позволяет:</p>
* **Запускать стандартные утилиты Wine**: <ul>
* `Редактор настроек (winecfg)` <li><b>Запускать стандартные утилиты Wine</b>:
* `Редактор реестра (regedit)` <ul>
* `Удаление программ (uninstaller)` <li><code>Редактор настроек (winecfg)</code></li>
* `Командная строка (cmd)` <li><code>Редактор реестра (regedit)</code></li>
* `Файловый менеджер (winefile)` <li><code>Удаление программ (uninstaller)</code></li>
* **Управлять компонентами**: <li><code>Командная строка (cmd)</code></li>
* **Менеджер компонентов (Winetricks)**: Удобный интерфейс для установки и переустановки библиотек, шрифтов и настроек. <li><code>Файловый менеджер (winefile)</code></li>
* **Управление Wine/Proton**: Смена версии Wine или Proton для выбранного префикса. </ul>
* **Управление DXVK/VKD3D**: Установка или удаление конкретных версий DXVK и VKD3D. </li>
* **Ассоциации файлов**: Настройка открытия определенных типов файлов (например, `.pdf`, `.docx`) нативными приложениями Linux. <li><b>Управлять компонентами</b>:
* **Включать/выключать ESync и FSync**. <ul>
* **Устанавливать приложения**: Установить любой `.exe` или `.msi` файл напрямую в выбранный префикс. <li><b>Менеджер компонентов (Winetricks)</b>: Удобный интерфейс для установки и переустановки библиотек, шрифтов и настроек.</li>
* **Создавать ярлыки**: Создать ярлык для любого исполняемого файла внутри префикса. <li><b>Управление Wine/Proton</b>: Смена версии Wine или Proton для выбранного префикса.</li>
* **Удалять префикс** или **создавать из него шаблон**. <li><b>Управление DXVK/VKD3D</b>: Установка или удаление конкретных версий DXVK и VKD3D.</li>
<li><b>Ассоциации файлов</b>: Настройка открытия определенных типов файлов (например, <code>.pdf</code>, <code>.docx</code>) нативными приложениями Linux.</li>
</ul>
</li>
<li><b>Включать/выключать ESync и FSync</b>.</li>
<li><b>Устанавливать приложения</b>: Установить любой <code>.exe</code> или <code>.msi</code> файл напрямую в выбранный префикс.</li>
<li><b>Создавать ярлыки</b>: Создать ярлык для любого исполняемого файла внутри префикса.</li>
<li><b>Удалять префикс</b> или <b>создавать из него шаблон</b>.</li>
</ul>
Справа отображается подробная информация о конфигурации выбранного префикса. <p>Справа отображается подробная информация о конфигурации выбранного префикса.</p>
### Вкладка «Справка» <h3>Вкладка «Справка»</h3>
Содержит полезную информацию о проекте: <p>Содержит полезную информацию о проекте:</p>
* **Руководство**: Ссылка на официальную документацию. <ul>
* **Авторы**: Список разработчиков и участников проекта. <li><b>Руководство</b>: Ссылка на официальную документацию.</li>
* **Лицензия**: Текст лицензии WineHelper и информация о сторонних компонентах. <li><b>Авторы</b>: Список разработчиков и участников проекта.</li>
* **История изменений**: Changelog пакета. <li><b>Лицензия</b>: Текст лицензии WineHelper и информация о сторонних компонентах.</li>
<li><b>История изменений</b>: Changelog пакета.</li>
</ul>
<div align="center"> <div align="center">
<img src="image/handbook/help.png"> <img src="image/handbook/help.png">
@@ -365,7 +381,9 @@ WineHelper предоставляет доступ к основным инст
</details> </details>
### Примечание <h3>Примечание</h3>
> [!WARNING] <blockquote>
> Проект находится на стадии WIP (work in progress) <p><b>[WARNING]</b><br>
Проект находится на стадии WIP (work in progress)</p>
</blockquote>

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# info_ru: Сервис обновления ПО: "R-Атлас", "R-Инфо" и "R-Тариф". # info_ru: Сервис обновления ПО
######################################################################## ########################################################################
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,12 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# info_ru: SCAD Office — это программный комплекс для расчёта строительных конструкций. # info_ru: SCAD Office — это программный комплекс для расчёта строительных конструкций, с дополнением Apache OpenOffice. Apache OpenOffice - пакет офисного программного обеспечения для обработки текстов, электронных таблиц, презентаций, графики, баз данных и многого другого.
######################################################################## ########################################################################
export PROG_URL="https://scadoffice.ru" export PROG_URL="https://scadoffice.ru"
export WH_WINE_USE="wine_x_tkg_10-0_amd64" export WH_WINE_USE="wine_x_tkg_10-0_amd64"
export WINEPREFIX="scadoffice" export WINEPREFIX="scadoffice"
export PROG_NAME="SCAD Office" export PROG_NAME="SCAD Office"
export PROG_ICON="scadoffice" export PROG_ICON="scadoffice"
export BASE_PFX="scadaoffice_pfx_x64_v05" export BASE_PFX="scadaoffice_pfx_x64_v04"
export WH_WINDOWS_VER="10" export WH_WINDOWS_VER="10"
export WINEARCH="win64" export WINEARCH="win64"
export INSTALL_DLL="dotnet20 dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6" export INSTALL_DLL="dotnet20 dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6"
@@ -32,6 +32,7 @@ if [[ -n $2 ]] ; then
fi fi
fi fi
if [[ $BASE_PFX == "none" ]] ; then
print_info "Установка дополнительных компонентов..." print_info "Установка дополнительных компонентов..."
ADDONS_PACK="${WH_TMP_DIR}/$(basename "$SCADOFFICE_ADDONS_URL")" ADDONS_PACK="${WH_TMP_DIR}/$(basename "$SCADOFFICE_ADDONS_URL")"
@@ -58,13 +59,12 @@ if try_download "$SCADOFFICE_ADDONS_URL" "${ADDONS_PACK}" ; then
try_remove_dir "$ADDONS_PATH" try_remove_dir "$ADDONS_PATH"
try_remove_file "$ADDONS_PACK" try_remove_file "$ADDONS_PACK"
fi fi
fi
if try_download "https://scadhelp.ru/files/10/download" "${AUTOINSTALL_EXE}" ; then if try_download "https://scadhelp.ru/files/10/download" "${AUTOINSTALL_EXE}" ; then
create_new_dir "$DRIVE_C/SDATA" create_new_dir "$DRIVE_C/SDATA"
create_new_dir "$DRIVE_C/SWORK" create_new_dir "$DRIVE_C/SWORK"
# временно запрещаем запуск hasplms.exe, hasplmv.exe для успешного завершения установки wine_run_install "${AUTOINSTALL_EXE}" /auto /hide
tmp_winedlloverride_update "hasplms.exe,hasplmv.exe=d"
wine_run_install "$AUTOINSTALL_EXE"
try_remove_file "$AUTOINSTALL_EXE" try_remove_file "$AUTOINSTALL_EXE"
# Определение всех программ, значков и исполняемых файлов # Определение всех программ, значков и исполняемых файлов

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# info_ru: «Справки БК» (Windows версия 2.5.5) от 31.01.2024 — специальное программное обеспечение, предназначенное для заполнения справок о доходах, расходах, об имуществе и обязательствах имущественного характера. # info_ru: «Справки БК» — специальное программное обеспечение, предназначенное для заполнения справок о доходах, расходах, об имуществе и обязательствах имущественного характера.
######################################################################## ########################################################################
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"

View File

@@ -1,34 +0,0 @@
#!/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

@@ -1,52 +0,0 @@
#!/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

@@ -1,49 +0,0 @@
#!/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

@@ -1,34 +0,0 @@
#!/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

@@ -1,34 +0,0 @@
#!/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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# info_ru: Ручная установка дополнений для T-FLEX CAD 17 или 18 # info_ru: Ручная установка дополнений для T-FLEX DOCS 17 или 18
######################################################################## ########################################################################
export PROG_NAME="T-FLEX CAD 17/18" export PROG_NAME="T-FLEX CAD 17/18"
export PROG_ICON="tflexcad" export PROG_ICON="tflexcad"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# info_ru: Ручная установка дополнений для T-FLEX DOCS 17 или 18 # info_ru: Ручная установка дополнений для T-FLEX CAD 17 или 18
######################################################################## ########################################################################
export PROG_NAME="T-FLEX DOCS 17/18" export PROG_NAME="T-FLEX CAD 17/18"
export PROG_ICON="tflexcad" export PROG_ICON="tflexcad"
export WH_WINE_USE="wine_wh_tflex_10-9_amd64" export WH_WINE_USE="wine_wh_tflex_10-9_amd64"
export BASE_PFX="tflex_pfx_x64_v03" export BASE_PFX="tflex_pfx_x64_v03"

View File

@@ -208,18 +208,12 @@ dfb44ce5e5af7dba1686932c63d6b05e5dd6919a21c78130a7d1d0271b93958e audiorecstatio
# create with wine_x_tkg_10-0_i586 (universal user: xuser) # create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks arial dotnet7 dotnetdesktop7 renderer=gdi # winetricks arial dotnet7 dotnetdesktop7 renderer=gdi
8c6312f2e4e846a98ca4a87fc90ee1917eb28d4caaddde040fb4d2dd05f8c0fe scadaoffice_pfx_x64_v05.tar.xz 4fa93434c5c15440014357323257ddcee7d28b94ad6a56bd6f5a08b33ae4c3cb scadaoffice_pfx_x64_v04.tar.xz
# create with wine_x_tkg_10-0_amd64 (universal user: xuser) # create with wine-8.8-staging-amd64
# winetricks dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6 dotnet20 # winetricks dotnet48 gdiplus vcrun6sp6 vcrun2005 vcrun2019 d3dx11_42 d3dx11_43 d3dx9 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 d3dcompiler_47 richtx32 riched30 riched20 msxml6 dotnet20
# + addons with ODBC, SSH, *.reg
# addons with ODBC, SSH, *.reg
0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb scadoffice_addons_v02.tar.xz 0f4ef434df07bc338ae308af44330590eaa1d9c94b64850514e55b960642d0eb scadoffice_addons_v02.tar.xz
ef7e8f1ba785d48e4ea287feed5b79bd630d423e59efadb43da9653adefef218 ais-lpu-client_pfx_x86_v01.tar.xz ef7e8f1ba785d48e4ea287feed5b79bd630d423e59efadb43da9653adefef218 ais-lpu-client_pfx_x86_v01.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser) # create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks vcrun2005 vcrun2008 dotnet20sp2 dotnet40 mfc42 7zip # winetricks vcrun2005 vcrun2008 dotnet20sp2 dotnet40 mfc42 7zip
f18864014fdb2fead0b45b5e70e95073072b89168df8cd6debba89081ac51a2a ksamu_pfx_x64_v01.tar.xz
# create with wine_x_tkg_10-0_i586 (universal user: xuser)
# winetricks msxml6 msxml4 msxml3 riched30 msls31 riched20 msftedit richtx32 fontsmooth=gray
# + manuall installed riched32

View File

@@ -1,17 +0,0 @@
#!/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

@@ -17,7 +17,6 @@ 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"
@@ -29,11 +28,9 @@ 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" \
@@ -104,6 +101,16 @@ 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"
@@ -156,7 +163,6 @@ check_variables WH_WINDOWS_VER "10"
# check_variables WH_USE_GSTREAMER "1" # check_variables WH_USE_GSTREAMER "1"
# check_variables WH_USE_D3D_EXTRAS "1" # check_variables WH_USE_D3D_EXTRAS "1"
check_variables WH_USE_SHADER_CACHE "1" check_variables WH_USE_SHADER_CACHE "1"
check_variables WH_USE_MESA_GL_OVERRIDE "0"
check_variables WH_USE_WINE_DXGI "0" check_variables WH_USE_WINE_DXGI "0"
check_variables WH_DLL_INSTALL "" check_variables WH_DLL_INSTALL ""
@@ -478,10 +484,6 @@ 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}"
@@ -550,6 +552,8 @@ create_desktop () {
if [[ -z "$name_desktop" ]] || [[ -z "$exe_file" ]] ; then if [[ -z "$name_desktop" ]] || [[ -z "$exe_file" ]] ; then
fatal "Использование: $0 desktop \"Имя ярлыка\" \"/путь/к/файлу.exe\" [иконка|auto] [имя_desktop_файла]" fatal "Использование: $0 desktop \"Имя ярлыка\" \"/путь/к/файлу.exe\" [иконка|auto] [имя_desktop_файла]"
elif [[ ! -f "$exe_file" ]] ; then elif [[ ! -f "$exe_file" ]] ; then
print_warning "Для создания ярлыка не найден исполняемый файл: $exe_file"
local BASENAME_EXE="$(basename "$exe_file")" local BASENAME_EXE="$(basename "$exe_file")"
print_info "Запускаем поиск $BASENAME_EXE" print_info "Запускаем поиск $BASENAME_EXE"
local FIND_PATH local FIND_PATH
@@ -560,11 +564,9 @@ create_desktop () {
exe_file="$(find "$FIND_PATH" -type f -not -type l \ exe_file="$(find "$FIND_PATH" -type f -not -type l \
-not -path "*/windows/*" -not -path "*/dosdevices/*" \ -not -path "*/windows/*" -not -path "*/dosdevices/*" \
-iname "$BASENAME_EXE")" -iname "$BASENAME_EXE")"
if [[ -z "$exe_file" ]] || [[ ! -f "$exe_file" ]] ; then if [[ -z "$exe_file" ]] || [[ ! -f "$exe_file" ]]
print_error "Для создания ярлыка не найден исполняемый файл: $BASENAME_EXE" then fatal "Для создания ярлыка не найден исполняемый файл: $BASENAME_EXE"
return 1 else print_ok "Исполняемый файл $BASENAME_EXE найден по пути: $(dirname "$exe_file")/"
else
print_ok "Исполняемый файл $BASENAME_EXE найден по пути: $(dirname "$exe_file")/"
fi fi
fi fi
@@ -1284,8 +1286,7 @@ 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
@@ -1346,25 +1347,23 @@ kill_wine () {
} }
init_database () { init_database () {
local whdb_file="0" WHDB_FILE="0"
if [[ -n "$WIN_FILE_EXEC" ]] \ if [[ -f "$WIN_FILE_EXEC" ]] ; then
&& [[ -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,89 +1388,40 @@ prepair_wine () {
[[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud" [[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud"
} }
wine_regfile () {
print_info "Запускаем команду: $WINELOADER $@"
"$WINELOADER" "$@" && print_ok "Выполнено." || fatal "Не выполнено: $WINELOADER $@"
wait_wineserver
if [[ "$WINEARCH" == "win64" ]] \
&& [[ -f "${WINELOADER}64" ]]
then
print_info "Запускаем команду: ${WINELOADER}64 $@"
"${WINELOADER}64" "$@" && print_ok "Выполнено." || fatal "Не выполнено: ${WINELOADER}64 $@"
wait_wineserver
fi
}
wine_run () { wine_run () {
local wh_add_args win_file_exec win_file_path win_file_name
if [[ $1 =~ (winecfg|regedit|winefile|wineconsole) ]] ; then
win_file_exec="$1"
win_file_name="$win_file_exec"
win_file_path="$DRIVE_C"
wh_add_args=""
elif [[ $1 =~ \.dll$ ]] ; then
wine_regfile regsvr32 /s "$@"
return 0
elif [[ -f "$1" ]] ; then
win_file_exec="$(readlink -f "$1")"
win_file_path="$(dirname "$win_file_exec")"
win_file_name="$(basename "$win_file_exec")"
case "${win_file_name,,}" in
*.exe) wh_add_args="$WINE_WIN_START" ;;
*.msi) wh_add_args="msiexec /i" ;;
*.bat|*.cmd) wh_add_args="" ;;
*.reg) wine_regfile regedit "$@" ; return 0 ;;
*) fatal "Не удалось запустить файл $1. Проверьте расширение файла." ;;
esac
if [[ $WINEARCH == "win32" ]] \ if [[ $WINEARCH == "win32" ]] \
&& file "$win_file_exec" | grep -q "x86-64" && file "$WIN_FILE_EXEC" | grep -q "x86-64"
then fatal "Нельзя запустить 64-битное приложение в 32-битном префиксе!" then fatal "Нельзя запустить 64-битное приложение в 32-битном префиксе!"
fi fi
WIN_FILE_PATH="$(dirname "$WIN_FILE_EXEC")"
[[ -d "$WIN_FILE_PATH" ]] && cd "$WIN_FILE_PATH"
if [[ -n $LOG_FILE ]] && [[ -f "$LOG_FILE" ]] ; then
echo "##### Основные переменные #####" | tee -a "$LOG_FILE"
env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" | tee -a "$LOG_FILE"
echo "##### Лог WINE #####" | tee -a "$LOG_FILE"
$MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$LOG_FILE"
else else
fatal "Команда введена не правильно или не найден исполняемый файл $1" $MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS
fi fi
shift
cd "$win_file_path"
if [[ $WINEDEBUG != "-all" ]] ; then
local log_dir log_file
log_dir="$HOME/winehelper_backup_log"
log_file="$log_dir/${PREFIX_NAME}_${win_file_name%.*}.log"
create_new_dir "$log_dir"
date > "$log_file"
print_warning "Включен режим логирования работы WINE."
print_warning "Лог будет сохранен по пути: $log_file"
echo "##### Основные переменные #####" | tee -a "$log_file"
env | grep -e "WH_" -e "WINE" -e "DXVK" -e "VKD3D" | tee -a "$log_file"
echo "##### Лог WINE #####" | tee -a "$log_file"
$MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS 2>&1 | tee -a "$log_file"
else
$MANGOHUD_RUN "$WINELOADER" $wh_add_args "$win_file_exec" "$@" $LAUNCH_PARAMETERS
fi
wait_wineserver wait_wineserver
cd "$DRIVE_C"
} }
wine_run_install () { wine_run_install () {
print_info "Запускаем установку: $1." print_info "Запускаем установку: $1."
case "$WH_INSTALL_MODE" in if [[ "$INSTALL_MODE" == "manual" ]]
"manual") print_warning "Рекомендуется не менять пути для установки приложения!" ;; then print_warning "Рекомендуется не менять пути для установки приложения!"
"test") print_warning "Установка приложения из списка экспериментальных скриптов." ;;
esac
if [[ ! -f "$1" ]]
then fatal "Нет файла для установки: $1"
else wine_run "$@"
fi 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 () { run_autoinstall () {
@@ -1489,20 +1439,24 @@ 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 [[ -f "$WH_TESTINSTALL_DIR/$INSTALL_SCRIPT_NAME" ]] ; then elif [[ -d "$WH_TESTINSTALL_DIR" ]] \
&& [[ -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 WH_INSTALL_MODE export INSTALL_SCRIPT INSTALL_MODE
if [[ $INSTALL_SCRIPT_NAME == "list" ]] || [[ -z "$INSTALL_SCRIPT_NAME" ]] ; then if [[ $INSTALL_SCRIPT_NAME == "list" ]] || [[ -z "$INSTALL_SCRIPT_NAME" ]] ; then
print_install_list () { list_install_scripts() {
parse_install_scripts() { local dir="$1"
local parse_dir="$1" local title="$2"
[[ ! -d "$parse_dir" ]] || [[ -z "$(ls -A "$parse_dir" 2>/dev/null)" ]] && return [[ ! -d "$dir" ]] || [[ -z "$(ls -A "$dir" 2>/dev/null)" ]] && return
print_info "$title"
awk ' awk '
FNR==1 { FNR==1 {
@@ -1519,19 +1473,12 @@ run_autoinstall () {
printf "\n%s - %s\n%s\n", filename, progname, info printf "\n%s - %s\n%s\n", filename, progname, info
} }
} }
' "$parse_dir"/* ' "$dir"/*
}
list_install_scripts "$WH_AUTOINSTALL_DIR" "Список программ с возможностью автоматической установки:"
echo echo
} list_install_scripts "$WH_MANUALINSTALL_DIR" "Список программ с возможностью установки из существующего дистрибутива:"
print_info "Список программ с возможностью автоматической установки:"
parse_install_scripts "$WH_AUTOINSTALL_DIR"
print_info "Список программ с возможностью установки из существующего дистрибутива:"
parse_install_scripts "$WH_MANUALINSTALL_DIR"
print_warning "Программы из списка экспериментальных скриптов:"
parse_install_scripts "$WH_TESTINSTALL_DIR"
}
print_install_list | less -R --use-color
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" ]]
@@ -2203,21 +2150,20 @@ select_component_version() {
} }
run_install_to_prefix() { run_install_to_prefix() {
if [[ -z "$1" ]] || [[ -z "$2" ]] || [[ ! -f "$2" ]] ; then export WINEPREFIX="$1"
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 "$@" wine_run_install "$WIN_FILE_EXEC"
} }
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
@@ -2225,27 +2171,21 @@ 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
@@ -2253,20 +2193,15 @@ 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
} }
@@ -2285,7 +2220,9 @@ 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."
} }
@@ -2325,8 +2262,7 @@ 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 [[ $WH_DEVEL != "1" ]] \ if [[ -d "$HOME/.local/share/$SCRIPT_NAME" ]] \
&& [[ -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
@@ -2372,14 +2308,12 @@ 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"
prepair_wine case "${WIN_FILE_NAME,,}" in
*.exe) prepair_wine ; wine_run $WINE_WIN_START "$WIN_FILE_EXEC" "$@" ;;
if [[ -n "$1" ]] && [[ -f "$1" ]] ; then *.msi) prepair_wine ; wine_run msiexec /i "$WIN_FILE_EXEC" "$@" ;;
WIN_OPEN_FILE="$("$WINELOADER" winepath -w "$1")" *.bat|*.cmd) prepair_wine ; wine_run start "$WIN_FILE_EXEC" "$@" ;;
shift *) fatal "Тип файла не поддерживается." ;;
fi esac
wine_run "$WIN_FILE_EXEC" "$@" "$WIN_OPEN_FILE"
else else
print_error "Команды $arg1 не существует." print_error "Команды $arg1 не существует."
wh_info wh_info

View File

@@ -13,8 +13,8 @@ from functools import partial
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar, from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar,
QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox, QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox,
QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu) QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu)
from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve, pyqtSignal from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor, QTextCharFormat from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor
from PyQt5.QtNetwork import QLocalServer, QLocalSocket from PyQt5.QtNetwork import QLocalServer, QLocalSocket
@@ -428,8 +428,6 @@ class WinetricksManagerDialog(QDialog):
"Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»." "Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»."
) )
installation_complete = pyqtSignal()
def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None): def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None):
super().__init__(parent) super().__init__(parent)
self.prefix_path = prefix_path self.prefix_path = prefix_path
@@ -619,33 +617,12 @@ class WinetricksManagerDialog(QDialog):
self._log(f"--- Предупреждение: не удалось прочитать {log_path}: {e} ---") self._log(f"--- Предупреждение: не удалось прочитать {log_path}: {e} ---")
return installed_verbs return installed_verbs
def _parse_winetricks_list_output(self, output, installed_verbs, list_widget, category): def _parse_winetricks_list_output(self, output, installed_verbs, list_widget):
"""Парсит вывод 'winetricks list' и заполняет QListWidget.""" """Парсит вывод 'winetricks list' и заполняет QListWidget."""
# Regex, который обрабатывает строки как с префиксом статуса '[ ]', так и без него. # Regex, который обрабатывает строки как с префиксом статуса '[ ]', так и без него.
# 1. `(?:\[(.)]\s+)?` - опциональная группа для статуса (напр. '[x]'). # 1. `(?:\[(.)]\s+)?` - опциональная группа для статуса (напр. '[x]').
# 2. `([^\s]+)` - имя компонента (без пробелов). # 2. `([^\s]+)` - имя компонента (без пробелов).
# 3. `(.*)` - оставшаяся часть строки (описание). # 3. `(.*)` - оставшаяся часть строки (описание).
# Определяем шаблоны для фильтрации на основе категории
dlls_blacklist_pattern = None
fonts_blacklist_pattern = None
settings_blacklist_pattern = None
if category == 'dlls':
# Исключаем d3d*, directx9, dont_use, dxvk*, vkd3d*, galliumnine, faudio*, Foundation
dlls_blacklist_pattern = re.compile(
r'^(d3d|directx9|dont_use|dxvk|vkd3d|galliumnine|faudio|foundation)', re.IGNORECASE
)
elif category == 'fonts':
fonts_blacklist_pattern = re.compile(
r'^(dont_use)', re.IGNORECASE
)
elif category == 'settings':
# Исключаем vista*, alldlls, autostart_*, bad*, good*, win*, videomemory*, vd=*, isolate_home
settings_blacklist_pattern = re.compile(
r'^(vista|alldlls|autostart_|bad|good|win|videomemory|vd=|isolate_home)', re.IGNORECASE
)
line_re = re.compile(r"^\s*(?:\[(.)]\s+)?([^\s]+)\s*(.*)") line_re = re.compile(r"^\s*(?:\[(.)]\s+)?([^\s]+)\s*(.*)")
found_items = False found_items = False
@@ -666,14 +643,6 @@ class WinetricksManagerDialog(QDialog):
if '/' in name or '\\' in name or name.lower() in ('executing', 'using', 'warning:') or name.endswith(':'): if '/' in name or '\\' in name or name.lower() in ('executing', 'using', 'warning:') or name.endswith(':'):
continue continue
# Применяем фильтры для черных списков
if dlls_blacklist_pattern and dlls_blacklist_pattern.search(name):
continue
if fonts_blacklist_pattern and fonts_blacklist_pattern.search(name):
continue
if settings_blacklist_pattern and settings_blacklist_pattern.search(name):
continue
is_checked = name in installed_verbs is_checked = name in installed_verbs
item_text = f"{name.ljust(27)}{description.strip()}" item_text = f"{name.ljust(27)}{description.strip()}"
item = QListWidgetItem(item_text) item = QListWidgetItem(item_text)
@@ -712,7 +681,7 @@ class WinetricksManagerDialog(QDialog):
self._log("--------------------------------------------------", "red") self._log("--------------------------------------------------", "red")
else: else:
installed_verbs = self._parse_winetricks_log() installed_verbs = self._parse_winetricks_log()
found_items = self._parse_winetricks_list_output(output, installed_verbs, list_widget, category) found_items = self._parse_winetricks_list_output(output, installed_verbs, list_widget)
if from_cache is None: # Только если мы не читали из кэша if from_cache is None: # Только если мы не читали из кэша
# Сохраняем успешный результат в кэш # Сохраняем успешный результат в кэш
@@ -870,9 +839,6 @@ 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
@@ -890,7 +856,6 @@ class WinetricksManagerDialog(QDialog):
# Перезагружаем данные, чтобы обновить состояние # Перезагружаем данные, чтобы обновить состояние
self.initial_states.clear() self.initial_states.clear()
self.load_all_categories() self.load_all_categories()
self.installation_complete.emit()
self.installation_finished = True self.installation_finished = True
def closeEvent(self, event): def closeEvent(self, event):
@@ -1625,34 +1590,10 @@ 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
@@ -1695,8 +1636,8 @@ class WineHelperGUI(QMainWindow):
self.main_layout.addLayout(content_layout) self.main_layout.addLayout(content_layout)
# Фиксируем минимальные размеры # Фиксируем минимальные размеры
self.stacked_widget.setMinimumWidth(535) self.stacked_widget.setMinimumWidth(520)
self.info_panel.setMinimumWidth(395) self.info_panel.setMinimumWidth(415)
# Вкладки # Вкладки
self.create_auto_install_tab() self.create_auto_install_tab()
@@ -1791,11 +1732,8 @@ class WineHelperGUI(QMainWindow):
if tab_name == "Автоматическая установка": if tab_name == "Автоматическая установка":
title = "Автоматическая установка" title = "Автоматическая установка"
html_content = ("<h3>Автоматическая установка</h3>" html_content = ("<h3>Автоматическая установка</h3>"
"<p>Скрипты из этого списка скачают, установят и настроят приложение за вас. Просто выберите программу и нажмите «Установить».</p>" "<p>Скрипты из этого списка скачают, установят и настроят приложение за вас.</p>"
"<p>Для доступа к экспериментальным скриптам установки отметьте опцию <b>«Показать тестовые версии»</b> внизу списка.</p>" "<p>Просто выберите программу и нажмите «Установить».</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 = "Ручная установка"
@@ -1919,7 +1857,6 @@ 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)
@@ -2083,14 +2020,14 @@ class WineHelperGUI(QMainWindow):
return btn return btn
def _populate_install_grid(self, grid_layout, scripts_list, script_folder, button_list, start_index=None): def _populate_install_grid(self, grid_layout, scripts_list, script_folder, button_list):
""" """
Заполняет 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' или 'testinstall'). :param script_folder: Имя папки со скриптами ('autoinstall' или 'manualinstall').
:param button_list: Список для хранения созданных кнопок. :param button_list: Список для хранения созданных кнопок.
""" """
button_index = 0 button_index = 0
@@ -2104,13 +2041,7 @@ 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()
@@ -2120,12 +2051,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(len(button_list), 2) row, column = divmod(button_index, 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, add_stretch=True): def _create_searchable_grid_tab(self, placeholder_text, filter_slot):
""" """
Создает стандартную вкладку с полем поиска и сеточным макетом с прокруткой. Создает стандартную вкладку с полем поиска и сеточным макетом с прокруткой.
Возвращает кортеж (главный виджет вкладки, сеточный макет, поле поиска, область прокрутки). Возвращает кортеж (главный виджет вкладки, сеточный макет, поле поиска, область прокрутки).
@@ -2159,12 +2090,11 @@ class WineHelperGUI(QMainWindow):
grid_layout.setColumnStretch(1, 1) grid_layout.setColumnStretch(1, 1)
v_scroll_layout.addLayout(grid_layout) v_scroll_layout.addLayout(grid_layout)
if add_stretch:
v_scroll_layout.addStretch(1) v_scroll_layout.addStretch(1)
return tab_widget, grid_layout, search_edit, scroll_area return tab_widget, grid_layout, search_edit, scroll_area
def _create_and_populate_install_tab(self, tab_title, script_folders, search_placeholder, filter_slot): def _create_and_populate_install_tab(self, tab_title, script_folder, search_placeholder, filter_slot):
""" """
Создает и заполняет вкладку для установки (автоматической или ручной). Создает и заполняет вкладку для установки (автоматической или ручной).
Возвращает кортеж со скриптами, кнопками и виджетами. Возвращает кортеж со скриптами, кнопками и виджетами.
@@ -2174,17 +2104,16 @@ class WineHelperGUI(QMainWindow):
) )
scripts = [] scripts = []
buttons_list = [] script_path = os.path.join(Var.DATA_PATH, script_folder)
for folder in script_folders:
script_path = os.path.join(Var.DATA_PATH, folder)
if os.path.isdir(script_path): if os.path.isdir(script_path):
try: try:
folder_scripts = sorted(os.listdir(script_path)) scripts = sorted(os.listdir(script_path))
scripts.extend(folder_scripts)
self._populate_install_grid(grid_layout, folder_scripts, folder, buttons_list)
except OSError as e: except OSError as e:
print(f"Не удалось прочитать директорию {script_path}: {e}") print(f"Не удалось прочитать директорию {script_path}: {e}")
buttons_list = []
self._populate_install_grid(grid_layout, scripts, script_folder, buttons_list)
self.add_tab(tab_widget, tab_title) self.add_tab(tab_widget, tab_title)
return scripts, buttons_list, grid_layout, search_edit, scroll_area return scripts, buttons_list, grid_layout, search_edit, scroll_area
@@ -2195,89 +2124,30 @@ 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, add_stretch=True "Поиск установленной программы...", self.filter_installed_buttons
) )
self.add_tab(installed_tab, "Установленные") self.add_tab(installed_tab, "Установленные")
@@ -2309,13 +2179,6 @@ class WineHelperGUI(QMainWindow):
self.created_prefix_selector.currentIndexChanged.connect(self.on_created_prefix_selected) self.created_prefix_selector.currentIndexChanged.connect(self.on_created_prefix_selected)
selector_layout.addWidget(self.created_prefix_selector, 1) selector_layout.addWidget(self.created_prefix_selector, 1)
self.open_prefix_folder_button = QPushButton()
self.open_prefix_folder_button.setIcon(QIcon.fromTheme("folder-open"))
self.open_prefix_folder_button.setToolTip("Открыть папку префикса в файловом менеджере")
self.open_prefix_folder_button.setEnabled(False)
self.open_prefix_folder_button.clicked.connect(self.open_selected_prefix_folder)
selector_layout.addWidget(self.open_prefix_folder_button)
self.create_base_pfx_button = QPushButton() self.create_base_pfx_button = QPushButton()
self.create_base_pfx_button.setIcon(QIcon.fromTheme("document-export")) self.create_base_pfx_button.setIcon(QIcon.fromTheme("document-export"))
self.create_base_pfx_button.setToolTip("Создать шаблон из выбранного префикса (для опытных пользователей)") self.create_base_pfx_button.setToolTip("Создать шаблон из выбранного префикса (для опытных пользователей)")
@@ -2519,7 +2382,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(True) self.remove_all_button.setEnabled(bool(prefix_names))
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)
@@ -2535,9 +2398,8 @@ 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(True) self.remove_all_button.setEnabled(False)
self.create_base_pfx_button.setEnabled(False) self.create_base_pfx_button.setEnabled(False)
self.open_prefix_folder_button.setEnabled(False)
else: else:
# Прокручиваем к выбранному элементу, чтобы он был виден в списке # Прокручиваем к выбранному элементу, чтобы он был виден в списке
self.created_prefix_selector.view().scrollTo( self.created_prefix_selector.view().scrollTo(
@@ -2549,7 +2411,6 @@ class WineHelperGUI(QMainWindow):
self.delete_prefix_button.setEnabled(True) self.delete_prefix_button.setEnabled(True)
self.remove_all_button.setEnabled(True) self.remove_all_button.setEnabled(True)
self.create_base_pfx_button.setEnabled(True) self.create_base_pfx_button.setEnabled(True)
self.open_prefix_folder_button.setEnabled(True)
def delete_selected_prefix(self): def delete_selected_prefix(self):
"""Удаляет префикс, выбранный в выпадающем списке на вкладке 'Менеджер префиксов'.""" """Удаляет префикс, выбранный в выпадающем списке на вкладке 'Менеджер префиксов'."""
@@ -2658,21 +2519,6 @@ class WineHelperGUI(QMainWindow):
self._run_simple_command("create-base-pfx", [prefix_name]) self._run_simple_command("create-base-pfx", [prefix_name])
self.command_dialog.exec_() self.command_dialog.exec_()
def open_selected_prefix_folder(self):
"""Открывает папку выбранного префикса в системном файловом менеджере."""
prefix_name = self.current_managed_prefix_name
if not prefix_name:
return
prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name)
if os.path.isdir(prefix_path):
try:
subprocess.Popen(['xdg-open', prefix_path])
except Exception as e:
QMessageBox.warning(self, "Ошибка", f"Не удалось открыть директорию:\n{prefix_path}\n\nОшибка: {e}")
else:
QMessageBox.warning(self, "Ошибка", f"Директория префикса не найдена:\n{prefix_path}")
def _setup_prefix_management_panel(self, prefix_name): def _setup_prefix_management_panel(self, prefix_name):
"""Настраивает панель управления префиксом на основе текущего состояния.""" """Настраивает панель управления префиксом на основе текущего состояния."""
is_prefix_selected = bool(prefix_name) is_prefix_selected = bool(prefix_name)
@@ -2731,39 +2577,19 @@ class WineHelperGUI(QMainWindow):
self.esync_button.blockSignals(False) self.esync_button.blockSignals(False)
self.fsync_button.blockSignals(False) self.fsync_button.blockSignals(False)
# --- Чтение и отображение установленных компонентов Winetricks ---
winetricks_log_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name, "winetricks.log")
installed_verbs = []
if os.path.exists(winetricks_log_path):
try:
with open(winetricks_log_path, 'r', encoding='utf-8') as f:
for line in f:
verb = line.split('#', 1)[0].strip()
if verb:
installed_verbs.append(verb)
except IOError as e:
print(f"Ошибка чтения winetricks.log: {e}")
# Фильтруем служебные компоненты, чтобы не засорять вывод
verbs_to_ignore = {
'isolate_home', 'winxp', 'win7', 'win10', 'win11',
'vista', 'win2k', 'win2k3', 'win2k8', 'win8', 'win81',
'workaround', 'internal'
}
display_verbs = sorted([v for v in installed_verbs if v not in verbs_to_ignore])
# Карта для красивого отображения известных переменных # Карта для красивого отображения известных переменных
display_map = { display_map = {
"WINEPREFIX": ("Путь", lambda v: v), "WINEPREFIX": ("Путь", lambda v: v),
"WINEARCH": ("Архитектура", lambda v: "64-bit" if v == "win64" else "32-bit"), "WINEARCH": ("Архитектура", lambda v: "64-bit" if v == "win64" else "32-bit"),
"WH_WINE_USE": ("Версия Wine", lambda v: "Системная" if v == "system" else v), "WH_WINE_USE": ("Версия Wine", lambda v: "Системная" if v == "system" else v),
"BASE_PFX": ("Тип", lambda v: 'Чистый' if v == "none" else 'С рекомендуемыми библиотеками'),
"DXVK_VER": ("Версия DXVK", lambda v: v if v else "Не установлено"), "DXVK_VER": ("Версия DXVK", lambda v: v if v else "Не установлено"),
"VKD3D_VER": ("Версия VKD3D", lambda v: v if v else "Не установлено"), "VKD3D_VER": ("Версия VKD3D", lambda v: v if v else "Не установлено"),
"WINEESYNC": ("ESync", lambda v: "Включен" if v == "1" else "Выключен"), "WINEESYNC": ("ESync", lambda v: "Включен" if v == "1" else "Выключен"),
"WINEFSYNC": ("FSync", lambda v: "Включен" if v == "1" else "Выключен"), "WINEFSYNC": ("FSync", lambda v: "Включен" if v == "1" else "Выключен"),
"WH_XDG_OPEN": ("Ассоциации файлов", lambda v: v if v and v != "0" else "Не заданы"), "WH_XDG_OPEN": ("Ассоциации файлов", lambda v: v if v and v != "0" else "Не заданы"),
} }
display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "DXVK_VER", "VKD3D_VER", "WINEESYNC", "WINEFSYNC", "WH_XDG_OPEN"] display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "BASE_PFX", "DXVK_VER", "VKD3D_VER", "WINEESYNC", "WINEFSYNC", "WH_XDG_OPEN"]
html_content = f'<p style="line-height: 1.3; font-size: 9pt;">' html_content = f'<p style="line-height: 1.3; font-size: 9pt;">'
html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>" html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>"
@@ -2785,15 +2611,6 @@ class WineHelperGUI(QMainWindow):
html_content += "<br><b>Дополнительные параметры:</b><br>" html_content += "<br><b>Дополнительные параметры:</b><br>"
html_content += other_vars_html html_content += other_vars_html
html_content += "<br><b>Компоненты (Winetricks):</b> "
if display_verbs:
# Используем span вместо div, чтобы избежать лишних отступов
html_content += '<span style="max-height: 120px; overflow-y: auto;">'
html_content += ", ".join(html.escape(v) for v in display_verbs)
html_content += '</span>'
else:
html_content += "Не установлены"
html_content += "</p>" html_content += "</p>"
self.prefix_info_display.setHtml(html_content) self.prefix_info_display.setHtml(html_content)
@@ -3350,6 +3167,9 @@ class WineHelperGUI(QMainWindow):
"""Открывает диалог создания нового префикса.""" """Открывает диалог создания нового префикса."""
dialog = CreatePrefixDialog(self) dialog = CreatePrefixDialog(self)
if dialog.exec_() == QDialog.Accepted: if dialog.exec_() == QDialog.Accepted:
if not self._show_license_agreement_dialog():
return
self.start_prefix_creation( self.start_prefix_creation(
prefix_name=dialog.prefix_name, prefix_name=dialog.prefix_name,
wine_arch=dialog.wine_arch, wine_arch=dialog.wine_arch,
@@ -3566,7 +3386,11 @@ 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)
@@ -3754,8 +3578,7 @@ class WineHelperGUI(QMainWindow):
msg_box.setText( msg_box.setText(
"Приложение будет запущено в режиме отладки.\n\n" "Приложение будет запущено в режиме отладки.\n\n"
"После закрытия приложения лог будет сохранен в папке 'winehelper_backup_log' " "После закрытия приложения лог будет сохранен в папке 'winehelper_backup_log' "
"в вашем домашнем каталоге под именем (пример: prefix_program.log).\n\n" "в вашем домашнем каталоге под именем 'winehelper.log'."
"Продолжить?"
) )
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)
@@ -3797,7 +3620,6 @@ class WineHelperGUI(QMainWindow):
wine_executable = self._get_wine_executable_for_prefix(prefix_name) wine_executable = self._get_wine_executable_for_prefix(prefix_name)
dialog = WinetricksManagerDialog(prefix_path, winetricks_path, self, wine_executable=wine_executable) dialog = WinetricksManagerDialog(prefix_path, winetricks_path, self, wine_executable=wine_executable)
dialog.installation_complete.connect(lambda: self.update_prefix_info_display(prefix_name))
dialog.exec_() dialog.exec_()
def _get_wine_executable_for_prefix(self, prefix_name): def _get_wine_executable_for_prefix(self, prefix_name):
@@ -3960,27 +3782,10 @@ 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._set_run_button_state(False) self.run_button.setText("Запустить")
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:
@@ -4047,7 +3852,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._set_run_button_state(True) self.run_button.setText("Остановить")
print(f"Запущено: {program} {' '.join(arguments)}") print(f"Запущено: {program} {' '.join(arguments)}")
except Exception as e: except Exception as e:
QMessageBox.critical(self, "Ошибка запуска", QMessageBox.critical(self, "Ошибка запуска",
@@ -4325,8 +4130,6 @@ 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)
@@ -4492,9 +4295,7 @@ 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 os.path.exists(os.path.join(Var.DATA_PATH, "autoinstall", self.current_script)) "autoinstall" if self.current_script in self.autoinstall_scripts else "manualinstall",
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):
@@ -4811,7 +4612,6 @@ class WineHelperGUI(QMainWindow):
self.command_process.deleteLater() self.command_process.deleteLater()
self.command_process = None self.command_process = None
self.command_close_button.setEnabled(True) self.command_close_button.setEnabled(True)
self.command_log_output.ensureCursorVisible()
def _handle_launcher_creation_finished(self, exit_code, exit_status): def _handle_launcher_creation_finished(self, exit_code, exit_status):
"""Обрабатывает завершение создания ярлыка.""" """Обрабатывает завершение создания ярлыка."""