我正在Go中编写一个程序,它应该打开一个可移植的浏览器到一个给定的页面并监视它,这样如果浏览器关闭,它应该自动重新打开。此程序退出时也应关闭浏览器。
到目前为止,我已经设法在用户关闭浏览器时重新打开浏览器,但是我无法关闭它。
这是我的代码:
package browser
import (
"fmt"
"os/exec"
log "github.com/sirupsen/logrus"
)
type iBrowserHandler interface {
Start(processListener chan bool) error
Stop() error
KillProcess() error
}
type browserHandler struct {
cmd *exec.Cmd
pathToChromium string
pdvEndpoint string
}
func newBrowserHandler(pathToChromium string, pdvEndpoint string) iBrowserHandler {
b := &browserHandler{}
b.pathToChromium = pathToChromium
b.pdvEndpoint = pdvEndpoint
return b
}
func (b *browserHandler) Start(processListener chan bool) error {
endpoint := fmt.Sprintf("--app=%s", b.pdvEndpoint)
b.cmd = exec.Command(b.pathToChromium, endpoint, "--kiosk")
err := b.cmd.Run()
if err != nil {
log.WithError(err).Error("Error with the browser process")
processListener <- false
} else {
processListener <- true
}
return err
}
func (b *browserHandler) Stop() error {
err := b.cmd.Process.Release()
if err != nil {
log.WithError(err).Fatal("Error shutting down chromium")
}
return err
}
func (b *browserHandler) KillProcess() error {
err := b.cmd.Process.Kill()
if err != nil {
log.WithError(err).Fatal("Error killing chromium process")
}
return err
}
这是我用来启动浏览器的功能:
var handler iBrowserHandler
func init() {
var pathToChromium string
var c = config.GetInstance()
var os = runtime.GOOS
if os == "windows" {
pathToChromium = "chromium-browser\\ChromiumPortable.exe"
} else {
pathToChromium = "chrome"
}
handler = newBrowserHandler(pathToChromium, c.GetConfig().PDVUrl)
}
func StartBrowser(done chan bool) {
browserProcessListener := make(chan bool)
defer close(browserProcessListener)
go handler.Start(browserProcessListener)
var tryReopenBrowser = true
for {
select {
case <-browserProcessListener:
if tryReopenBrowser {
log.Warn("Browser process is stopped. Attempting to restart")
go handler.Start(browserProcessListener)
} else {
log.Warn("Browser process is stopped. Will not attempt to restart")
}
case <-done:
log.Info("Shutting down browser")
tryReopenBrowser = false
handler.KillProcess()
return
default:
}
}
}
当程序启动时,我调用StartBrowser()函数。浏览器启动后,它会一直监听它是否已关闭(cmd.Run()
函数会阻止线程的执行,直到进程完成)。
如果浏览器已关闭,则我的程序会尝试重新打开它。
如果程序收到停止信号,它会尝试关闭浏览器。我尝试使用cmd.Process.Release()
和cmd.Process.Kill()
命令,但两者都不关闭浏览器。还有其他办法吗?
答案 0 :(得分:1)
我找到了答案!问题是Go cmd.Process.Kill()
命令只停止父进程,而不是子进程,所以我不得不通过操作系统手动终止这些进程。
由于我在Windows上,KillProcess()
方法现在看起来像这样:
func (b *browserHandler) KillProcess() error {
log.Info("Killing browser process")
kill := exec.Command("taskkill", "/T", "/F", "/PID", strconv.Itoa(b.cmd.Process.Pid))
err := kill.Run()
if err != nil {
log.WithError(err).Error("Error killing chromium process")
}
log.Info("Browser process was killed")
return err
}
答案 1 :(得分:0)
而不是cmd.Run()
使用cmd.Start()
see this