mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 03:23:49 +08:00
95 lines
2.8 KiB
Go
95 lines
2.8 KiB
Go
//go:build windows
|
||
// +build windows
|
||
|
||
package terminal
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"unsafe"
|
||
|
||
"golang.org/x/sys/windows"
|
||
|
||
"github.com/pkg/errors"
|
||
)
|
||
|
||
// RunningByDoubleClick 检查是否通过双击直接运行
|
||
func RunningByDoubleClick() bool {
|
||
kernel32 := windows.NewLazySystemDLL("kernel32.dll")
|
||
lp := kernel32.NewProc("GetConsoleProcessList")
|
||
if lp != nil {
|
||
var ids [2]uint32
|
||
var maxCount uint32 = 2
|
||
ret, _, _ := lp.Call(uintptr(unsafe.Pointer(&ids)), uintptr(maxCount))
|
||
if ret > 1 {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// NoMoreDoubleClick 提示用户不要双击运行,并生成安全启动脚本
|
||
func NoMoreDoubleClick() error {
|
||
toHighDPI()
|
||
r := boxW(getConsoleWindows(), "请勿通过双击直接运行本程序, 这将导致一些非预料的后果.\n请在shell中运行./go-cqhttp.exe\n点击确认将释出安全启动脚本,点击取消则关闭程序", "警告", 0x00000030|0x00000001)
|
||
if r == 2 {
|
||
return nil
|
||
}
|
||
r = boxW(0, "点击确认将覆盖go-cqhttp.bat,点击取消则关闭程序", "警告", 0x00000030|0x00000001)
|
||
if r == 2 {
|
||
return nil
|
||
}
|
||
f, err := os.OpenFile("go-cqhttp.bat", os.O_CREATE|os.O_RDWR, 0o666)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if err != nil {
|
||
return errors.Errorf("打开go-cqhttp.bat失败: %v", err)
|
||
}
|
||
_ = f.Truncate(0)
|
||
|
||
ex, _ := os.Executable()
|
||
exPath := filepath.Base(ex)
|
||
_, err = f.WriteString("%Created by go-cqhttp. DO NOT EDIT ME!%\nstart cmd /K \"" + exPath + "\"")
|
||
if err != nil {
|
||
return errors.Errorf("写入go-cqhttp.bat失败: %v", err)
|
||
}
|
||
f.Close()
|
||
boxW(0, "安全启动脚本已生成,请双击go-cqhttp.bat启动", "提示", 0x00000040|0x00000000)
|
||
return nil
|
||
}
|
||
|
||
// BoxW of Win32 API. Check https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxw for more detail.
|
||
func boxW(hwnd uintptr, caption, title string, flags uint) int {
|
||
captionPtr, _ := windows.UTF16PtrFromString(caption)
|
||
titlePtr, _ := windows.UTF16PtrFromString(title)
|
||
u32 := windows.NewLazySystemDLL("user32.dll")
|
||
ret, _, _ := u32.NewProc("MessageBoxW").Call(
|
||
hwnd,
|
||
uintptr(unsafe.Pointer(captionPtr)),
|
||
uintptr(unsafe.Pointer(titlePtr)),
|
||
uintptr(flags))
|
||
|
||
return int(ret)
|
||
}
|
||
|
||
// GetConsoleWindows retrieves the window handle used by the console associated with the calling process.
|
||
func getConsoleWindows() (hWnd uintptr) {
|
||
hWnd, _, _ = windows.NewLazySystemDLL("kernel32.dll").NewProc("GetConsoleWindow").Call()
|
||
return
|
||
}
|
||
|
||
// toHighDPI tries to raise DPI awareness context to DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED
|
||
func toHighDPI() {
|
||
systemAware := ^uintptr(2) + 1
|
||
unawareGDIScaled := ^uintptr(5) + 1
|
||
u32 := windows.NewLazySystemDLL("user32.dll")
|
||
proc := u32.NewProc("SetThreadDpiAwarenessContext")
|
||
if proc.Find() != nil {
|
||
return
|
||
}
|
||
for i := unawareGDIScaled; i <= systemAware; i++ {
|
||
_, _, _ = u32.NewProc("SetThreadDpiAwarenessContext").Call(i)
|
||
}
|
||
}
|