python写个自己用的内存清理工具,用在win10和win11上很实用。分享完整源码,可根据自己需求随意定制

开发背景;

自己电脑经常内存飙升却不知道是什么进程引起的,按传统办法是要点开任务管理器去排个序来查看下,有时还要点开文件位置再确认一下,觉得麻烦。 于是干脆用Python写一个,很实用!

功能特点:

  1. 内存清理信息:清理前和清理后的内存使用总和。

  2. 进程列表:显示所有进程的 PID、名称、内存使用和文件位置。点击列名可以对该列进行排序。

  3. 功能按钮:清理内存”:清理内存并更新内存使用信息。“刷新进程列表”:重新加载进程列表并更新内存使用信息。“结束进程”:弹出确认对话框,用户确认后结束选中的进程。“导出进程列表”:将当前进程列表导出为 CSV 文件。

  4. 新进程提醒:如果有新进程启动,会弹窗显示进程的名称、PID 和文件位置。

工具截图:

完整代码:

import os
import psutil
import ctypes
import sys
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import csv
import time
import threading

# 检查并提升管理员权限
def run_as_admin():
    if sys.platform != 'win32':
        return False

    try:
        if ctypes.windll.shell32.IsUserAnAdmin():
            return True
    except:
        pass

    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
    sys.exit()

# 获取所有进程信息
def get_processes():
    processes = []
    for proc in psutil.process_iter(['pid', 'name', 'memory_info', 'exe']):
        try:
            processes.append((proc.info['pid'], proc.info['name'], proc.info['memory_info'].rss, proc.info['exe']))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            continue
    return processes

# 计算所有进程的内存使用总和
def get_total_memory_usage():
    total_memory = 0
    for proc in psutil.process_iter(['memory_info']):
        try:
            total_memory += proc.info['memory_info'].rss
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            continue
    return total_memory

# 结束选中的进程
def kill_process():
    selected_item = process_tree.selection()
    if not selected_item:
        messagebox.showwarning("警告", "请选择一个进程!")
        return

    pid = int(process_tree.item(selected_item, 'values')[0])
    process_name = process_tree.item(selected_item, 'values')[1]

    # 确认对话框
    confirm = messagebox.askyesno("确认", f"确定要结束进程 {process_name} (PID: {pid}) 吗?")
    if not confirm:
        return

    try:
        process = psutil.Process(pid)
        process.terminate()
        messagebox.showinfo("成功", f"进程 {process_name} (PID: {pid}) 已结束!")
        refresh_processes()
    except Exception as e:
        messagebox.showerror("错误", f"结束进程时出错: {e}")

# 刷新进程列表
def refresh_processes():
    for row in process_tree.get_children():
        process_tree.delete(row)
    processes = get_processes()
    for proc in processes:
        process_tree.insert("", "end", values=proc)

    # 更新内存使用信息
    update_memory_usage()

# 更新内存使用信息
def update_memory_usage():
    total_memory = get_total_memory_usage()
    memory_before.set(f"清理前内存使用: {total_memory / 1024 / 1024:.2f} MB")
    memory_after.set(f"清理后内存使用: {total_memory / 1024 / 1024:.2f} MB")

# 内存清理功能
def clear_memory():
    try:
        # 获取清理前的内存使用总和
        before_memory = get_total_memory_usage()

        # 释放未使用的内存
        ctypes.windll.psapi.EmptyWorkingSet(ctypes.c_ulong(-1))

        # 获取清理后的内存使用总和
        after_memory = get_total_memory_usage()

        # 更新界面显示
        memory_before.set(f"清理前内存使用: {before_memory / 1024 / 1024:.2f} MB")
        memory_after.set(f"清理后内存使用: {after_memory / 1024 / 1024:.2f} MB")
        messagebox.showinfo("成功", "内存清理完成!")
    except Exception as e:
        messagebox.showerror("错误", f"清理内存时出错: {e}")

# 导出进程列表为 CSV 文件
def export_processes():
    file_path = filedialog.asksaveasfilename(
        defaultextension=".csv",
        filetypes=[("CSV 文件", "*.csv"), ("所有文件", "*.*")],
        title="保存进程列表"
    )
    if not file_path:
        return

    try:
        with open(file_path, mode="w", newline="", encoding="utf-8") as file:
            writer = csv.writer(file)
            # 写入表头
            writer.writerow(["PID", "进程名", "内存使用 (MB)", "文件位置"])
            # 写入进程数据
            for row in process_tree.get_children():
                values = process_tree.item(row, 'values')
                writer.writerow(values)
        messagebox.showinfo("成功", f"进程列表已导出到 {file_path}")
    except Exception as e:
        messagebox.showerror("错误", f"导出进程列表时出错: {e}")

