Golang 跨平台自动化系统,控制键盘、鼠标、位图、图像、读取屏幕,进程、窗口句柄以及全局事件监听。

Evans 471f7ba05f Merge pull request #695 from go-vgo/bitmap-pr 2 weeks ago
.circleci 47cde13dab Update: update screen capture code and examples 2 weeks ago
.github f98b4c52bd Update: update CI to newest 2 months ago
base e9b5a9251e Update: Unified pid and xid name, Update godoc, fixed typo 2 years ago
clipboard b8a6b1778e Update: gofmt the code 11 months ago
cv 519c7bf718 add readme.md file 4 years ago
docs c62f7fd81e Update README.md and documents 1 year ago
event 627f5c9d3b remove unused files 2 years ago
examples 78d01703b8 Update: update examples and test code, README.md 2 weeks ago
key 61b77ce3e1 fix: x11 capslock reference the wrong constant 10 months ago
mouse 5c3cbd6e17 Update: update and remove some old code 1 year ago
screen 75fd24ea0a Fixed: Fixed x11 build 2 weeks ago
test 985c590284 Removed Windows VIRTUALScreen size and Update examples 2 years ago
window ead43d062e Fixed: fix x11 build 2 weeks ago
.gitignore a23859625e Update version and keycode 3 years ago
.travis.yml f428ffb1fb Update: Bump CI to 1.19 2 years ago
CONTRIBUTING.md 5b0ac98ef3 fix: continuous typo 1 year ago
LICENSE 6c790bdaf4 Update LICENSE 7 years ago
README.md 70f811ce53 Update: update readme.md 2 weeks ago
README_zh.md 47ca6812fe Update README.md 2 years ago
appveyor.yml f98b4c52bd Update: update CI to newest 2 months ago
doc.go f911550742 Update: Update README.md and godoc 1 year ago
go.mod a84a195c4c Update: update go mod 2 weeks ago
go.sum a84a195c4c Update: update go mod 2 weeks ago
img.go 90f41269da Update: update gomod and fixed warning 1 year ago
key.go ffcf6b26cd Update: fixed windows scale move and Location(), update godoc 1 year ago
keycode.go 99963bc6fc Refactor some keyboard C code to go 2 years ago
ps.go 469cd4da5e Update & Add: unified use the int to replace int32; 1 year ago
robot_info_test.go 8e7a413ec6 Fix x11 display leak (#590) 1 year ago
robotgo.go 47cde13dab Update: update screen capture code and examples 2 weeks ago
robotgo_adb.go 1e7006d7de add android null file [wait push] 5 years ago
robotgo_android.go 1e7006d7de add android null file [wait push] 5 years ago
robotgo_fn_v1.go bb76af18f0 Add: add mouse of scale support and optimize the multi screen 1 year ago
robotgo_mac.go e9b5a9251e Update: Unified pid and xid name, Update godoc, fixed typo 2 years ago
robotgo_mac_unix.go 337cd3f73a add sys scale option displayID support 2 years ago
robotgo_mac_win.go df1617d894 Update: used NotPid option args and move Deprecated func to v1 1 year ago
robotgo_ocr.go cc45178922 gofmt to 1.17 build tag 3 years ago
robotgo_test.go 78d01703b8 Update: update examples and test code, README.md 2 weeks ago
robotgo_win.go 8a990ac042 Update: update go mod to newest 4 months ago
robotgo_x11.go 05c54c6f25 chore: fix function names in comment 6 months ago
screen.go 47cde13dab Update: update screen capture code and examples 2 weeks ago
wayland_n.go 39818d41fa Add: add next Linux and Windows files 10 months ago
windows_n.go 39818d41fa Add: add next Linux and Windows files 10 months ago

README.md

Robotgo

Build Status CircleCI Status Build Status Appveyor Go Report Card GoDoc GitHub release

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.