I am writing a program in Go that should open a portable browser to a given page and monitor it, so that if the browser is closed, it should be automatically reopened. Also the browser should be closed when the program exits.
So far I have managed to reopen the browser when the user closes it, however I am not being able to close it.
Here is my code:
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
}
And this is the function that I am using to start the browser:
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:
}
}
}
When the program starts I call the StartBrowser() function. Once the browser is started, it keeps listening to see if it was closed (the cmd.Run()
function blocks the execution of the thread until the process finishes).
If the browser was closed, then my program attempts to reopen it.
If the program receives a stop signal, it tries to close the browser. I tried to use both the cmd.Process.Release()
and the cmd.Process.Kill()
commands, but both do not close the browser. Is there any other way to do this?
The SIGINT signal is sent to a process by its controlling terminal when a user wishes to interrupt the process. This is typically initiated by pressing Ctrl+C, but on some systems, the "delete" character or "break" key can be used.
The provided context is used to kill the process (by calling os. Process. Kill) if the context becomes done before the command completes on its own. After the Run() completes, you can inspect ctx.
I found an answer! The problem is that the Go cmd.Process.Kill()
command only stops the parent process, but not the child processes, so I had to kill these processes manually through the OS.
Since I am on Windows my KillProcess()
method now looks like this:
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
}
Credits: this thread has an answer for both Windows and Unix systems.
Instead of cmd.Run()
use cmd.Start()
see this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With