Скрытие окна CMD при выполнении команды в GoLang goWSL

Вопрос или проблема

Я работаю над приложением на 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
}

Объяснение:

  1. SysProcAttr: Убедитесь, что вы используете правильный пакет для импорта syscall. Структура SysProcAttr позволяет установить параметры, относящиеся к процессу, включая возможность скрыть окно.

  2. Скрытые окна в Windows: Параметр HideWindow: true в SysProcAttr будет работать только в том случае, если компилируемое приложение собрано для Windows и использует соответствующую версию Go, поскольку данная опция специфична для WinAPI.

  3. Ошибка компиляции: Если у вас проблема с компиляцией при установке cmd.SysProcAttr, возможно, вы используете неподходящие импорты, либо ваша версия Go не поддерживает данную функциональность. Убедитесь, что вы используете актуальную версию Go и импортируете syscall.

Замечания:

  • Проверьте, установлен ли у вас доступ к WSL и правильно ли настроен дистрибутив.
  • При работе на Windows вы можете также столкнуться с ограничениями полей ошибок, поэтому обязательно учитывайте их при разработке.

Эта реализация позволит вам запускать WSL команды без открывания окна CMD, улучшая пользовательский интерфейс вашего приложения.

Оцените материал
Добавить комментарий

Капча загружается...