У меня есть программа Go, которая хочет установить Traicicon.В случае, если процесс выполняется без заголовка, то есть он не сможет создать графический интерфейс пользователя, программа Go по-прежнему имеет смысл и должна запускаться, но, очевидно, она не будет устанавливать traicicon.
Что такоепуть в Go, как определить, является ли текущий процесс Go безголовым?
В настоящее время я использую следующий код:
func isHeadless() bool {
_, display := os.LookupEnv("DISPLAY")
return !(runtime.GOOS == "windows" || display)
}
Этот код прекрасно работает на «нормальной» Windows, Linuxили Mac OS X, и я уверен, что он также отлично работает на FreeBSD, NetBSD, Dragonfly и многих других.
Тем не менее, у этого кода, очевидно, много проблем:
- Предполагается, что Windows никогда не бывает без головы (неправильно, что, если процесс был запущен без входа пользователя в систему, а также есть Windows 10 IoT Core, которую можно настроить на работу без головы https://docs.microsoft.com/en-us/windows/iot-core/learn-about-hardware/headlessmode)
- Это неподдержка Android (для которой также существует безголовая версия IoT).
- Предполагается, что все, кроме Windows, имеет X-сервер и, следовательно, переменную среды DISPLAY (например, неправильно).Android)
Итак, как правильно в Go определить, является ли текущий процесс безголовым / работает в безголовой среде?
Я не ищу обходных путей, напримердобавив в мою программу ключ командной строки --headless
.Потому что у меня уже есть , что в любом случае для пользователей, у которых есть головы, но которые хотят, чтобы программа работала так, как если бы она была безголовой.
В некоторых других средах программирования такие возможности существуют.Например, Java имеет java.awt.GraphicsEnvironment.isHeadless()
, и я ищу аналогичную возможность в Go.
Некоторые люди предложили просто попробовать создать пользовательский интерфейс и отловить ошибку.Это не работает, по крайней мере, не с библиотекой, которую я использую.Я использую github.com/getlantern/systray
.Когда systray.Run()
не может создать пользовательский интерфейс, процесс умирает.Мой код для настройки системного трея выглядит следующим образом:
func setupSystray() { // called from main()
go func() {
systray.Run(onReady, nil)
}()
}
func onReady() {
systray.SetTitle("foo")
// ...
}
Когда я запускаю этот код в Linux с DISPLAY
unset, вывод будет следующим:
$ ./myapp-linux-amd64
Unable to init server: Could not connect: Connection refused
(myapp-linux-amd64:5783): Gtk-WARNING **: 19:42:37.914: cannot open display:
$ echo $?
1
Это можетможно утверждать, что это ошибка в библиотеке (и я создал билет для библиотеки https://github.com/getlantern/systray/issues/71),, но, тем не менее, некоторые другие API и среды предоставляют функцию isHeadless()
, и я ищу эквивалент в Golang.