ShadowEditor/server/cmd/win/install.go
2020-06-23 22:30:11 +08:00

95 lines
2.1 KiB
Go

// Copyright 2017-2020 The ShadowEditor Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//
// For more information, please visit: https://github.com/tengge1/ShadowEditor
// You can also visit: https://gitee.com/tengge1/ShadowEditor
// Reference URL: https://github.com/andrewkroh/sys/blob/master/windows/svc/example/install.go
// +build windows
package win
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/tengge1/shadoweditor/cmd"
"golang.org/x/sys/windows/svc/eventlog"
"golang.org/x/sys/windows/svc/mgr"
)
// installCmd install ShadowEditor as a service on Windows.
var installCmd = &cobra.Command{
Use: "install",
Short: "Install service on Windows",
Long: `Install service on Windows`,
Run: func(cmd *cobra.Command, args []string) {
if err := installService(ServiceName, ServiceDisplayName); err != nil {
fmt.Println(err.Error())
}
},
}
func init() {
cmd.AddCommand(installCmd)
}
func installService(name, desc string) error {
// TODO: Simplify the procedure here.
exepath, err := exePath()
if err != nil {
return err
}
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(name)
if err == nil {
s.Close()
return fmt.Errorf("service %s already exists", name)
}
s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc}, "is", "auto-started")
if err != nil {
return err
}
defer s.Close()
err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
if err != nil {
s.Delete()
return fmt.Errorf("SetupEventLogSource() failed: %s", err)
}
return nil
}
func exePath() (string, error) {
prog := os.Args[0]
p, err := filepath.Abs(prog)
if err != nil {
return "", err
}
fi, err := os.Stat(p)
if err == nil {
if !fi.Mode().IsDir() {
return p, nil
}
err = fmt.Errorf("%s is directory", p)
}
if filepath.Ext(p) == "" {
p += ".exe"
fi, err := os.Stat(p)
if err == nil {
if !fi.Mode().IsDir() {
return p, nil
}
err = fmt.Errorf("%s is directory", p)
}
}
return "", err
}