list Windows user services
This commit is contained in:
parent
cc0176e058
commit
f03a0755af
|
@ -51,6 +51,10 @@ func Stop(conf *service.Service) error {
|
||||||
return stop(conf)
|
return stop(conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func List(conf *service.Service) ([]string, []string, []error) {
|
||||||
|
return list(conf)
|
||||||
|
}
|
||||||
|
|
||||||
// IsPrivileged returns true if we suspect that the current user (or process) will be able
|
// IsPrivileged returns true if we suspect that the current user (or process) will be able
|
||||||
// to write to system folders, bind to privileged ports, and otherwise
|
// to write to system folders, bind to privileged ports, and otherwise
|
||||||
// successfully run a system service.
|
// successfully run a system service.
|
||||||
|
@ -67,6 +71,16 @@ func WhereIs(exe string) (string, error) {
|
||||||
return filepath.Abs(filepath.ToSlash(exepath))
|
return filepath.Abs(filepath.ToSlash(exepath))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ManageError struct {
|
||||||
|
Name string
|
||||||
|
Hint string
|
||||||
|
Parent error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ManageError) Error() string {
|
||||||
|
return e.Name + ": " + e.Hint + ": " + e.Parent.Error()
|
||||||
|
}
|
||||||
|
|
||||||
type ErrDaemonize struct {
|
type ErrDaemonize struct {
|
||||||
DaemonArgs []string
|
DaemonArgs []string
|
||||||
error string
|
error string
|
||||||
|
|
|
@ -130,6 +130,38 @@ func stop(conf *service.Service) error {
|
||||||
return runner.Stop(conf)
|
return runner.Stop(conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func list(c *service.Service) ([]string, []string, []error) {
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
regs, err := listRegistry(c)
|
||||||
|
if nil != err {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgs, errors := listConfigs(c)
|
||||||
|
if 0 != len(errors) {
|
||||||
|
errs = append(errs, errors...)
|
||||||
|
}
|
||||||
|
|
||||||
|
managed := []string{}
|
||||||
|
for i := range cfgs {
|
||||||
|
managed = append(managed, cfgs[i].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
others := []string{}
|
||||||
|
for i := range regs {
|
||||||
|
reg := regs[i]
|
||||||
|
for j := range cfgs {
|
||||||
|
cfg := cfgs[j]
|
||||||
|
if reg != cfg.Title {
|
||||||
|
others = append(others, reg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return managed, others, errs
|
||||||
|
}
|
||||||
|
|
||||||
func getRunnerArgs(c *service.Service) []string {
|
func getRunnerArgs(c *service.Service) []string {
|
||||||
self := os.Args[0]
|
self := os.Args[0]
|
||||||
debug := ""
|
debug := ""
|
||||||
|
@ -154,6 +186,84 @@ func getRunnerArgs(c *service.Service) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type winConf struct {
|
||||||
|
Filename string `json:"-"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func listConfigs(c *service.Service) ([]winConf, []error) {
|
||||||
|
var errs []error
|
||||||
|
|
||||||
|
smdir := `\opt\serviceman`
|
||||||
|
if !c.System {
|
||||||
|
smdir = filepath.Join(c.Home, ".local", smdir)
|
||||||
|
}
|
||||||
|
confpath := filepath.Join(smdir, `etc`)
|
||||||
|
|
||||||
|
infos, err := ioutil.ReadDir(confpath)
|
||||||
|
if nil != err {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
errs = append(errs, &ManageError{
|
||||||
|
Name: confpath,
|
||||||
|
Hint: "Read directory",
|
||||||
|
Parent: err,
|
||||||
|
})
|
||||||
|
return nil, errs
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO report active status
|
||||||
|
srvs := []winConf{}
|
||||||
|
for i := range infos {
|
||||||
|
filename := strings.ToLower(infos[i].Name())
|
||||||
|
if len(filename) <= srvLen || !strings.HasSuffix(srvExt, filename) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := filename[:len(filename)-srvLen]
|
||||||
|
b, err := ioutil.ReadFile(filepath.Join(confpath, filename))
|
||||||
|
if nil != err {
|
||||||
|
errs = append(errs, &ManageError{
|
||||||
|
Name: name,
|
||||||
|
Hint: "Read file",
|
||||||
|
Parent: err,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cfg := &winConf{Filename: filename}
|
||||||
|
err = json.Unmarshal(b, cfg)
|
||||||
|
if nil != err {
|
||||||
|
errs = append(errs, &ManageError{
|
||||||
|
Name: name,
|
||||||
|
Hint: "Parse JSON",
|
||||||
|
Parent: err,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
srvs = append(srvs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return srvs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listRegistry(c *service.Service) ([]string, error) {
|
||||||
|
autorunKey := `SOFTWARE\Microsoft\Windows\CurrentVersion\Run`
|
||||||
|
k, _, err := registry.CreateKey(
|
||||||
|
registry.CURRENT_USER,
|
||||||
|
autorunKey,
|
||||||
|
registry.QUERY_VALUE,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer k.Close()
|
||||||
|
|
||||||
|
return k.ReadValueNames(-1)
|
||||||
|
}
|
||||||
|
|
||||||
// copies self to install path and returns config path
|
// copies self to install path and returns config path
|
||||||
func installServiceman(c *service.Service) ([]string, error) {
|
func installServiceman(c *service.Service) ([]string, error) {
|
||||||
// TODO check version and upgrade or dismiss
|
// TODO check version and upgrade or dismiss
|
||||||
|
|
Loading…
Reference in New Issue