go windows鎖屏 && 關閉桌面(殺掉檔案資源管理器)

Grassto發表於2020-10-15

鎖屏

func lockScreen() {
	var args []string
	args = append(args, "user32.dll", "LockWorkStation")
	_, err := common.StartProcess("rundll32.exe", args...)
	if err != nil {
		common.Log.Error("lockScreen err:", err)
	}
}

判斷是否鎖屏

func tScreenIsLocked() {
	lockScreen()
	// 時延太短會看不到效果
	time.Sleep(time.Second * 7)
	fmt.Println(ScreenIsLocked())
}

const (
	DESKTOP_SWITCHDESKTOP = 0x0100 // The access to the desktop
)

// get desktop locked status
func ScreenIsLocked() bool {

	// load user32.dll only once
	user32 := syscall.MustLoadDLL("user32.dll")
	openDesktop := user32.MustFindProc("OpenDesktopW")
	closeDesktop := user32.MustFindProc("CloseDesktop")
	switchDesktop := user32.MustFindProc("SwitchDesktop")


	var lpdzDesktopPtr uintptr = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Default"))) //string
	var dwFloatsPtr uintptr = 0                                                               //uint32
	var fInheritPtr uintptr = 0                                                               //boolean
	var dwDesiredAccessPtr uintptr = uintptr(DESKTOP_SWITCHDESKTOP)                           //uint32

	r1, _, _ := syscall.Syscall6(openDesktop.Addr(), 4, lpdzDesktopPtr, dwFloatsPtr, fInheritPtr, dwDesiredAccessPtr, 0, 0)
	if r1 == 0 {
		panic("get desktop locked status error")
	}

	res, _, _ := syscall.Syscall(switchDesktop.Addr(), 1, r1, 0, 0)
	// clean up
	syscall.Syscall(closeDesktop.Addr(), 1, r1, 0, 0)

	return res != 1
}

殺掉檔案資源管理器

type PROCESSENTRY32 struct {
	dwSize              int32
	cntUsage            int32
	th32ProcessID       int32
	th32DefaultHeapID   uintptr
	th32ModuleID        int32
	cntThreads          int32
	th32ParentProcessID int32
	pcPriClassBase      int32
	dwFlags             int32
	szExeFile           [260]byte
}

func killExplorer() {
	kernel32 := syscall.NewLazyDLL("kernel32.dll")
	CreateToolhelp32Snapshot := kernel32.NewProc("CreateToolhelp32Snapshot")
	pHandle, _, _ := CreateToolhelp32Snapshot.Call(uintptr(0x2), uintptr(0x0))
	if int(pHandle) == -1 {
		fmt.Println("pHandle = -1")
		return
	}
	defer func() {
		CloseHandle := kernel32.NewProc("CloseHandle")
		CloseHandle.Call(pHandle)
	}()
	Process32Next := kernel32.NewProc("Process32Next")
	for {
		var proc PROCESSENTRY32
		proc.dwSize = int32(unsafe.Sizeof(proc))
		if rt, _, _ := Process32Next.Call(uintptr(pHandle), uintptr(unsafe.Pointer(&proc))); int(rt) == 1 {
			if strings.HasPrefix(string(proc.szExeFile[0:]), "explorer.exe") {
				if pro, err := os.FindProcess(int(proc.th32ProcessID)); err != nil {
					fmt.Println("FindProcess err: ", err)
				} else {
					err = pro.Kill()
				}
			}
		} else {
			break
		}
	}
}

注: 檔案資源管理器被關閉之後,可按Ctrl + Shift + Delete開啟工作管理員,檔案 => 執行新任務,輸入explorer.exe重新開啟檔案資源管理器。

相關文章