5 Commits
latest ... main

Author SHA1 Message Date
Gabriel Kheisa
e6fba958b3 Update main.go 2025-11-26 08:09:26 +07:00
Gabriel Kheisa
b0c38f4fda Uncomment restartExplorer function call 2025-11-25 19:37:51 +07:00
gabrielkheisa
c0f53de986 disable restart explorer 2025-04-25 21:43:37 +07:00
gabrielkheisa
da93884565 extend the explorer.exe relaunch interval 2025-04-23 21:32:27 +07:00
gabrielkheisa
b02568fbea update 2025-04-19 20:34:44 +07:00
3 changed files with 57 additions and 5 deletions

View File

@@ -92,10 +92,12 @@ This produces a GUI app (no console window).
---
## 🖼 Tray Preview
## Tray Preview
You must provide your own `icon.ico` in the same folder — this will be used as the tray icon.
![tray](/screenshot/tray.jpg)
> Tip: You can create `.ico` files from PNGs using online converters like [icoconvert.com](https://icoconvert.com)
---
@@ -106,7 +108,7 @@ You must provide your own `icon.ico` in the same folder — this will be used as
- Time check runs every 60 seconds
- Changing the clock or timezone will trigger a switch automatically
- No admin rights needed
- ~~⚠️ **Warning:** This program will kill and restart `explorer.exe` to ensure proper theme application after a mode switch. This is necessary because `explorer.exe` can sometimes become buggy and not fully apply the new theme, leaving behind visual artifacts. **Please ensure `explorer.exe` is not performing any sensitive tasks like copying files before a theme switch occurs, as this process will interrupt those operations.**~~
---
## Optional Ideas
@@ -123,4 +125,4 @@ MIT — free for personal and commercial use.
---
Made with Go, Windows quirks, and coffee ☕
Made with Go, Windows quirks, and Indocafe Coffeemix

54
main.go
View File

@@ -15,6 +15,42 @@ import (
"golang.org/x/sys/windows/registry"
)
// Define required structures for OS version check
const (
VER_MAJORVERSION = 0x001
VER_MINORVERSION = 0x002
VER_BUILDNUMBER = 0x004
)
type RTL_OSVERSIONINFOW struct {
OSVersionInfoSize uint32
MajorVersion uint32
MinorVersion uint32
BuildNumber uint32
PlatformId uint32
CSDVersion [128]uint16
}
// isWindows11OrNewer checks if the OS is Windows 11 (Build >= 22000) or later.
func isWindows11OrNewer() bool {
ntdll := syscall.NewLazyDLL("ntdll.dll")
rtlGetVersion := ntdll.NewProc("RtlGetVersion")
var info RTL_OSVERSIONINFOW
info.OSVersionInfoSize = uint32(unsafe.Sizeof(info))
ret, _, _ := rtlGetVersion.Call(uintptr(unsafe.Pointer(&info)))
// Check if the call was successful (NTSTATUS 0)
if ret != 0 {
return false // Assume older or error
}
// Windows 11 is generally defined by Build Number >= 22000
return info.MajorVersion >= 10 && info.BuildNumber >= 22000
}
// Set Windows dark/light mode via registry
func setMode(light bool) {
key, _ := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.SET_VALUE)
@@ -30,7 +66,7 @@ func setMode(light bool) {
// Restart Explorer to fully apply theme
func restartExplorer() {
exec.Command("taskkill", "/f", "/im", "explorer.exe").Run()
time.Sleep(1 * time.Second)
time.Sleep(5 * time.Second)
exec.Command("explorer.exe").Start()
}
@@ -80,6 +116,15 @@ func backgroundLoop() {
lightImg := findImageFile("light")
darkImg := findImageFile("dark")
lastMode := getCurrentMode()
// Determine if explorer restart is needed once at startup
needsExplorerRestart := isWindows11OrNewer()
if !needsExplorerRestart {
fmt.Println("Running on Windows 10 (or older), skipping explorer restart.")
} else {
fmt.Println("Running on Windows 11 (or newer), explorer restart enabled.")
}
for {
hour := time.Now().Hour()
@@ -95,7 +140,12 @@ func backgroundLoop() {
if newMode != lastMode {
setMode(newMode == "light")
restartExplorer()
// Conditional Explorer Restart ( Windows 10 or 11)
if needsExplorerRestart {
restartExplorer()
}
lastMode = newMode
}

BIN
screenshot/tray.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB