Golang(Go语言) 对windows进行注销、关机、重启、闪电关机、闪电重启的操作

发布时间 2023-12-06 00:20:42作者: 烟熏牛肉干

有个小项目需要对windows系统进行远程电源操作,于是封装了以下代码方便使用。
目录结构如下:

main.go

package main

import (
	"fastshutdown/utils/power"
	"fmt"
)

func main() {
	err := power.Shutdown(true)
	if err != nil {
		fmt.Printf("Error shutting down system: %v\n", err)
		return
	}
	fmt.Println("System shutdown successfully initiated.")
}

win32api.go

package power

import (
	"fmt"
	"syscall"
	"unsafe"
)

// ntdll.dll
var (
	modntdll               = syscall.NewLazyDLL("ntdll.dll")
	procRtlAdjustPrivilege = modntdll.NewProc("RtlAdjustPrivilege")
	procNtShutdownSystem   = modntdll.NewProc("NtShutdownSystem")
)

// user32.dll
var (
	user32            = syscall.NewLazyDLL("user32.dll")
	procExitWindowsEx = user32.NewProc("ExitWindowsEx")
)

// 提权等级
const (
	privilege = 19
)

// adjustPrivilege 提权
func adjustPrivilege(privilege uintptr, enable bool) (bool, error) {
	var (
		enableInt  uintptr
		wasEnabled uintptr
	)
	if enable {
		enableInt = 1
	}
	status, _, err := procRtlAdjustPrivilege.Call(privilege, enableInt, 0, uintptr(unsafe.Pointer(&wasEnabled)))
	if status != 0 {
		return false, err
	}
	return wasEnabled > 0, nil
}

// NtShutdownSystem 执行闪电重启或关机
// 使用对应的选项,2 表示关机,1 表示重启
func ntShutdownSystem(option uintptr) error {
	_, err := adjustPrivilege(privilege, true)
	if err != nil {
		return err
	}
	status, _, err := procNtShutdownSystem.Call(option)
	if status != 0 {
		return err
	}
	return nil
}

// exitWindows 执行正常重启、关机或注销
// 第一个参数:0 表示注销,1 表示关机,2 表示重启
// 第二个参数:true表示强制退出挂起的程序,false不强制
func exitWindows(flag uint, force bool) error {
	// This syscall requires admin privileges
	_, err := adjustPrivilege(privilege, true)
	if err != nil {
		return err
	}
	ewxFlag := uintptr(flag)
	if force {
		ewxFlag |= 0x00000010
	}
	ret, _, err := procExitWindowsEx.Call(uintptr(flag), 0)

	if ret == 0 {
		return fmt.Errorf("failed to execute ExitWindowsEx: %v", err)
	}

	return nil
}

func.go

package power

func Logout(force bool) error {
	return exitWindows(0, force)
}

func Shutdown(force bool) error {
	return exitWindows(0x00000001, force)
}

func Reboot(force bool) error {
	return exitWindows(0x00000002, force)
}

func FastPowerOff() error {
	return ntShutdownSystem(1)
}

func FastReboot() error {
	return ntShutdownSystem(2)
}

注意事项:调试之前一定要保存好自己的文件,切记切记!