banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

[Reprint] Setting Desktop Wallpaper in Golang

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  
}  
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.