Skip to content

Commit

Permalink
added: RAM cleaner, refactored: internals files
Browse files Browse the repository at this point in the history
  • Loading branch information
middaysan committed May 25, 2024
1 parent 5a68f17 commit a4acbda
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 154 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
This is a simple Windows application that runs in the system tray and allows you to clean the standby memory list. The application requests administrator privileges upon startup and provides a menu in the tray to perform memory cleaning.

## Features
- Runs in the system tray.
- Cleans RAM
- Cleans the standby memory list when its size exceeds 65% of free memory.
- Requests administrator privileges on startup.
- Displays memory usage statistics when hovering over the tray icon.
- Uses an embedded icon for the tray.
- Runs in the system tray.

## Requirements
- Requests administrator privileges on startup.
- Windows operating system.
- Go 1.16 or later.

Expand Down
52 changes: 44 additions & 8 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,64 @@
package main

import (
"clean-standby-list/internal/elevation"
"clean-standby-list/internal/memory"
"clean-standby-list/internal/tray"
"clean-standby-list/internal/windows_api"
"runtime"
"time"

"github.com/getlantern/systray"
)

var lastCleanup time.Time
var stopChan = make(chan struct{})
const (
percentThreshold = 65
)

func main() {
// Request admin rights if not already granted
if !elevation.IsRunAsAdmin() {
elevation.RunMeElevated()
if !windowsapi.IsRunAsAdmin() {
windowsapi.RunAsAdmin()
return
}

onReady := func() {
tray.OnReady(memory.EmptyStandbyList, memory.CheckAndCleanStandbyList)
}
go autoCleanStandbyList(stopChan)

systray.Run(onReady, onExit)
systray.Run(tray.OnReady, onExit)
}

func onExit() {
close(stopChan)
runtime.GC()
}

// autoCleanStandbyList periodically cleans the standby list to free up RAM.
// It runs in a loop until the stopChan is closed.
// The function checks the percentage of standby list usage against the threshold.
// If the percentage is above the threshold and enough time has passed since the last cleanup,
// it calls the CleanStandbyList function to clean the standby list.
// It also updates the tooltip and sleeps for 1 minute before the next iteration.
//
// Parameters:
// - stopChan: A channel used to stop the function when closed.
//
// Note: The function assumes the availability of the windowsapi package.
func autoCleanStandbyList(stopChan chan struct{}) {
for {
select {
case <-stopChan:
return
default:
standbyList, freeRAM, _ := windowsapi.GetStanbyListAndFreeRAMSize()
percent := standbyList / freeRAM * 100

if percent > percentThreshold && time.Since(lastCleanup) > 5*time.Minute {
windowsapi.CleanStandbyList()
lastCleanup = time.Now()
}

tray.UpdateTooltip()
time.Sleep(1 * time.Minute)
}
}
}
100 changes: 0 additions & 100 deletions internal/memory/memory.go

This file was deleted.

Binary file modified internal/tray/assets/icon.ico
Binary file not shown.
99 changes: 68 additions & 31 deletions internal/tray/tray.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ package tray
import (
_ "embed"
"fmt"
"log"
"os"
"time"

windowsapi "clean-standby-list/internal/windows_api"

"github.com/getlantern/systray"
)

Expand All @@ -18,43 +19,79 @@ import (
//go:embed assets/icon.ico
var iconData []byte

var LastCleanup time.Time
const (
PercentThreshold = 65
)

type TrayInfoStruct struct {
LastSTDCleanup time.Time
LastRAMCleanup time.Time
ErrorStr string
}

var TrayInfo = TrayInfoStruct{
LastSTDCleanup: time.Time{},
LastRAMCleanup: time.Time{},
ErrorStr: "",
}

func OnReady(emptyStandbyList func() error, checkAndCleanStandbyList func()) {
// OnReady initializes the system tray icon and menu items.
// It sets the icon, title, and adds menu items for cleaning the standby list, cleaning the RAM, and quitting the application.
// It also starts a goroutine to handle menu item clicks.
func OnReady() {
systray.SetIcon(iconData) // Use the embedded icon
systray.SetTitle("Memory Cleaner")
systray.SetTooltip("Right-click to clean standby list")

mClean := systray.AddMenuItem("Clean", "Clean the standby list")
mSTDClean := systray.AddMenuItem("Clean Standby List", "Clean the standby list")
mRAMClean := systray.AddMenuItem("Clean RAM", "Clean the RAM")
mQuit := systray.AddMenuItem("Quit", "Exit the application")

go func() {
for {
select {
case <-mClean.ClickedCh:
if err := emptyStandbyList(); err != nil {
log.Printf("Error cleaning standby list: %v\n", err)
} else {
log.Println("Standby list cleaned successfully")
LastCleanup = time.Now()
}
case <-mQuit.ClickedCh:
systray.Quit()
os.Exit(0)
}
}
}()
go handleMenuClicks(mSTDClean, mRAMClean, mQuit)
}

// Periodically update the tooltip with memory information
go func() {
for {
checkAndCleanStandbyList()
time.Sleep(30 * time.Second) // Update every minute
}
}()
// UpdateTooltip updates the tooltip text of the system tray icon.
// It retrieves the standby list and free RAM size using the windowsapi package,
// and formats the tooltip string with the obtained values and the last cleanup timestamps.
// The formatted tooltip string is then set as the tooltip for the system tray icon.
func UpdateTooltip() {
standbyList, freeRAM, err := windowsapi.GetStanbyListAndFreeRAMSize()
if err != nil {
TrayInfo.ErrorStr = err.Error()
}

tooltipStr := fmt.Sprintf(
"SBL: %d MB\nFreeRAM: %d MB\nSTBcln: %s\nRAMcln: %s",
standbyList/(1024*1024),
freeRAM/(1024*1024),
TrayInfo.LastSTDCleanup.Format("15:04:05"),
TrayInfo.LastRAMCleanup.Format("15:04:05"),
)

systray.SetTooltip(tooltipStr)
}

func UpdateTooltip(standbySize, freeSize uint64, percent uint64) {
tooltip := fmt.Sprintf("Standby List: %d MB, Free Memory: %d MB, Percent: %d%%", standbySize/(1024*1024), freeSize/(1024*1024), percent)
systray.SetTooltip(tooltip)
func handleMenuClicks(mSTDClean, mRAMClean, mQuit *systray.MenuItem) {
for {
select {
case <-mRAMClean.ClickedCh:
if err := windowsapi.CleanRAM(); err != nil {
TrayInfo.ErrorStr = err.Error()
UpdateTooltip()
} else {
TrayInfo.LastRAMCleanup = time.Now()
UpdateTooltip()
}
case <-mSTDClean.ClickedCh:
if err := windowsapi.CleanStandbyList(); err != nil {
TrayInfo.ErrorStr = err.Error()
UpdateTooltip()
} else {
TrayInfo.LastSTDCleanup = time.Now()
UpdateTooltip()
}
case <-mQuit.ClickedCh:
systray.Quit()
os.Exit(0)
}
}
}
Loading

0 comments on commit a4acbda

Please sign in to comment.