Вопрос или проблема
Я работаю над приложением на GoLang для Windows, которое использует потрясающие пакеты Fyne и GoWSL (https://github.com/ubuntu/GoWSL) для выполнения команд WSL из моего интерфейса.
У меня есть функция, которая вызывает WSL. Она работает хорошо, однако каждый раз, когда я выполняю команду, открывается отвратительное окно CMD. В идеале, я бы хотел выполнять эти команды WSL в фоновом режиме, не показывая их пользователю.
Вот моя функция:
func runWSLCommand(command string) error {
// Получаем стандартное дистрибутив
distro, ok, distroErr := wsl.DefaultDistro(context.Background())
if distroErr != nil {
panic(distroErr)
}
if !ok {
panic(distroErr)
}
// Получаем конфигурацию и выводим её
pp.Println("Выводим информацию о дистрибутиве:")
pp.Printf("%v\n", distro)
// Показываем CombinedOutput
pp.Println("Запускаем команду с перенаправленным выводом: " + command)
// Получаем команду
cmd := distro.Command(context.Background(), command)
// Убедимся, что окно скрыто
//cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
// Выполняем команду wsl и получаем вывод
out, err := cmd.CombinedOutput()
if err != nil {
errorPrinter.Println(fmt.Sprintf("Неожиданная ошибка: %v\nСообщение об ошибке: %s", err, out))
return errors.New("Ошибка: не удалось выполнить команду: " + fmt.Sprintf("Неожиданная ошибка: %v\nСообщение об ошибке: %s", err, out))
} else {
pp.Println("WSL: " + string(out))
return nil
}
}
Я пробовал гуглить и скрывать окно следующим способом. Однако код не компилируется с раскомментированным флагом скрытого окна:
// Получаем команду
cmd := distro.Command(context.Background(), command)
// Убедимся, что окно скрыто
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} // Это не компилируется
// Выполняем команду wsl и получаем вывод
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "Неожиданная ошибка: %v\nСообщение об ошибке: %s", err, out)
return errors.New("Ошибка: не удалось выполнить команду: " + fmt.Sprintf("Неожиданная ошибка: %v\nСообщение об ошибке: %s", err, out))
} else {
pp.Println("WSL: " + string(out))
return nil
}
Как я могу вызвать библиотеку GoWSL, не открывая новое окно CMD для каждой команды? Спасибо.
Ответ или решение
Чтобы предотвратить открытие окна командной строки (CMD) при выполнении WSL команд в вашей GoLang UI приложении, вы можете использовать syscall.StartProcess
с некоторыми параметрами, чтобы скрыть окно. Однако есть некоторые нюансы в том, как вы используете пакет GoWSL.
Вот обновленная версия вашей функции runWSLCommand
, которая должна работать без открытия окна CMD:
package main
import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"syscall"
"github.com/ubuntu/GoWSL"
"github.com/your-pp-package" // Замените на ваш пакет для pprint
)
func runWSLCommand(command string) error {
// Получаем стандартное дистрибутив
distro, ok, distroErr := wsl.DefaultDistro(context.Background())
if distroErr != nil {
panic(distroErr)
}
if !ok {
panic("Не найдено дистрибутива")
}
// Получаем команду
pp.Println("Запуск команды: " + command)
cmd := distro.Command(context.Background(), command)
// Скрытие окна
cmd.SysProcAttr = &syscall.SysProcAttr{
// hide window flag для Windows
HideWindow: true,
}
// Выполняем команду и получаем вывод
out, err := cmd.CombinedOutput()
if err != nil {
errorMsg := fmt.Sprintf("Неожиданная ошибка: %v\nСообщение об ошибке: %s", err, out)
fmt.Fprintf(os.Stderr, errorMsg)
return errors.New("Ошибка: Не удалось запустить команду: " + errorMsg)
}
// Печатаем результат
pp.Println("WSL: " + string(out))
return nil
}
Объяснение:
-
SysProcAttr: Убедитесь, что вы используете правильный пакет для импорта
syscall
. СтруктураSysProcAttr
позволяет установить параметры, относящиеся к процессу, включая возможность скрыть окно. -
Скрытые окна в Windows: Параметр
HideWindow: true
вSysProcAttr
будет работать только в том случае, если компилируемое приложение собрано для Windows и использует соответствующую версию Go, поскольку данная опция специфична для WinAPI. -
Ошибка компиляции: Если у вас проблема с компиляцией при установке
cmd.SysProcAttr
, возможно, вы используете неподходящие импорты, либо ваша версия Go не поддерживает данную функциональность. Убедитесь, что вы используете актуальную версию Go и импортируетеsyscall
.
Замечания:
- Проверьте, установлен ли у вас доступ к WSL и правильно ли настроен дистрибутив.
- При работе на Windows вы можете также столкнуться с ограничениями полей ошибок, поэтому обязательно учитывайте их при разработке.
Эта реализация позволит вам запускать WSL команды без открывания окна CMD, улучшая пользовательский интерфейс вашего приложения.