Je développe un démon sans interface utilisateur autre qu’une simple icône dans la barre des tâches Windows.
Je voudrais ne pas avoir de dépendances sur les autres paquets, alors j’essaie d’utiliser le paquetage syscall
et d’implémenter moi-même les appels nécessaires.
Shell_NotifyIcon
dans shell32.dll
. Shell_NotifyIconW
(déclinaison Unicode), mais l’implémentation est partielle. Construit avec la documentation xilp / systray .
type HANDLE uintptr type HICON HANDLE type HWND HANDLE type GUID struct { Data1 uint32 Data2 uint16 Data3 uint16 Data4 [8]byte } type NOTIFYICONDATA struct { CbSize uint32 HWnd HWND UID uint32 UFlags uint32 UCallbackMessage uint32 HIcon HICON SzTip [128]uint16 DwState uint32 DwStateMask uint32 SzInfo [256]uint16 UVersion uint32 SzInfoTitle [64]uint16 DwInfoFlags uint32 GuidItem GUID }
const ( NIM_ADD = 0x00000000 NIM_MODIFY = 0x00000001 NIM_DELETE = 0x00000002 NIM_SETVERSION = 0x00000004 NIF_MESSAGE = 0x00000001 NIF_ICON = 0x00000002 NIF_TIP = 0x00000004 NIF_STATE = 0x00000008 NIF_HIDDEN = 0x00000001 )
package main import ( "log" "syscall" "unsafe" ) func main() { shell32 := syscall.MustLoadDLL("shell32.dll") Shell_NotifyIcon := shell32.MustFindProc("Shell_NotifyIconW") iconData := NOTIFYICONDATA{ HWnd: 0, UFlags: NIF_MESSAGE | NIF_STATE, DwState: NIF_HIDDEN, DwStateMask: NIS_HIDDEN, } iconData.CbSize = uint32(unsafe.Sizeof(iconData)) ret, _, _ := Shell_NotifyIcon.Call( NIM_ADD, uintptr(unsafe.Pointer(&iconData)), ) if ret == 0 { log.Println("Failed") return } // Do anything, like open a HTTP server to keep the program running http.ListenAndServe(":8080", nil) }
HWnd
, mais sans elle, l’exécutable se bloque. UFlags
, DwState
et DwStateMask
ont des valeurs que j’ai trouvées dans différents projets. Je sais que c’est possible; le Golang WIKI donne une implémentation pour appeler une boîte de message.