RobotGo, Go Native cross-platform RPA and GUI automation @vcaesar
Go to file
Evans 471f7ba05f
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Merge pull request #695 from go-vgo/bitmap-pr
Update: update go mod
2024-10-07 14:17:46 -07:00
.circleci Update: update screen capture code and examples 2024-10-07 13:45:03 -07:00
.github Update: update CI to newest 2024-08-16 11:35:18 -07:00
base Update: Unified pid and xid name, Update godoc, fixed typo 2022-09-13 15:49:21 -07:00
clipboard Update: gofmt the code 2023-10-30 08:24:33 -07:00
cv add readme.md file 2020-03-09 12:38:25 -04:00
docs Update README.md and documents 2023-04-09 12:40:01 -07:00
event remove unused files 2022-01-02 18:53:07 -04:00
examples Update: update examples and test code, README.md 2024-10-07 13:56:46 -07:00
key fix: x11 capslock reference the wrong constant 2023-12-20 17:35:11 +08:00
mouse Update: update and remove some old code 2023-07-06 10:14:42 -07:00
screen Fixed: Fixed x11 build 2024-10-06 18:11:23 -07:00
test Removed Windows VIRTUALScreen size and Update examples 2022-03-21 10:05:02 -07:00
window Fixed: fix x11 build 2024-10-06 17:51:51 -07:00
.gitignore Update version and keycode 2021-09-16 15:18:56 -04:00
.travis.yml Update: Bump CI to 1.19 2022-09-06 14:51:08 -07:00
appveyor.yml Update: update CI to newest 2024-08-16 11:35:18 -07:00
CONTRIBUTING.md fix: continuous typo 2023-08-26 11:45:07 +08:00
doc.go Update: Update README.md and godoc 2022-11-28 13:40:01 -08:00
go.mod Update: update go mod 2024-10-07 14:15:17 -07:00
go.sum Update: update go mod 2024-10-07 14:15:17 -07:00
img.go Update: update gomod and fixed warning 2023-09-03 12:12:56 -07:00
key.go Update: fixed windows scale move and Location(), update godoc 2023-03-13 11:07:26 -07:00
keycode.go Refactor some keyboard C code to go 2022-01-31 23:12:24 -08:00
LICENSE Update LICENSE 2017-09-19 01:50:43 +08:00
ps.go Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
README_zh.md Update README.md 2022-09-12 15:20:48 -07:00
README.md Update: update readme.md 2024-10-07 14:09:01 -07:00
robot_info_test.go Fix x11 display leak (#590) 2023-06-11 10:17:26 -07:00
robotgo_adb.go add android null file [wait push] 2019-03-05 11:12:11 -04:00
robotgo_android.go add android null file [wait push] 2019-03-05 11:12:11 -04:00
robotgo_fn_v1.go Add: add mouse of scale support and optimize the multi screen 2023-01-22 18:34:03 -08:00
robotgo_mac_unix.go add sys scale option displayID support 2022-01-03 19:49:54 -04:00
robotgo_mac_win.go Update: used NotPid option args and move Deprecated func to v1 2023-01-20 13:53:06 -08:00
robotgo_mac.go Update: Unified pid and xid name, Update godoc, fixed typo 2022-09-13 15:49:21 -07:00
robotgo_ocr.go gofmt to 1.17 build tag 2021-09-15 11:57:59 -04:00
robotgo_test.go Update: update examples and test code, README.md 2024-10-07 13:56:46 -07:00
robotgo_win.go Update: update go mod to newest 2024-06-12 13:02:30 -07:00
robotgo_x11.go chore: fix function names in comment 2024-04-15 11:37:14 +08:00
robotgo.go Update: update screen capture code and examples 2024-10-07 13:45:03 -07:00
screen.go Update: update screen capture code and examples 2024-10-07 13:45:03 -07:00
wayland_n.go Add: add next Linux and Windows files 2023-12-20 09:52:51 -08:00
windows_n.go Add: add next Linux and Windows files 2023-12-20 09:52:51 -08:00

Robotgo

Build Status CircleCI Status Build Status Appveyor Go Report Card GoDoc GitHub release Join the chat at https://gitter.im/go-vgo/robotgo

Golang Desktop Automation. Control the mouse, keyboard, read the screen, process, Window Handle, image and bitmap and global event listener.

RobotGo supports Mac, Windows, and Linux(X11); and robotgo supports arm64 and x86-amd64.

Contents

Docs

Binding:

ADB, packaging android adb API.

Robotn, binding JavaScript and other, support more language.

Requirements:

Now, Please make sure Golang, GCC is installed correctly before installing RobotGo.

ALL:

Golang

GCC

For MacOS:

Xcode Command Line Tools (And Privacy setting: #277)

xcode-select --install

For Windows:

MinGW-w64 (Use recommended) or others Mingw llvm-mingw;

Download the Mingw, then set system environment variables C:\mingw64\bin to the Path. Set environment variables to run GCC from command line.

Or the other GCC (But you should compile the "libpng" with yourself when use the bitmap.)

For everything else:

GCC

X11 with the XTest extension (the Xtst library)

"Clipboard": xsel xclip


"Bitmap": libpng (Just used by the "bitmap".)

"Event-Gohook": xcb, xkb, libxkbcommon (Just used by the "hook".)

Ubuntu:
# gcc
sudo apt install gcc libc6-dev

# x11
sudo apt install libx11-dev xorg-dev libxtst-dev

# Clipboard
sudo apt install xsel xclip

#
# Bitmap
sudo apt install libpng++-dev

# GoHook
sudo apt install xcb libxcb-xkb-dev x11-xkb-utils libx11-xcb-dev libxkbcommon-x11-dev libxkbcommon-dev

Fedora:
# x11
sudo dnf install libXtst-devel

# Clipboard
sudo dnf install xsel xclip

#
# Bitmap
sudo dnf install libpng-devel

# GoHook
sudo dnf install libxkbcommon-devel libxkbcommon-x11-devel xorg-x11-xkb-utils-devel

Installation:

With Go module support (Go 1.11+), just import:

import "github.com/go-vgo/robotgo"

Otherwise, to install the robotgo package, run the command:

go get github.com/go-vgo/robotgo

png.h: No such file or directory? Please see issues/47.

Update:

go get -u github.com/go-vgo/robotgo

Note go1.10.x C file compilation cache problem, golang #24355. go mod vendor problem, golang #26366.

Examples:

Mouse

package main

import (
  "github.com/go-vgo/robotgo"
)

func main() {
  robotgo.MouseSleep = 100

  robotgo.ScrollDir(10, "up")
  robotgo.ScrollDir(20, "right")

  robotgo.Scroll(0, -10)
  robotgo.Scroll(100, 0)

  robotgo.MilliSleep(100)
  robotgo.ScrollSmooth(-10, 6)
  // robotgo.ScrollRelative(10, -100)

  robotgo.Move(10, 20)
  robotgo.MoveRelative(0, -10)
  robotgo.DragSmooth(10, 10)

  robotgo.Click("wheelRight")
  robotgo.Click("left", true)
  robotgo.MoveSmooth(100, 200, 1.0, 10.0)

  robotgo.Toggle("left")
  robotgo.Toggle("left", "up")
}

Keyboard

package main

import (
  "fmt"

  "github.com/go-vgo/robotgo"
)

func main() {
  robotgo.TypeStr("Hello World")
  robotgo.TypeStr("だんしゃり", 0, 1)
  // robotgo.TypeStr("テストする")

  robotgo.TypeStr("Hi, Seattle space needle, Golden gate bridge, One world trade center.")
  robotgo.TypeStr("Hi galaxy, hi stars, hi MT.Rainier, hi sea. こんにちは世界.")
  robotgo.Sleep(1)

  // ustr := uint32(robotgo.CharCodeAt("Test", 0))
  // robotgo.UnicodeType(ustr)

  robotgo.KeySleep = 100
  robotgo.KeyTap("enter")
  // robotgo.TypeStr("en")
  robotgo.KeyTap("i", "alt", "cmd")

  arr := []string{"alt", "cmd"}
  robotgo.KeyTap("i", arr)

  robotgo.MilliSleep(100)
  robotgo.KeyToggle("a")
  robotgo.KeyToggle("a", "up")

  robotgo.WriteAll("Test")
  text, err := robotgo.ReadAll()
  if err == nil {
    fmt.Println(text)
  }
}

Screen

package main

import (
  "fmt"

  "github.com/go-vgo/robotgo"
  "github.com/vcaesar/imgo"
)

func main() {
  x, y := robotgo.Location()
  fmt.Println("pos: ", x, y)

  color := robotgo.GetPixelColor(100, 200)
  fmt.Println("color---- ", color)

  sx, sy := robotgo.GetScreenSize()
  fmt.Println("get screen size: ", sx, sy)

  bit := robotgo.CaptureScreen(10, 10, 30, 30)
  defer robotgo.FreeBitmap(bit)

  img := robotgo.ToImage(bit)
  imgo.Save("test.png", img)

  num := robotgo.DisplaysNum()
  for i := 0; i < num; i++ {
    robotgo.DisplayID = i
    img1, _ := robotgo.CaptureImg()
    path1 := "save_" + strconv.Itoa(i)
    robotgo.Save(img1, path1+".png")
    robotgo.SaveJpeg(img1, path1+".jpeg", 50)

    img2, _ := robotgo.CaptureImg(10, 10, 20, 20)
    robotgo.Save(img2, "test_"+strconv.Itoa(i)+".png")

    x, y, w, h := robotgo.GetDisplayBounds(i)
    img3, err := robotgo.CaptureImg(x, y, w, h)
    fmt.Println("Capture error: ", err)
    robotgo.Save(img3, path1+"_1.png")
  }
}

Bitmap

package main

import (
  "fmt"

  "github.com/go-vgo/robotgo"
  "github.com/vcaesar/bitmap"
)

func main() {
  bit := robotgo.CaptureScreen(10, 20, 30, 40)
  // use `defer robotgo.FreeBitmap(bit)` to free the bitmap
  defer robotgo.FreeBitmap(bit)

  fmt.Println("bitmap...", bit)
  img := robotgo.ToImage(bit)
  // robotgo.SavePng(img, "test_1.png")
  robotgo.Save(img, "test_1.png")

  bit2 := robotgo.ToCBitmap(robotgo.ImgToBitmap(img))
  fx, fy := bitmap.Find(bit2)
  fmt.Println("FindBitmap------ ", fx, fy)
  robotgo.Move(fx, fy)

  arr := bitmap.FindAll(bit2)
  fmt.Println("Find all bitmap: ", arr)

  fx, fy = bitmap.Find(bit)
  fmt.Println("FindBitmap------ ", fx, fy)

  bitmap.Save(bit, "test.png")
}

OpenCV

package main

import (
  "fmt"
  "math/rand"

  "github.com/go-vgo/robotgo"
  "github.com/vcaesar/gcv"
  "github.com/vcaesar/bitmap"
)

func main() {
  opencv()
}

func opencv() {
  name := "test.png"
  name1 := "test_001.png"
  robotgo.SaveCapture(name1, 10, 10, 30, 30)
  robotgo.SaveCapture(name)

  fmt.Print("gcv find image: ")
  fmt.Println(gcv.FindImgFile(name1, name))
  fmt.Println(gcv.FindAllImgFile(name1, name))

  bit := bitmap.Open(name1)
  defer robotgo.FreeBitmap(bit)
  fmt.Print("find bitmap: ")
  fmt.Println(bitmap.Find(bit))

  // bit0 := robotgo.CaptureScreen()
  // img := robotgo.ToImage(bit0)
  // bit1 := robotgo.CaptureScreen(10, 10, 30, 30)
  // img1 := robotgo.ToImage(bit1)
  // defer robotgo.FreeBitmapArr(bit0, bit1)
  img, _ := robotgo.CaptureImg()
  img1, _ := robotgo.CaptureImg(10, 10, 30, 30)

  fmt.Print("gcv find image: ")
  fmt.Println(gcv.FindImg(img1, img))
  fmt.Println()

  res := gcv.FindAllImg(img1, img)
  fmt.Println(res[0].TopLeft.Y, res[0].Rects.TopLeft.X, res)
  x, y := res[0].TopLeft.X, res[0].TopLeft.Y
  robotgo.Move(x, y-rand.Intn(5))
  robotgo.MilliSleep(100)
  robotgo.Click()

  res = gcv.FindAll(img1, img) // use find template and sift
  fmt.Println("find all: ", res)
  res1 := gcv.Find(img1, img)
  fmt.Println("find: ", res1)

  img2, _, _ := robotgo.DecodeImg("test_001.png")
  x, y = gcv.FindX(img2, img)
  fmt.Println(x, y)
}

Event

package main

import (
  "fmt"

  // "github.com/go-vgo/robotgo"
  hook "github.com/robotn/gohook"
)

func main() {
  add()
  low()
  event()
}

func add() {
  fmt.Println("--- Please press ctrl + shift + q to stop hook ---")
  hook.Register(hook.KeyDown, []string{"q", "ctrl", "shift"}, func(e hook.Event) {
    fmt.Println("ctrl-shift-q")
    hook.End()
  })

  fmt.Println("--- Please press w---")
  hook.Register(hook.KeyDown, []string{"w"}, func(e hook.Event) {
    fmt.Println("w")
  })

  s := hook.Start()
  <-hook.Process(s)
}

func low() {
	evChan := hook.Start()
	defer hook.End()

	for ev := range evChan {
		fmt.Println("hook: ", ev)
	}
}

func event() {
  ok := hook.AddEvents("q", "ctrl", "shift")
  if ok {
    fmt.Println("add events...")
  }

  keve := hook.AddEvent("k")
  if keve {
    fmt.Println("you press... ", "k")
  }

  mleft := hook.AddEvent("mleft")
  if mleft {
    fmt.Println("you press... ", "mouse left button")
  }
}

Window

package main

import (
  "fmt"

  "github.com/go-vgo/robotgo"
)

func main() {
  fpid, err := robotgo.FindIds("Google")
  if err == nil {
    fmt.Println("pids... ", fpid)

    if len(fpid) > 0 {
      robotgo.TypeStr("Hi galaxy!", fpid[0])
      robotgo.KeyTap("a", fpid[0], "cmd")

      robotgo.KeyToggle("a", fpid[0])
      robotgo.KeyToggle("a", fpid[0], "up")

      robotgo.ActivePid(fpid[0])

      robotgo.Kill(fpid[0])
    }
  }

  robotgo.ActiveName("chrome")

  isExist, err := robotgo.PidExists(100)
  if err == nil && isExist {
    fmt.Println("pid exists is", isExist)

    robotgo.Kill(100)
  }

  abool := robotgo.Alert("test", "robotgo")
  if abool {
 	  fmt.Println("ok@@@ ", "ok")
  }

  title := robotgo.GetTitle()
  fmt.Println("title@@@ ", title)
}

Authors

Plans

  • Refactor some C code to Go (such as x11, windows)
  • Better multiscreen support
  • Wayland support
  • Update Window Handle
  • Try to support Android and IOS

Contributors

License

Robotgo is primarily distributed under the terms of "both the MIT license and the Apache License (Version 2.0)", with portions covered by various BSD-like licenses.

See LICENSE-APACHE, LICENSE-MIT.