title: 【Reprint】Setting Desktop Wallpaper with Golang
date: 2021-07-06 11:14:45
comment: false
toc: true
category:
- Golang
tags: - Reprint
- Go
- golang
- Setting
- Desktop
- Wallpaper
This article is reprinted from: Setting Desktop Wallpaper with Golang - Go Language Chinese Network - Golang Chinese Community & Golang Version Change Windows Wallpaper to Bing Daily Background Image - Go Language Chinese Network - Golang Chinese Community
Version 1#
Written in Golang, set Windows desktop wallpaper, the image comes from Bing website (cn.bing.com)
GitHub source address: https://github.com/tujiaw/gowallpaper
If you're interested, give it a star
Compiled program: https://pan.baidu.com/s/1l5OW9GeuUF0r5TFaBWkWZg (extraction code: pcqh)
Double-click to run, display as follows:
Set Microsoft Bing's wallpaper, usage as follows:
day - Update wallpaper daily
now - Set today's wallpaper
prev - Set yesterday's wallpaper
next - Set tomorrow's wallpaper
rand - Randomly switch wallpaper at intervals (e.g., switch wallpaper every minute: rand 1m)
quit - Exit
#
Golang Calls Windows API#
package winapi
import (
"log"
"syscall"
"unsafe"
)
var ApiList = map[string][]string {
"user32.dll": {
"MessageBoxW",
"SystemParametersInfoW",
},
"kernel32.dll": {
},
}
var ProcCache map[string]*syscall.Proc
func init() {
ProcCache = make(map[string]*syscall.Proc)
for dllName, apiList := range ApiList {
d, err := syscall.LoadDLL(dllName)
if err != nil {
panic(err)
}
for _, name := range apiList {
api, err := d.FindProc(name)
if err != nil {
log.Println(err, name)
}
ProcCache[name] = api
}
_ = syscall.FreeLibrary(d.Handle)
}
}
func WinCall(name string, a ...uintptr) {
if api, ok := ProcCache[name]; ok {
_, _, err := api.Call(a...)
if err != nil {
log.Println(err)
}
} else {
log.Println("API not found, name:", name)
}
}
func IntPtr(n int) uintptr {
return uintptr(n)
}
func StrPtr(s string) uintptr {
p, _ := syscall.UTF16PtrFromString(s)
return uintptr(unsafe.Pointer(p))
}
func ShowMessage(title, text string) {
WinCall("MessageBoxW", IntPtr(0), StrPtr(text), StrPtr(title), IntPtr(0))
}
func SetWallpaper(bmpPath string) {
WinCall("SystemParametersInfoW", IntPtr(20), IntPtr(0), StrPtr(bmpPath), IntPtr(3))
}
Version 2#
Directly obtain image links from the Bing search homepage, modify the size in the link, obtain the image, and call the Windows DLL to set the desktop background image
package main
import (
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"github.com/antchfx/htmlquery"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"syscall"
"time"
"unsafe"
)
const (
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
BingHomeURL = "https://cn.bing.com"
CurrentPathDir = "cache/"
)
const (
Size1k string = "1920,1080"
Size2k string = "2560,1440"
Size4k string = "3840,2160"
)
// ImageSize Image size
type ImageSize struct {
w string
h string
}
func init() {
_ = os.Mkdir(CurrentPathDir, 0755)
}
// EncodeMD5 MD5 encoding
func EncodeMD5(value string) string {
m := md5.New()
m.Write([]byte(value))
return hex.EncodeToString(m.Sum(nil))
}
// SetWindowsWallpaper Set Windows wallpaper
func SetWindowsWallpaper(imagePath string) error {
dll := syscall.NewLazyDLL("user32.dll")
proc := dll.NewProc("SystemParametersInfoW")
_t, _ := syscall.UTF16PtrFromString(imagePath)
ret, _, _ := proc.Call(20, 1, uintptr(unsafe.Pointer(_t)), 0x1|0x2)
if ret != 1 {
return errors.New("System call failed")
}
return nil
}
// GetBingBackgroundImageURL Get Bing homepage background image link
func GetBingBackgroundImageURL() (string, error) {
client := http.Client{}
request, err := http.NewRequest("GET", BingHomeURL, nil)
if err != nil {
return "", err
}
request.Header.Set("user-agent", UserAgent)
response, err := client.Do(request)
if err != nil {
return "", err
}
htmlDoc, err := htmlquery.Parse(response.Body)
if err != nil {
return "", err
}
item := htmlquery.FindOne(htmlDoc, "//div[@id=\"bgImgProgLoad\"]")
result := htmlquery.SelectAttr(item, "data-ultra-definition-src")
return BingHomeURL + result, nil
}
// DownloadImage Download image, save and return the absolute path of the saved file name
func DownloadImage(imageURL string, size *ImageSize) (string, error) {
wRegexp := regexp.MustCompile("w=\\d+")
hRegexp := regexp.MustCompile("h=\\d+")
imageURL = wRegexp.ReplaceAllString(imageURL, "w="+size.w)
imageURL = hRegexp.ReplaceAllString(imageURL, "h="+size.h)
client := http.Client{}
request, err := http.NewRequest("GET", imageURL, nil)
if err != nil {
return "", err
}
response, err := client.Do(request)
if err != nil {
return "", err
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}
day := time.Now().Format("2006-01-02")
fileName := EncodeMD5(imageURL)
path := CurrentPathDir + fmt.Sprintf("[%sx%s][%s]%s", size.w, size.h, day, fileName) + ".jpg"
err = ioutil.WriteFile(path, body, 0755)
if err != nil {
return "", err
}
absPath, err := filepath.Abs(path)
if err != nil {
return "", err
}
return absPath, nil
}
func main() {
fmt.Println("Getting Bing background image...")
imageURL, err := GetBingBackgroundImageURL()
if err != nil {
fmt.Println("Failed to get background image link: " + err.Error())
return
}
fmt.Println("Successfully obtained: " + imageURL)
fmt.Println("Downloading image...")
imagePath, err := DownloadImage(imageURL, &ImageSize{
w: strings.Split(Size4k, ",")[0],
h: strings.Split(Size4k, ",")[1],
})
if err != nil {
fmt.Println("Failed to download image: " + err.Error())
return
}
fmt.Println("Setting desktop...")
err = SetWindowsWallpaper(imagePath)
if err != nil {
fmt.Println("Failed to set desktop background: " + err.Error())
return
}
}
My Version#
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"syscall"
"time"
"unsafe"
"github.com/antchfx/htmlquery"
)
func main() {
// fmt.Println("Getting Bing background image...")
// imageURL, err := GetBingBackgroundImageURL()
// if err != nil {
// fmt.Println("Failed to get background image link: " + err.Error())
// return
// }
// fmt.Println("Successfully obtained: " + imageURL)
fmt.Println("Downloading image...")
imagePath, err := DownloadImage(computerMobilePhoneAdaptiveRandomPicture, &ImageSize{
w: strings.Split(Size4k, ",")[0],
h: strings.Split(Size4k, ",")[1],
})
if err != nil {
fmt.Println("Failed to download image: " + err.Error())
return
}
fmt.Println("Setting desktop...")
err = SetWindowsWallpaper(imagePath)
if err != nil {
fmt.Println("Failed to set desktop background: " + err.Error())
return
}
}
const (
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
BingHomeURL = "https://cn.bing.com"
CurrentPathDir = "cache/"
RandBingImgURL = "https://img.tjit.net/bing/rand/"
// Computer mobile adaptive random image
computerMobilePhoneAdaptiveRandomPicture = "https://img.tjit.net/bing/rand/"
)
const (
Size1k string = "1920,1080"
Size2k string = "2560,1440"
Size4k string = "3840,2160"
)
// ImageSize Image size
type ImageSize struct {
w string
h string
}
func init() {
_ = os.Mkdir(CurrentPathDir, 0755)
}
// EncodeMD5 MD5 encoding
func EncodeMD5(value string) string {
m := md5.New()
m.Write([]byte(value))
return hex.EncodeToString(m.Sum(nil))
}
// SetWindowsWallpaper Set Windows wallpaper
func SetWindowsWallpaper(imagePath string) error {
dll := syscall.NewLazyDLL("user32.dll")
proc := dll.NewProc("SystemParametersInfoW")
_t, _ := syscall.UTF16PtrFromString(imagePath)
ret, _, _ := proc.Call(20, 1, uintptr(unsafe.Pointer(_t)), 0x1|0x2)
if ret != 1 {
return errors.New("System call failed")
}
return nil
}
// GetBingBackgroundImageURL Get Bing homepage background image link
func GetBingBackgroundImageURL() (string, error) {
client := http.Client{}
request, err := http.NewRequest("GET", BingHomeURL, nil)
if err != nil {
return "", err
}
request.Header.Set("user-agent", UserAgent)
response, err := client.Do(request)
if err != nil {
return "", err
}
bodyRes, err := ioutil.ReadAll(response.Body)
body := ioutil.NopCloser(bytes.NewReader(bodyRes))
body1 := ioutil.NopCloser(bytes.NewReader(bodyRes))
htmlDoc, err := htmlquery.Parse(body)
if err != nil {
return "", err
}
all, err := ioutil.ReadAll(body1)
s := string(all)
fmt.Println(s)
item := htmlquery.FindOne(htmlDoc, "//div[@id=\"bgImgProgLoad\"]")
result := htmlquery.SelectAttr(item, "data-ultra-definition-src")
return BingHomeURL + result, nil
}
// DownloadImage Download image, save and return the absolute path of the saved file name
func DownloadImage(imageURL string, size *ImageSize) (string, error) {
wRegexp := regexp.MustCompile("w=\\d+")
hRegexp := regexp.MustCompile("h=\\d+")
imageURL = wRegexp.ReplaceAllString(imageURL, "w="+size.w)
imageURL = hRegexp.ReplaceAllString(imageURL, "h="+size.h)
client := http.Client{}
request, err := http.NewRequest("GET", imageURL, nil)
if err != nil {
return "", err
}
response, err := client.Do(request)
if err != nil {
return "", err
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return "", err
}
day := time.Now().Format("2006-01-02")
fileName := EncodeMD5(imageURL)
path := CurrentPathDir + fmt.Sprintf("[%sx%s][%s]%s", size.w, size.h, day, fileName) + ".jpg"
err = ioutil.WriteFile(path, body, 0755)
if err != nil {
return "", err
}
absPath, err := filepath.Abs(path)
if err != nil {
return "", err
}
return absPath, nil
}