程序启动器

顾名思义,程序启动器仅作为一个程序的独立入口,和命令行 start xxx 有一样的功能,多一个启动器,也就是为程序入口加个 LOGO
本启动器使用 GO 实现

1. 配置文件

为了使程序在使用过程中更加灵活,我们需要一个设计一个配置文件 launcher.json

1
2
3
4
5
{
"target": "ping",
"workDir": ".",
"params": ["www.baidu.com", "-n", "2"]
}

配置文件初步需求为三个参数,目标命令(target)、执行目录(workDir)、参数(params)

2. 解析配置文件

在代码中定义文件对象属性

1
2
3
4
5
type LaunchConfig struct {
Target string `json:"target"`
WorkDir string `json:"workDir"`
Params []string `json:"params"`
}

加载配置文件

1
2
3
JsonParse := NewJsonConfig()
v := LaunchConfig{}
JsonParse.LoadConfig("launcher.json", &v)

3. 为启动器加锁

通过加锁的方式保证程序同一时间内不可启动多次

1
2
3
4
5
6
7
8
9
10
_, err := os.Stat(".lock.loop")
if err == nil || os.IsExist(err) {
file, _ = os.OpenFile("README.Use.txt", os.O_CREATE|os.O_WRONLY, 0666)
file.WriteAt([]byte("u must shutdown the exe and then remove .lock.loop file"), 0)
file.Close()
fmt.Println("u must shutdown the exe and then remove .lock.loop file")
return
}
// 加锁
file, _ = os.Create(".lock.loop")

4. 支持命令行附加参数

1
2
// 将命令行参数 合并到配置文件的参数后面
cmd := exec.Command(v.Target, append(v.Params, args...)...)

5. 启动子进程

1
2
3
4
5
6
7
8
9
cmd.Dir = v.WorkDir
cmd.Env = os.Environ()
// 重定向子进程的错误输出
cmd.Stderr = os.Stderr
cmd.Start()
// cmd.Wait()
fmt.Printf("[PID] %d running...\n", cmd.Process.Pid)
file.Close()
os.Remove(".lock.loop")

6 总结

总体来说是一个比较简单的练手程序,程序源代码地址 source