Golang(Go语言) 对windows进行注销、关机、重启、闪电关机、闪电重启的操作
有个小项目需要对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)
}
注意事项:调试之前一定要保存好自己的文件,切记切记!