# 排序函数
def treeview_sort_column(tv, col, reverse):
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    try:
        l.sort(key=lambda t: int(t[0]) if col == "memory" else t[0], reverse=reverse)
    except ValueError:
        l.sort(reverse=reverse)

    for index, (val, k) in enumerate(l):
        tv.move(k, '', index)

    tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse))

# 监控新进程
def monitor_new_processes():
    global previous_processes

    while True:
        current_processes = get_processes()
        current_pids = {proc[0] for proc in current_processes}
        previous_pids = {proc[0] for proc in previous_processes}

        # 检查新进程
        new_pids = current_pids - previous_pids
        if new_pids:
            for proc in current_processes:
                if proc[0] in new_pids:
                    messagebox.showinfo(
                        "新进程提醒",
                        f"新进程已启动:\n\n"
                        f"进程名: {proc[1]}\n"
                        f"PID: {proc[0]}\n"
                        f"文件位置: {proc[3]}"
                    )

        previous_processes = current_processes
        time.sleep(5)  # 每 5 秒检查一次

# 创建主窗口
def create_gui():
    global memory_before, memory_after, process_tree, previous_processes

    root = tk.Tk()
    root.title("内存清理工具")
    root.geometry("800x600")

    # 初始化进程列表
    previous_processes = get_processes()

    # 启动新进程监控线程
    monitor_thread = threading.Thread(target=monitor_new_processes, daemon=True)
    monitor_thread.start()

    # 标题
    title_label = tk.Label(root, text="Windows 内存清理工具", font=("Arial", 16))
    title_label.pack(pady=10)

    # 内存信息显示
    memory_before = tk.StringVar()
    memory_after = tk.StringVar()

    memory_before.set("清理前内存使用: N/A")
    memory_after.set("清理后内存使用: N/A")

    before_label = tk.Label(root, textvariable=memory_before, font=("Arial", 12))
    before_label.pack(pady=5)

    after_label = tk.Label(root, textvariable=memory_after, font=("Arial", 12))
    after_label.pack(pady=5)

    # 清理内存按钮
    clear_button = tk.Button(root, text="清理内存", command=clear_memory, font=("Arial", 14), bg="lightblue")
    clear_button.pack(pady=10)

    # 进程列表
    process_frame = tk.Frame(root)
    process_frame.pack(fill="both", expand=True, padx=10, pady=10)

    columns = ("pid", "name", "memory", "exe")
    process_tree = ttk.Treeview(process_frame, columns=columns, show="headings")
    process_tree.heading("pid", text="PID", command=lambda: treeview_sort_column(process_tree, "pid", False))
    process_tree.heading("name", text="进程名", command=lambda: treeview_sort_column(process_tree, "name", False))
    process_tree.heading("memory", text="内存使用 (MB)", command=lambda: treeview_sort_column(process_tree, "memory", False))
    process_tree.heading("exe", text="文件位置", command=lambda: treeview_sort_column(process_tree, "exe", False))

    process_tree.column("pid", width=100, anchor="center")
    process_tree.column("name", width=200, anchor="w")
    process_tree.column("memory", width=150, anchor="center")
    process_tree.column("exe", width=300, anchor="w")

    process_tree.pack(fill="both", expand=True)

    # 刷新进程列表按钮
    refresh_button = tk.Button(root, text="刷新进程列表", command=refresh_processes, font=("Arial", 12), bg="lightgreen")
    refresh_button.pack(pady=10)

    # 结束进程按钮
    kill_button = tk.Button(root, text="结束进程", command=kill_process, font=("Arial", 12), bg="lightcoral")
    kill_button.pack(pady=10)

    # 导出进程列表按钮
    export_button = tk.Button(root, text="导出进程列表", command=export_processes, font=("Arial", 12), bg="lightyellow")
    export_button.pack(pady=10)

    # 初始化进程列表和内存使用信息
    refresh_processes()

    root.mainloop()

if __name__ == "__main__":
    run_as_admin()
    create_gui()

代码说明

  1. monitor_new_processes

    • 这是一个后台线程函数,每 5 秒检查一次系统进程列表。

    • 如果发现新进程,弹窗显示进程的名称、PID 和文件位置。

  2. get_processes

    • 获取所有进程的信息,包括 PID、名称、内存使用和文件位置。

  3. previous_processes

    • 用于存储上一次检查时的进程列表,以便与新进程列表进行比较。

  4. threading.Thread

    • 使用线程运行 monitor_new_processes,避免阻塞主界面。

