RobotGo, Go Native cross-platform RPA and GUI automation @vcaesar
Go to file
vcaesar 469cd4da5e Update & Add: unified use the int to replace int32;
unified name and add more func;
Update gomod and CI
2022-11-27 17:55:45 -08:00
.circleci Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
.github Update: Bump CI to 1.19 2022-09-06 14:51:08 -07:00
base Update: Unified pid and xid name, Update godoc, fixed typo 2022-09-13 15:49:21 -07:00
clipboard Update godoc and README.md 2021-11-17 17:08:59 -04:00
cv add readme.md file 2020-03-09 12:38:25 -04:00
docs Update godoc and README.md 2021-12-24 13:50:06 -04:00
event remove unused files 2022-01-02 18:53:07 -04:00
examples Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
key Optimize keyboard code and Update examples 2022-04-09 10:33:02 -07:00
mouse Update: Unified pid and xid name, Update godoc, fixed typo 2022-09-13 15:49:21 -07:00
screen Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
test Removed Windows VIRTUALScreen size and Update examples 2022-03-21 10:05:02 -07:00
window Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08: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 & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
CONTRIBUTING.md update and unify copyright year 2018-02-02 00:07:44 +08:00
doc.go Update godoc 2022-01-31 17:25:23 -08:00
go.mod Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
go.sum Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
img.go convert img lose 1 pixel bug 2022-07-31 16:47:14 +08:00
key.go Update: update godoc and fixed typo 2022-09-14 15:23:09 -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 godoc and fixed typo 2022-09-14 15:23:09 -07:00
robot_info_test.go Unifed and rename some function for Pad 2022-11-01 10:28:00 -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_mac_unix.go add sys scale option displayID support 2022-01-03 19:49:54 -04:00
robotgo_mac_win.go Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -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 & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
robotgo_win.go Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
robotgo_x11.go Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -08:00
robotgo.go Update & Add: unified use the int to replace int32; 2022-11-27 17:55:45 -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, bitmap and image, read the screen, process, Window Handle 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 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)


"Bitmap":

libpng (Just used by bitmap)

"Event":

xcb, xkb, libxkbcommon

"Clipboard":

xsel xclip
Ubuntu:
# gcc
sudo apt install gcc libc6-dev

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

# Bitmap
sudo apt install libpng++-dev

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

# Clipboard
sudo apt install xsel xclip
Fedora:
sudo dnf install libXtst-devel 

# Bitmap
sudo dnf install libpng-devel

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

# Clipboard
sudo dnf install xsel xclip

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")
  }
}

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!", int(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)
}

CrossCompiling

Windows64 to windows32
SET CGO_ENABLED=1
SET GOARCH=386
go build main.go

Other to windows

Install Requirements (Ubuntu, Just used by bitmap.):

sudo apt install gcc-multilib
sudo apt install gcc-mingw-w64
# fix err: zlib.h: No such file or directory
sudo apt install libz-mingw-w64-dev

Build the binary:

GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ go build -x ./
// CC=mingw-w64\x86_64-7.2.0-win32-seh-rt_v5-rev1\mingw64\bin\gcc.exe
// CXX=mingw-w64\x86_64-7.2.0-win32-seh-rt_v5-rev1\mingw64\bin\g++.exe

Some discussions and questions, please see issues/228, issues/143.

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.