Menu

7/28/25

Code app xem phần cứng máy tính với python và gemini - AI

 

B1. Script cho AI thực hiện gen mã nguồn Python.

mình đang dùng python 3.13.5 hãy viết cho tôi 1 phần mềm đọc thông tin phần cứng máy tính có giao diện đồ họa, mã nguồn nằm trong 1 file .py duy nhất, Phần mềm sẽ sử dụng SQLite làm cơ sở dữ liệu , có thể chạy được luôn, dễ dàng nâng cấp sau này để trở thành 1 tab của phần mềm lớn khác

B2. Sau khi cài xong python mới nhất: 3.13.5 thì chạy các lệnh sau trong cmd để tải package thư viện hỗ trợ xem thông tin phần cứng máy tính về:

C:\Windows\System32>pip install psutil

C:\Windows\System32>pip install wmi

C:\Windows\System32>pip install py-cpuinfo

B3. Code do gemini tạo mình save thành file hardware_monitor.py ròi chạy trong cmd:

d:\>py -3 hardware_monitor.py



import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
import platform
import psutil
import wmi # Chỉ dành cho Windows
import cpuinfo
import socket # Import thư viện socket để dùng AF_INET

class HardwareInfoApp:
    def __init__(self, master):
        self.master = master
        master.title("Thông tin phần cứng máy tính")
        master.geometry("800x600")

        self.db_name = "hardware_info.db"
        self.create_database()

        self.create_widgets()
        self.load_hardware_info()

    def create_database(self):
        conn = sqlite3.connect(self.db_name)
        cursor = conn.cursor()
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS hardware_data (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                category TEXT,
                item TEXT,
                value TEXT
            )
        """)
        conn.commit()
        conn.close()

    def create_widgets(self):
        # Notebook for tabs
        self.notebook = ttk.Notebook(self.master)
        self.notebook.pack(expand=True, fill="both", padx=10, pady=10)

        # Tab 1: System Info
        self.system_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.system_frame, text="Hệ thống")
        self.create_system_info_widgets(self.system_frame)

        # Tab 2: CPU Info
        self.cpu_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.cpu_frame, text="CPU")
        self.create_cpu_info_widgets(self.cpu_frame)

        # Tab 3: Memory Info
        self.memory_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.memory_frame, text="RAM")
        self.create_memory_info_widgets(self.memory_frame)

        # Tab 4: Disk Info
        self.disk_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.disk_frame, text="Ổ đĩa")
        self.create_disk_info_widgets(self.disk_frame)

        # Tab 5: Network Info
        self.network_frame = ttk.Frame(self.notebook)
        self.notebook.add(self.network_frame, text="Mạng")
        self.create_network_info_widgets(self.network_frame)

        # Tab 6: GPU Info (Windows only)
        # Chỉ tạo tab GPU nếu hệ điều hành là Windows để tránh lỗi import wmi trên Linux/macOS
        if platform.system() == "Windows":
            self.gpu_frame = ttk.Frame(self.notebook)
            self.notebook.add(self.gpu_frame, text="GPU")
            self.create_gpu_info_widgets(self.gpu_frame)


        # Buttons
        button_frame = ttk.Frame(self.master)
        button_frame.pack(pady=5)

        self.refresh_button = ttk.Button(button_frame, text="Làm mới", command=self.load_hardware_info)
        self.refresh_button.pack(side="left", padx=5)

        self.save_button = ttk.Button(button_frame, text="Lưu vào DB", command=self.save_all_info_to_db)
        self.save_button.pack(side="left", padx=5)

    def create_system_info_widgets(self, parent_frame):
        self.system_info_tree = ttk.Treeview(parent_frame, columns=("Item", "Value"), show="headings")
        self.system_info_tree.heading("Item", text="Mục")
        self.system_info_tree.heading("Value", text="Giá trị")
        self.system_info_tree.pack(expand=True, fill="both")

        vsb = ttk.Scrollbar(parent_frame, orient="vertical", command=self.system_info_tree.yview)
        vsb.pack(side='right', fill='y')
        self.system_info_tree.configure(yscrollcommand=vsb.set)

    def create_cpu_info_widgets(self, parent_frame):
        self.cpu_info_tree = ttk.Treeview(parent_frame, columns=("Item", "Value"), show="headings")
        self.cpu_info_tree.heading("Item", text="Mục")
        self.cpu_info_tree.heading("Value", text="Giá trị")
        self.cpu_info_tree.pack(expand=True, fill="both")

        vsb = ttk.Scrollbar(parent_frame, orient="vertical", command=self.cpu_info_tree.yview)
        vsb.pack(side='right', fill='y')
        self.cpu_info_tree.configure(yscrollcommand=vsb.set)

    def create_memory_info_widgets(self, parent_frame):
        self.memory_info_tree = ttk.Treeview(parent_frame, columns=("Item", "Value"), show="headings")
        self.memory_info_tree.heading("Item", text="Mục")
        self.memory_info_tree.heading("Value", text="Giá trị")
        self.memory_info_tree.pack(expand=True, fill="both")

        vsb = ttk.Scrollbar(parent_frame, orient="vertical", command=self.memory_info_tree.yview)
        vsb.pack(side='right', fill='y')
        self.memory_info_tree.configure(yscrollcommand=vsb.set)

    def create_disk_info_widgets(self, parent_frame):
        self.disk_info_tree = ttk.Treeview(parent_frame, columns=("Device", "Mountpoint", "File System", "Size", "Used", "Free", "Percent"), show="headings")
        self.disk_info_tree.heading("Device", text="Thiết bị")
        self.disk_info_tree.heading("Mountpoint", text="Điểm gắn kết")
        self.disk_info_tree.heading("File System", text="Hệ thống tệp")
        self.disk_info_tree.heading("Size", text="Tổng dung lượng")
        self.disk_info_tree.heading("Used", text="Đã dùng")
        self.disk_info_tree.heading("Free", text="Còn trống")
        self.disk_info_tree.heading("Percent", text="Phần trăm")
        self.disk_info_tree.pack(expand=True, fill="both")

        vsb = ttk.Scrollbar(parent_frame, orient="vertical", command=self.disk_info_tree.yview)
        vsb.pack(side='right', fill='y')
        self.disk_info_tree.configure(yscrollcommand=vsb.set)

    def create_network_info_widgets(self, parent_frame):
        self.network_info_tree = ttk.Treeview(parent_frame, columns=("Interface", "IP Address", "Netmask", "MAC Address"), show="headings")
        self.network_info_tree.heading("Interface", text="Giao diện")
        self.network_info_tree.heading("IP Address", text="Địa chỉ IP")
        self.network_info_tree.heading("Netmask", text="Netmask")
        self.network_info_tree.heading("MAC Address", text="Địa chỉ MAC")
        self.network_info_tree.pack(expand=True, fill="both")

        vsb = ttk.Scrollbar(parent_frame, orient="vertical", command=self.network_info_tree.yview)
        vsb.pack(side='right', fill='y')
        self.network_info_tree.configure(yscrollcommand=vsb.set)

    def create_gpu_info_widgets(self, parent_frame):
        self.gpu_info_tree = ttk.Treeview(parent_frame, columns=("Property", "Value"), show="headings")
        self.gpu_info_tree.heading("Property", text="Thuộc tính")
        self.gpu_info_tree.heading("Value", text="Giá trị")
        self.gpu_info_tree.pack(expand=True, fill="both")

        vsb = ttk.Scrollbar(parent_frame, orient="vertical", command=self.gpu_info_tree.yview)
        vsb.pack(side='right', fill='y')
        self.gpu_info_tree.configure(yscrollcommand=vsb.set)

    def load_hardware_info(self):
        self.clear_trees()
        self.get_system_info()
        self.get_cpu_info()
        self.get_memory_info()
        self.get_disk_info()
        self.get_network_info()
        if platform.system() == "Windows": # Chỉ gọi nếu chạy trên Windows
            self.get_gpu_info()

    def clear_trees(self):
        for i in self.system_info_tree.get_children():
            self.system_info_tree.delete(i)
        for i in self.cpu_info_tree.get_children():
            self.cpu_info_tree.delete(i)
        for i in self.memory_info_tree.get_children():
            self.memory_info_tree.delete(i)
        for i in self.disk_info_tree.get_children():
            self.disk_info_tree.delete(i)
        for i in self.network_info_tree.get_children():
            self.network_info_tree.delete(i)
        if platform.system() == "Windows": # Chỉ xóa nếu tab GPU tồn tại
            for i in self.gpu_info_tree.get_children():
                self.gpu_info_tree.delete(i)

    def get_system_info(self):
        info = {
            "Hệ điều hành": platform.system(),
            "Phiên bản HĐH": platform.version(),
            "Kiến trúc": platform.machine(),
            "Tên máy tính": platform.node(),
            "Nền tảng": platform.platform(),
            "Phiên bản Python": platform.python_version(),
        }
        for item, value in info.items():
            self.system_info_tree.insert("", "end", values=(item, value))

    def get_cpu_info(self):
        cpu_data = cpuinfo.get_cpu_info()
        self.cpu_info_tree.insert("", "end", values=("Tên CPU", cpu_data.get('brand_original', 'N/A')))
        self.cpu_info_tree.insert("", "end", values=("Kiến trúc", cpu_data.get('arch', 'N/A')))
        self.cpu_info_tree.insert("", "end", values=("Số lõi vật lý", psutil.cpu_count(logical=False)))
        self.cpu_info_tree.insert("", "end", values=("Số luồng (lõi ảo)", psutil.cpu_count(logical=True)))
        
        # Lấy tần số CPU, xử lý trường hợp không có dữ liệu
        cpu_freq = psutil.cpu_freq()
        if cpu_freq:
            self.cpu_info_tree.insert("", "end", values=("Tần số tối đa", f"{cpu_freq.max:.2f} Mhz"))
            self.cpu_info_tree.insert("", "end", values=("Tần số hiện tại", f"{cpu_freq.current:.2f} Mhz"))
        else:
            self.cpu_info_tree.insert("", "end", values=("Tần số tối đa", "N/A"))
            self.cpu_info_tree.insert("", "end", values=("Tần số hiện tại", "N/A"))

        self.cpu_info_tree.insert("", "end", values=("Sử dụng CPU", f"{psutil.cpu_percent(interval=1)}%"))

    def get_memory_info(self):
        svmem = psutil.virtual_memory()
        self.memory_info_tree.insert("", "end", values=("Tổng RAM", self.bytes_to_gb(svmem.total)))
        self.memory_info_tree.insert("", "end", values=("RAM đã dùng", self.bytes_to_gb(svmem.used)))
        self.memory_info_tree.insert("", "end", values=("RAM còn trống", self.bytes_to_gb(svmem.available)))
        self.memory_info_tree.insert("", "end", values=("Phần trăm sử dụng", f"{svmem.percent}%"))

        swap = psutil.swap_memory()
        self.memory_info_tree.insert("", "end", values=("Tổng bộ nhớ ảo (Swap)", self.bytes_to_gb(swap.total)))
        self.memory_info_tree.insert("", "end", values=("Đã dùng bộ nhớ ảo (Swap)", self.bytes_to_gb(swap.used)))
        self.memory_info_tree.insert("", "end", values=("Còn trống bộ nhớ ảo (Swap)", self.bytes_to_gb(swap.free)))
        self.memory_info_tree.insert("", "end", values=("Phần trăm sử dụng bộ nhớ ảo (Swap)", f"{swap.percent}%"))


    def get_disk_info(self):
        partitions = psutil.disk_partitions()
        for p in partitions:
            try:
                usage = psutil.disk_usage(p.mountpoint)
                self.disk_info_tree.insert("", "end", values=(
                    p.device,
                    p.mountpoint,
                    p.fstype,
                    self.bytes_to_gb(usage.total),
                    self.bytes_to_gb(usage.used),
                    self.bytes_to_gb(usage.free),
                    f"{usage.percent}%"
                ))
            except PermissionError:
                # Some partitions might not be accessible
                self.disk_info_tree.insert("", "end", values=(p.device, p.mountpoint, p.fstype, "N/A", "N/A", "N/A", "N/A"))
            except Exception as e:
                # Catch other potential errors
                self.disk_info_tree.insert("", "end", values=(p.device, p.mountpoint, p.fstype, "Lỗi", "Lỗi", "Lỗi", f"({e})"))


    def get_network_info(self):
        net_if_addrs = psutil.net_if_addrs()
        for interface_name, addresses in net_if_addrs.items():
            ip_address = "N/A"
            netmask = "N/A"
            mac_address = "N/A"
            for address in addresses:
                # Sử dụng socket.AF_INET thay vì psutil.AF_INET để tương thích tốt hơn
                if address.family == socket.AF_INET:  # IPv4
                    ip_address = address.address
                    netmask = address.netmask
                # psutil.AF_LINK hoạt động tốt hơn với psutil 
                elif address.family == psutil.AF_LINK:  # MAC Address
                    mac_address = address.address
            self.network_info_tree.insert("", "end", values=(interface_name, ip_address, netmask, mac_address))

    def get_gpu_info(self):
        if platform.system() == "Windows":
            try:
                c = wmi.WMI()
                found_gpu = False
                for gpu in c.Win32_VideoController():
                    found_gpu = True
                    self.gpu_info_tree.insert("", "end", values=("Tên card", gpu.Name))
                    
                    # Kiểm tra và chuyển đổi AdapterRAM nếu có
                    if hasattr(gpu, 'AdapterRAM') and gpu.AdapterRAM is not None:
                        self.gpu_info_tree.insert("", "end", values=("Bộ nhớ RAM", self.bytes_to_gb(gpu.AdapterRAM)))
                    else:
                        self.gpu_info_tree.insert("", "end", values=("Bộ nhớ RAM", "N/A"))

                    self.gpu_info_tree.insert("", "end", values=("Trạng thái", gpu.Status if hasattr(gpu, 'Status') else "N/A"))
                    
                    # Kiểm tra và hiển thị độ phân giải
                    if hasattr(gpu, 'CurrentHorizontalResolution') and hasattr(gpu, 'CurrentVerticalResolution') and \
                       gpu.CurrentHorizontalResolution is not None and gpu.CurrentVerticalResolution is not None:
                        self.gpu_info_tree.insert("", "end", values=("Độ phân giải", f"{gpu.CurrentHorizontalResolution}x{gpu.CurrentVerticalResolution}"))
                    else:
                        self.gpu_info_tree.insert("", "end", values=("Độ phân giải", "N/A"))

                    self.gpu_info_tree.insert("", "end", values=("Bộ xử lý video", gpu.VideoProcessor if hasattr(gpu, 'VideoProcessor') else "N/A"))
                    # Thêm một dòng trống để phân tách các GPU nếu có nhiều hơn 1
                    self.gpu_info_tree.insert("", "end", values=("", "")) 
                
                if not found_gpu:
                    self.gpu_info_tree.insert("", "end", values=("Không tìm thấy GPU", "Thông tin có thể không có sẵn hoặc cần driver"))

            except Exception as e:
                self.gpu_info_tree.insert("", "end", values=("Lỗi đọc GPU", str(e)))
        else:
            self.gpu_info_tree.insert("", "end", values=("Không hỗ trợ", "Chỉ hỗ trợ Windows"))

    def bytes_to_gb(self, bytes_val):
        if bytes_val is None:
            return "N/A"
        return f"{bytes_val / (1024**3):.2f} GB"

    def save_info_to_db(self, category, treeview):
        conn = sqlite3.connect(self.db_name)
        cursor = conn.cursor()
        for item in treeview.get_children():
            values = treeview.item(item, 'values')
            if len(values) >= 2: # Ensure there are at least "Item" and "Value"
                item_name = values[0]
                item_value = values[1]
                cursor.execute("INSERT INTO hardware_data (category, item, value) VALUES (?, ?, ?)",
                               (category, item_name, item_value))
            else: # Handle cases like disk info with multiple columns
                if category == "Ổ đĩa":
                    device = values[0] if len(values) > 0 else "N/A"
                    details = ", ".join(map(str, values[1:])) if len(values) > 1 else ""
                    cursor.execute("INSERT INTO hardware_data (category, item, value) VALUES (?, ?, ?)",
                                   (category, device, details))
                elif category == "Mạng":
                    interface = values[0] if len(values) > 0 else "N/A"
                    details = ", ".join(map(str, values[1:])) if len(values) > 1 else ""
                    cursor.execute("INSERT INTO hardware_data (category, item, value) VALUES (?, ?, ?)",
                                   (category, interface, details))
                elif category == "GPU":
                    prop = values[0] if len(values) > 0 else "N/A"
                    val = values[1] if len(values) > 1 else "N/A"
                    cursor.execute("INSERT INTO hardware_data (category, item, value) VALUES (?, ?, ?)",
                                   (category, prop, val))

        conn.commit()
        conn.close()

    def save_all_info_to_db(self):
        conn = sqlite3.connect(self.db_name)
        cursor = conn.cursor()
        cursor.execute("DELETE FROM hardware_data") # Clear existing data
        conn.commit()
        conn.close()

        self.save_info_to_db("Hệ thống", self.system_info_tree)
        self.save_info_to_db("CPU", self.cpu_info_tree)
        self.save_info_to_db("RAM", self.memory_info_tree)
        self.save_info_to_db("Ổ đĩa", self.disk_info_tree)
        self.save_info_to_db("Mạng", self.network_info_tree)
        if platform.system() == "Windows":
            self.save_info_to_db("GPU", self.gpu_info_tree)
        messagebox.showinfo("Lưu thông tin", "Thông tin phần cứng đã được lưu vào cơ sở dữ liệu thành công!")

# Cách chạy ứng dụng
if __name__ == "__main__":
    root = tk.Tk()
    app = HardwareInfoApp(root)
    root.mainloop()

No comments:

Post a Comment