<think>我们将在Windows 10上安装离线版SonarQube。由于是离线环境,我们需要提前下载好所需的文件。 步骤包括:下载SonarQube、安装Java环境、配置SonarQube、启动服务、安装插件(离线方式)、创建项目并扫描。 注意:SonarQube需要Java 11或17(根据版本不同),这里我们使用Java 17。 1. 环境准备 - 下载Java 17 (Zulu JDK 17) 离线安装包: https://www.azul.com/downloads/?package=jdk (选择Windows ZIP) - 下载SonarQube最新社区版: https://www.sonarsource.com/products/sonarqube/downloads/ (选择Community Edition ZIP) 2. 安装步骤 a) 安装Java:解压Zulu JDK到某个目录,例如:C:\Java\zulu17 b) 设置环境变量:JAVA_HOME=C:\Java\zulu17,并添加%JAVA_HOME%\bin到PATH c) 解压SonarQube到目录,例如:C:\SonarQube 3. 配置SonarQube(可选修改配置) 编辑C:\SonarQube\conf\sonar.properties: - 修改Web服务端口(默认9000): sonar.web.port=9000 - 如果需要修改数据库(默认使用内嵌H2,不推荐生产),这里我们使用默认H2(离线演示) 4. 启动SonarQube 以管理员身份打开命令提示符: cd C:\SonarQube\bin\windows-x86-64 StartSonar.bat 5. 安装插件(离线) - 从官网下载插件(需提前在有网络的环境下载): https://docs.sonarqube.org/latest/instance-administration/plugin-version-matrix/ - 将插件JAR文件放入C:\SonarQube\extensions\plugins - 重启SonarQube服务(先按Ctrl+C停止,再运行StartSonar.bat) 6. 创建扫描项目 使用SonarScanner进行扫描。下载SonarScanner for Windows并解压:https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/ 设置环境变量:将sonar-scanner的bin目录加入PATH。 7. 配置项目 在项目根目录创建sonar-project.properties文件: ```properties # 项目唯一标识 sonar.projectKey=my_project sonar.projectName=My Project sonar.projectVersion=1.0 # 源码目录 sonar.sources=src # 语言(根据插件支持) sonar.language=java # 编码 sonar.sourceEncoding=UTF-8 ``` 8. 执行扫描 在项目根目录运行: sonar-scanner 9. 查看报告 访问 http://localhost:9000 使用默认账号admin/admin登录。 注意:由于是离线环境,扫描时可能会提示无法更新插件,但已安装的插件规则仍然有效。 下面给出一个示例Java项目(带有一个有问题的代码)的扫描过程: 示例代码结构: my_project/ src/ main/ java/ com/ example/ Calculator.java Calculator.java 内容: ```java package com.example; public class Calculator { public int add(int a, int b) { return a + b; } public void divide(int a, int b) { if (b == 0) { System.out.println("Division by zero!"); } int result = a / b; // 这里当b为0时会抛出ArithmeticException } } ``` 执行扫描后,在SonarQube的界面上可以看到一个Bug:在divide方法中,当b为0时,会执行除法操作导致异常。 10. 自定义规则(可选) 在SonarQube的Web界面,可以创建质量配置(Quality Profiles)来自定义规则。 注意:在离线环境中,无法从SonarSource更新规则集,因此只能使用已安装插件自带的规则或手动导入之前导出的规则集。 下面提供如何导出导入规则集的步骤(需联网环境准备,然后离线使用): a) 在联网环境中,登录SonarQube,进入质量配置,导出所需的规则集(如Java的Sonar way)。 b) 将导出的XML文件复制到离线环境。 c) 在离线环境的SonarQube中,创建新的质量配置,然后选择导入。 由于是离线环境,我们可能无法获得所有规则,但可以使用已有的规则。 现在,我们给出一个批处理脚本,用于启动SonarQube服务(避免每次手动启动): 创建文件:C:\SonarQube\start_sonar.bat ```batch @echo off cd /d %~dp0 cd bin\windows-x86-64 StartSonar.bat ``` 注意事项: - SonarQube在Windows上作为控制台程序运行,关闭控制台窗口即停止服务。 - 生产环境建议将SonarQube安装为Windows服务(可以使用NSSM等工具)。 安装为服务(可选): - 下载NSSM:https://nssm.cc/download - 解压后,以管理员身份运行nssm.exe - 在界面中设置: Path: C:\SonarQube\bin\windows-x86-64\StartSonar.bat Startup directory: C:\SonarQube\bin\windows-x86-64 Service name: SonarQube - 点击Install service 这样,SonarQube就会作为服务运行。 现在,我们总结一下在Windows 10上安装离线版SonarQube的步骤。 由于我们无法在离线环境中下载,所以所有文件都需要提前准备好。 最后,我们给出一个简单的批处理脚本,用于设置环境变量(如果尚未设置)并启动SonarQube: ```batch @echo off REM 设置JAVA_HOME(如果未设置) if not defined JAVA_HOME set JAVA_HOME=C:\Java\zulu17 REM 将Java添加到PATH set PATH=%JAVA_HOME%\bin;%PATH% REM 启动SonarQube cd C:\SonarQube\bin\windows-x86-64 StartSonar.bat ``` 请根据实际安装目录调整上述路径。 §§相关问题§§: 1. 如何解决SonarQube启动时提示的“找不到Java”错误? 2. 在离线环境中如何更新SonarQube的版本? 3. 如何配置SonarQube使用外部数据库(如MySQL)? 4. SonarScanner在扫描时如何跳过测试代码?</think>### Windows 10 离线版 SonarQube 安装及使用教程 #### 一、环境准备(需提前下载) 1. **Java JDK**: - 下载 [Zulu JDK 17](https://www.azul.com/downloads/?package=jdk)(Windows ZIP) - 解压到 `C:\Java\jdk-17` 2. **SonarQube**: - 下载 [SonarQube 9.9 LTS](https://www.sonarsource.com/products/sonarqube/downloads/)(ZIP 包) - 解压到 `C:\SonarQube` 3. **插件**(下载后放至 `C:\SonarQube\extensions\plugins`): - [Java 插件](https://repo1.maven.org/maven2/org/sonarsource/java/sonar-java-plugin/7.14.0.31588/sonar-java-plugin-7.14.0.31588.jar) - [Python 插件](https://repo1.maven.org/maven2/org/sonarsource/python/sonar-python-plugin/3.15.0.3766/sonar-python-plugin-3.15.0.3766.jar) #### 二、配置环境变量 ```batch :: 以管理员身份运行CMD setx /M JAVA_HOME "C:\Java\jdk-17" setx /M Path "%Path%;%JAVA_HOME%\bin;C:\SonarQube\bin\windows-x86-64" ``` #### 三、修改配置文件 编辑 `C:\SonarQube\conf\sonar.properties`: ```properties # 取消注释并修改 sonar.web.host=0.0.0.0 sonar.web.port=9000 # 禁用更新检查(离线关键) sonar.updatecenter.activate=false # 使用内置H2数据库(离线模式) sonar.jdbc.url=jdbc:h2:tcp://localhost:9092/sonar ``` #### 四、启动服务 ```batch :: 以管理员身份运行 cd C:\SonarQube\bin\windows-x86-64 StartSonar.bat ``` **首次登录**: 访问 `http://localhost:9000`,账号/密码:`admin/admin` #### 五、创建扫描项目 1. 项目结构: ``` my-project/ ├─ src/ │ ├─ main.py ├─ sonar-project.properties ``` 2. Python 示例代码 (`main.py`): ```python def divide(a, b): # 漏洞:未处理除零错误 return a / b if __name__ == "__main__": print(divide(10, 0)) # 将引发异常 ``` 3. 配置文件 (`sonar-project.properties`): ```properties sonar.projectKey=my_python_project sonar.projectName=My Python Project sonar.projectVersion=1.0 sonar.sources=src sonar.sourceEncoding=UTF-8 sonar.language=py sonar.scm.disabled=true # 离线关键 ``` #### 六、执行扫描 1. 下载 [SonarScanner](https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/)(Windows ZIP) 2. 解压并添加 `bin` 目录到系统 PATH 3. 在项目根目录运行: ```batch sonar-scanner -Dsonar.login=admin -Dsonar.password=admin ``` #### 七、查看报告 访问 `http://localhost:9000` 查看: 1. **仪表盘**:项目健康度评分 2. **问题列表**: - 漏洞:`Division by zero` - 代码异味:`Add error handling` 3. **安全热点**:敏感操作标记 #### 八、自定义规则(示例) 创建自定义规则文件 `custom-rules.xml`: ```xml <profile> <name>My Python Rules</name> <language>py</language> <rule> <repositoryKey>python</repositoryKey> <key>S5659</key> <!-- 日志注入检查 --> <priority>CRITICAL</priority> </rule> <rule> <repositoryKey>python</repositoryKey> <key>S1313</key> <!-- 硬编码IP检查 --> <priority>MAJOR</priority> </rule> </profile> ``` 通过Web界面导入:**质量配置 → 创建 → 导入** ### 常见问题解决 1. **启动失败:端口冲突** ```batch netstat -ano | findstr :9000 taskkill /PID <占用PID> /F ``` 2. **扫描时卡住** 编辑 `C:\SonarQube\conf\wrapper.conf`: ```conf wrapper.java.additional.1=-Djava.io.tmpdir=C:/SonarQube/temp ``` 3. **插件兼容问题** 删除不兼容插件(日志文件提示): ```batch del C:\SonarQube\extensions\plugins\<问题插件>.jar ``` ### 离线维护建议 1. **定期备份**:`C:\SonarQube\data` 2. **插件更新**:在有网络环境下载新版插件后覆盖安装 3. **数据库清理**:通过Web界面 → **Administration → Projects → Manage Projects** 删除旧项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mosquito_lover1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值