gameproc

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: MIT Imports: 15 Imported by: 0

README

go-gameproc

Go


Find, stop and wait for a game's processes, natively or under Wine, Proton, dotnet or mono, on Linux and Windows. Package gameproc, module github.com/Rethunk-Tech/go-gameproc.

A game can run natively, under Wine or Proton, or through dotnet or mono, and a launcher or mod manager must tell which install a process belongs to, never mistake a system program or Steam for the game, and stop it cleanly. This package does that from the process table alone: no game data, no options, names come from the caller.

Quick start

go get github.com/Rethunk-Tech/go-gameproc

A worked example and the contracts: HUMANS.md.

Features

  • List processes by program name in one pass, with executable, command line and start time, including from inside a Flatpak.
  • Tell which install a process runs from, by executable, argument, Wine Z: path or symlinked deploy.
  • Stop politely: a Wine process is asked to close first, so a launcher sees a clean exit.
  • Wait for any pid, and read the exit code and signal of a child.
  • Start a child so its whole tree ends together: a process group, or a job object on Windows.
  • Start a Windows console program in a console of its own.

Documentation

Doc Audience
HUMANS.md Running and using the package
AGENTS.md Internals, invariants, and why
CONTRIBUTING.md Process — commits, tests, docs
SECURITY.md Vulnerability disclosure
CHANGELOG.md Release notes

License

MIT — see LICENSE. © 2026 Rethunk.Tech, LLC.

Documentation

Overview

Package gameproc finds, stops and waits for a game's processes, natively or under Wine, Proton, dotnet or mono, on Linux (including from inside a Flatpak) and Windows.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoConsole = errors.New("gameproc: a program with its own console starts only on Windows")

ErrNoConsole is StartOwnConsole's error off Windows.

View Source
var ErrNotChild = errors.New("gameproc: the process is not a child, so its exit status is unknown")

ErrNotChild is WaitPID's error, joined with the wait error, for a Unix process that is not the caller's child: it was waited out, but its exit status is unknown.

View Source
var ErrNotTracked = errors.New("gameproc: the process runs outside a job")

ErrNotTracked is TrackTree's error, joined with its cause, for a process that was resumed but that no job holds: KillTree then ends only the process.

Functions

func Alive

func Alive(pid int) bool

Alive reports whether a process with this pid is still running.

func ImagePath

func ImagePath(pid int) (string, error)

ImagePath is the executable path of pid (QueryFullProcessImageName).

func KillTree

func KillTree(pid int)

KillTree ends the process and, when it was tracked, everything it started.

func PrepareTree

func PrepareTree(cmd *exec.Cmd, noConsole bool)

PrepareTree makes cmd start suspended, so TrackTree can put it in a job before it spawns anything that would escape, and without a console window when noConsole. It never sets HideWindow and keeps one the caller set: Windows applies HideWindow to the first window the process shows, so a program that starts the real one in a second process (a mod loader that runs the game) would open that window hidden. CREATE_NO_WINDOW only withholds the console. An existing SysProcAttr is kept.

func StartOwnConsole

func StartOwnConsole(env []string, dir, name string, args []string) (<-chan error, error)

StartOwnConsole starts a program in a new console that it reads and writes itself, as a desktop shell or a game launcher starts a console program. os/exec cannot: it always passes standard handles (STARTF_USESTDHANDLES), and when none are set they are NUL, so the console stays empty and an input loop reads end-of-file. Redirecting a program that has a console also breaks the console calls it makes (colours, cursor, window size).

env is the complete environment of the program; empty means the caller's own. The process is tracked as TrackTree tracks one (it runs untracked when no job can hold it) and is released when it exits. The channel receives the exit: nil for code 0, else an error with ExitCode(), which StatusOf maps. It takes no context: the program outlives the caller's request.

func Stop

func Stop(_ context.Context, p Process, grace time.Duration) error

Stop is Terminate: Windows has no polite close for a process the caller does not own the windows of.

func Terminate

func Terminate(pid int, grace time.Duration) error

Terminate ends the process, or its whole tracked tree, at once, since Windows has no polite signal for a GUI program, and waits up to grace for it to be gone: TerminateProcess returns before the program's files are released.

func TrackTree

func TrackTree(pid int) error

TrackTree is called with the pid of a cmd that PrepareTree set, after Start. It puts the process in a job of its own, so KillTree reaches what it spawns, and resumes it. Closing the job handle later does not end the process: a started program may outlive its caller. An error matching ErrNotTracked, joined with its cause, means the process was resumed but no job holds it. Any other error means it could not be resumed; end it with KillTree.

func UntrackTree

func UntrackTree(pid int)

UntrackTree releases the job once the process has exited; call it after Wait returns. A job left behind for a pid the system later reuses would make Terminate end that job instead of the new process.

Types

type Process

type Process struct {
	PID   int
	Exe   string
	Args  []string
	Start time.Time
}

Process is a running process. Args is nil where the platform gives no command line (Windows). Exe is empty where the platform will not say which file the process runs (another user's process, a host listing from a Flatpak). Start is the zero time when unknown.

func Processes

func Processes(_ string, names ...string) ([]Process, error)

Processes lists processes whose image name is one of names (in any case, with or without ".exe") through Toolhelp. procDir is ignored. Command lines are not read (that needs the process's PEB), so Args stays nil. A program in the Windows folder is skipped; one whose image path cannot be read is kept with an empty Exe.

func (Process) ExeIs

func (p Process) ExeIs(names ...string) bool

ExeIs reports whether p's executable is one of the programs names, so its path is where the game itself runs from; it is false for an unreadable executable and for a host (Wine, Proton, dotnet) that runs the game.

func (Process) LinkedFrom

func (p Process) LinkedFrom(dir string) bool

LinkedFrom reports whether p's executable is the target of the file of the same name in dir. A mod manager that deploys by symlink puts the loader in the game folder as a link into its staging folder, and Windows names a process by the link's target, so the process path alone would not place it in the install.

func (Process) Named

func (p Process) Named(names ...string) bool

Named reports whether p is one of names, as Processes matched it. A process whose image path was unreadable may be any of them.

func (Process) RunsFrom

func (p Process) RunsFrom(dir string) bool

RunsFrom reports whether p belongs to the install in dir: its executable is inside dir, or a command-line argument names a path inside it. Wine and Proton processes show the Windows path of the game, which sits under Z: for a file outside the prefix, so that form counts as the Unix path it maps to.

type Status

type Status struct {
	Code   int
	Signal string
}

Status is how a process ended. Signal is the Unix signal name ("SIGSEGV") of a process a signal killed, and is empty on Windows. A killed process has Code 128 plus the signal number.

func StatusOf

func StatusOf(err error) Status

StatusOf maps exec.Cmd.Wait's error (or a StartOwnConsole result) to a Status. Signal is always empty.

func WaitPID

func WaitPID(pid int) (Status, error)

WaitPID waits until pid exits and reports its exit code, for a child or not.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL