最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Python編寫windows電腦用戶操作記錄查看器

 更新時(shí)間:2025年02月06日 16:27:59   作者:mosquito_lover1  
這篇文章主要為大家詳細(xì)介紹了如何基于Python編寫一個(gè)windows電腦用戶操作記錄查看器,可以讀取系統(tǒng)現(xiàn)有的日志記錄用戶,感興趣的小伙伴可以了解下

軟件功能

讀取系統(tǒng)現(xiàn)有的日志記錄:

Windows系統(tǒng)事件日志

最近訪問的文件記錄

程序安裝和執(zhí)行記錄

刷新日志、搜索記錄、刪除選中記錄

軟件截圖

核心源碼

import tkinter as tk
from tkinter import ttk, messagebox
import os
import winreg
from datetime import datetime
from win32com.shell import shell, shellcon
import win32api
import win32con
import win32evtlog
import win32evtlogutil
import win32file
import struct
from ctypes import *
import sys
import ctypes
 
def is_admin():
    """檢查是否具有管理員權(quán)限"""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False
 
class PCActivityMonitor:
    def __init__(self, root):
        self.root = root
        self.root.title("用戶操作記錄查看器")
        self.root.geometry("1200x800")
        
        # 檢查管理員權(quán)限
        if not is_admin():
            messagebox.showwarning("警告", 
                "程序未以管理員權(quán)限運(yùn)行,某些功能可能受限。\n"
                "建議以管理員身份重新運(yùn)行程序以獲取完整功能。")
        
        # 創(chuàng)建主框架
        self.main_frame = ttk.Frame(root)
        self.main_frame.pack(expand=True, fill="both", padx=5, pady=5)
        
        # 創(chuàng)建工具欄
        self.create_toolbar()
        
        # 創(chuàng)建Treeview
        self.create_treeview()
        
        # 初始加載數(shù)據(jù)
        self.load_all_logs()
 
    def create_toolbar(self):
        """創(chuàng)建工具欄"""
        toolbar = ttk.Frame(self.main_frame)
        toolbar.pack(fill="x", padx=5, pady=5)
        
        # 刷新按鈕
        ttk.Button(toolbar, text="刷新", command=self.load_all_logs).pack(side="left", padx=5)
        
        # 刪除按鈕
        ttk.Button(toolbar, text="刪除選中記錄", command=self.delete_selected).pack(side="left", padx=5)
        
        # 導(dǎo)出按鈕
        ttk.Button(toolbar, text="導(dǎo)出記錄", command=self.export_logs).pack(side="left", padx=5)
        
        # 搜索框
        ttk.Label(toolbar, text="搜索:").pack(side="left", padx=5)
        self.search_var = tk.StringVar()
        ttk.Entry(toolbar, textvariable=self.search_var, width=30).pack(side="left", padx=5)
        ttk.Button(toolbar, text="搜索", command=self.search_logs).pack(side="left", padx=5)
        ttk.Button(toolbar, text="清除搜索", command=self.clear_search).pack(side="left", padx=5)
 
    def create_treeview(self):
        """創(chuàng)建Treeview控件"""
        frame = ttk.Frame(self.main_frame)
        frame.pack(expand=True, fill="both")
        
        # 創(chuàng)建Treeview和滾動(dòng)條
        self.tree = ttk.Treeview(frame, columns=("time", "action", "object", "path"), show="headings")
        
        # 設(shè)置列標(biāo)題
        self.tree.heading("time", text="操作時(shí)間", command=lambda: self.treeview_sort_column("time", False))
        self.tree.heading("action", text="操作類型", command=lambda: self.treeview_sort_column("action", False))
        self.tree.heading("object", text="操作對(duì)象", command=lambda: self.treeview_sort_column("object", False))
        self.tree.heading("path", text="完整路徑", command=lambda: self.treeview_sort_column("path", False))
        
        # 設(shè)置列寬
        self.tree.column("time", width=150)
        self.tree.column("action", width=100)
        self.tree.column("object", width=250)
        self.tree.column("path", width=400)
        
        # 添加滾動(dòng)條
        y_scrollbar = ttk.Scrollbar(frame, orient="vertical", command=self.tree.yview)
        x_scrollbar = ttk.Scrollbar(frame, orient="horizontal", command=self.tree.xview)
        self.tree.configure(yscrollcommand=y_scrollbar.set, xscrollcommand=x_scrollbar.set)
        
        # 布局
        self.tree.pack(side="left", fill="both", expand=True)
        y_scrollbar.pack(side="right", fill="y")
        x_scrollbar.pack(side="bottom", fill="x")
        
        # 綁定右鍵菜單
        self.tree.bind("<Button-3>", self.show_context_menu)
        
        # 綁定雙擊事件
        self.tree.bind("<Double-1>", self.on_double_click)
 
    def load_all_logs(self):
        """加載所有日志記錄"""
        self.tree.delete(*self.tree.get_children())
        
        # 創(chuàng)建臨時(shí)列表存儲(chǔ)所有記錄
        all_records = []
        
        # 獲取文件訪問記錄
        all_records.extend(self.get_file_access_logs())
        
        # 獲取程序執(zhí)行記錄
        all_records.extend(self.get_program_execution_logs())
        
        # 獲取應(yīng)用程序日志
        all_records.extend(self.get_application_logs())
        
        # 按時(shí)間倒序排序
        all_records.sort(key=lambda x: x[0], reverse=True)
        
        # 插入排序后的記錄
        for record in all_records:
            self.tree.insert("", "end", values=record)
 
    def get_file_access_logs(self):
        """獲取文件訪問記錄"""
        records = []
        try:
            # 讀取最近訪問文件
            recent_path = os.path.join(os.environ['USERPROFILE'], 
                                     'AppData\\Roaming\\Microsoft\\Windows\\Recent')
            for file in os.listdir(recent_path):
                if file.endswith('.lnk'):
                    file_path = os.path.join(recent_path, file)
                    access_time = datetime.fromtimestamp(os.path.getatime(file_path))
                    
                    try:
                        shortcut = shell.SHCreateItemFromParsingName(
                            file_path, None, shell.IID_IShellItem
                        )
                        target_path = shortcut.GetDisplayName(shellcon.SIGDN_FILESYSPATH)
                        
                        records.append((
                            access_time.strftime("%Y-%m-%d %H:%M:%S"),
                            "文件訪問",
                            file[:-4],
                            target_path
                        ))
                    except:
                        continue
                        
            # 讀取Office文檔記錄
            office_path = os.path.join(os.environ['APPDATA'], 
                                     'Microsoft\\Office\\Recent')
            if os.path.exists(office_path):
                for file in os.listdir(office_path):
                    if file.endswith('.lnk'):
                        file_path = os.path.join(office_path, file)
                        access_time = datetime.fromtimestamp(os.path.getatime(file_path))
                        records.append((
                            access_time.strftime("%Y-%m-%d %H:%M:%S"),
                            "Office文檔",
                            file[:-4],
                            file_path
                        ))
                        
        except Exception as e:
            messagebox.showerror("錯(cuò)誤", f"讀取文件訪問記錄出錯(cuò): {str(e)}")
            
        return records
 
    def get_program_execution_logs(self):
        """獲取程序執(zhí)行記錄"""
        records = []
        try:
            key_paths = [
                (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"),
                (winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
            ]
            
            for hkey, key_path in key_paths:
                try:
                    with winreg.OpenKey(hkey, key_path, 0, 
                                      winreg.KEY_READ | winreg.KEY_WOW64_64KEY) as key:
                        for i in range(winreg.QueryInfoKey(key)[0]):
                            try:
                                subkey_name = winreg.EnumKey(key, i)
                                with winreg.OpenKey(key, subkey_name) as subkey:
                                    try:
                                        display_name = winreg.QueryValueEx(subkey, "DisplayName")[0]
                                        install_date = winreg.QueryValueEx(subkey, "InstallDate")[0]
                                        install_location = winreg.QueryValueEx(subkey, "InstallLocation")[0]
                                        
                                        date_obj = datetime.strptime(install_date, "%Y%m%d")
                                        
                                        records.append((
                                            date_obj.strftime("%Y-%m-%d %H:%M:%S"),
                                            "軟件安裝",
                                            display_name,
                                            install_location
                                        ))
                                    except:
                                        continue
                            except:
                                continue
                except:
                    continue
                    
        except Exception as e:
            messagebox.showerror("錯(cuò)誤", f"讀取程序執(zhí)行記錄出錯(cuò): {str(e)}")
            
        return records
 
    def get_application_logs(self):
        """獲取應(yīng)用程序日志"""
        records = []
        try:
            hand = win32evtlog.OpenEventLog(None, "Application")
            flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
            
            events = win32evtlog.ReadEventLog(hand, flags, 0)
            for event in events:
                if event.EventType in [win32evtlog.EVENTLOG_AUDIT_SUCCESS]:
                    records.append((
                        event.TimeGenerated.Format(),
                        "程序執(zhí)行",
                        event.SourceName,
                        "用戶操作記錄"
                    ))
        except:
            pass
            
        return records
 
    def load_file_system_journal(self):
        """讀取文件系統(tǒng)日志"""
        if not is_admin():
            print("需要管理員權(quán)限才能讀取文件系統(tǒng)日志")
            return
            
        try:
            drives = self.get_system_drives()
            for drive in drives:
                try:
                    # 檢查驅(qū)動(dòng)器類型
                    drive_type = win32file.GetDriveType(drive + "\\")
                    if drive_type != win32file.DRIVE_FIXED:
                        continue  # 跳過非固定磁盤
                        
                    # 嘗試啟用USN日志
                    self.enable_usn_journal(drive)
                    # 讀取USN日志
                    self.read_usn_journal(drive)
                except Exception as e:
                    print(f"處理驅(qū)動(dòng)器 {drive} 時(shí)出錯(cuò): {str(e)}")
                    continue
        except Exception as e:
            print(f"讀取文件系統(tǒng)日志出錯(cuò): {str(e)}")
 
    def get_system_drives(self):
        """獲取系統(tǒng)所有驅(qū)動(dòng)器"""
        drives = []
        bitmask = win32api.GetLogicalDrives()
        for letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
            if bitmask & 1:
                drives.append(f'{letter}:')
            bitmask >>= 1
        return drives
 
    def read_usn_journal(self, drive):
        """讀取USN日志"""
        try:
            # 打開驅(qū)動(dòng)器
            handle = win32file.CreateFile(
                f"\\\\.\\{drive}",
                win32con.GENERIC_READ | win32con.GENERIC_WRITE,
                win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
                None,
                win32con.OPEN_EXISTING,
                0,
                None
            )
 
            # 獲取USN日志信息
            if handle == win32file.INVALID_HANDLE_VALUE:
                return
 
            # 定義USN日志數(shù)據(jù)結(jié)構(gòu)
            class USN_JOURNAL_DATA(Structure):
                _fields_ = [
                    ("UsnJournalID", c_ulonglong),
                    ("FirstUsn", c_ulonglong),
                    ("NextUsn", c_ulonglong),
                    ("LowestValidUsn", c_ulonglong),
                    ("MaxUsn", c_ulonglong),
                    ("MaximumSize", c_ulonglong),
                    ("AllocationDelta", c_ulonglong),
                ]
 
            # 獲取USN日志信息
            buf = win32file.DeviceIoControl(
                handle,
                win32file.FSCTL_QUERY_USN_JOURNAL,
                None,
                sizeof(USN_JOURNAL_DATA),
                None
            )
 
            journal_data = USN_JOURNAL_DATA()
            memmove(byref(journal_data), buf, sizeof(journal_data))
 
            # 讀取最近的USN記錄
            read_data = struct.pack("QQI", journal_data.FirstUsn, journal_data.NextUsn, 0)
            data = win32file.DeviceIoControl(
                handle,
                win32file.FSCTL_READ_USN_JOURNAL,
                read_data,
                8192,
                None
            )
 
            # 解析USN記錄
            usn_records = self.parse_usn_records(data)
            
            # 添加到界面
            for record in usn_records:
                if record['reason'] & win32file.USN_REASON_FILE_DELETE:
                    self.tree.insert("", 0, values=(
                        record['time'].strftime("%Y-%m-%d %H:%M:%S"),
                        "文件刪除",
                        record['filename'],
                        f"{drive}\\{record['filepath']}"
                    ))
 
            win32file.CloseHandle(handle)
 
        except Exception as e:
            print(f"讀取USN日志出錯(cuò) {drive}: {str(e)}")
 
    def parse_usn_records(self, data):
        """解析USN記錄"""
        records = []
        offset = 0
        while offset < len(data):
            # 解析記錄頭
            record_length = struct.unpack_from("I", data, offset)[0]
            if record_length == 0:
                break
 
            # 解析文件名
            filename_offset = struct.unpack_from("H", data, offset + 56)[0]
            filename_length = struct.unpack_from("H", data, offset + 58)[0]
            filename = data[offset + filename_offset:offset + filename_offset + filename_length].decode('utf-16')
 
            # 獲取時(shí)間戳
            timestamp = struct.unpack_from("Q", data, offset + 48)[0]
            time = datetime.fromtimestamp((timestamp - 116444736000000000) // 10000000)
 
            # 獲取原因
            reason = struct.unpack_from("I", data, offset + 40)[0]
 
            # 獲取文件引用號(hào)
            file_ref = struct.unpack_from("Q", data, offset + 8)[0]
 
            records.append({
                'filename': filename,
                'filepath': self.get_file_path(file_ref),
                'time': time,
                'reason': reason
            })
 
            offset += record_length
 
        return records
 
    def get_file_path(self, file_ref):
        """獲取文件路徑"""
        try:
            return "Unknown Path"  # 實(shí)際實(shí)現(xiàn)需要更復(fù)雜的邏輯
        except:
            return "Unknown Path"
 
    def treeview_sort_column(self, col, reverse):
        """排序表格列"""
        l = [(self.tree.set(k, col), k) for k in self.tree.get_children('')]
        l.sort(reverse=reverse)
        
        # 重新排列項(xiàng)目
        for index, (val, k) in enumerate(l):
            self.tree.move(k, '', index)
        
        # 切換排序方向
        self.tree.heading(col, command=lambda: self.treeview_sort_column(col, not reverse))
 
    def on_double_click(self, event):
        """雙擊打開文件或目錄"""
        item = self.tree.selection()[0]
        path = self.tree.item(item)['values'][3]
        try:
            os.startfile(path)
        except:
            pass
 
    def export_logs(self):
        """導(dǎo)出日志記錄"""
        try:
            with open('user_activities.csv', 'w', encoding='utf-8') as f:
                # 寫入表頭
                f.write("操作時(shí)間,操作類型,操作對(duì)象,完整路徑\n")
                
                # 寫入數(shù)據(jù)
                for item in self.tree.get_children():
                    values = self.tree.item(item)['values']
                    f.write(f"{values[0]},{values[1]},{values[2]},{values[3]}\n")
                    
            messagebox.showinfo("成功", "日志已導(dǎo)出到 user_activities.csv")
        except Exception as e:
            messagebox.showerror("錯(cuò)誤", f"導(dǎo)出日志失敗: {str(e)}")
 
    def clear_search(self):
        """清除搜索結(jié)果"""
        self.search_var.set("")
        self.tree.selection_remove(*self.tree.selection())
 
    def delete_selected(self):
        """刪除選中的記錄"""
        selected = self.tree.selection()
        if not selected:
            messagebox.showwarning("警告", "請(qǐng)先選擇要?jiǎng)h除的記錄")
            return
            
        if messagebox.askyesno("確認(rèn)", "確定要?jiǎng)h除選中的記錄嗎?"):
            for item in selected:
                self.tree.delete(item)
 
    def search_logs(self):
        """搜索日志"""
        search_text = self.search_var.get().lower()
        if not search_text:
            return
            
        for item in self.tree.get_children():
            values = self.tree.item(item)['values']
            if any(search_text in str(value).lower() for value in values):
                self.tree.selection_add(item)
            else:
                self.tree.selection_remove(item)
 
    def show_context_menu(self, event):
        """顯示右鍵菜單"""
        menu = tk.Menu(self.root, tearoff=0)
        menu.add_command(label="復(fù)制", command=self.copy_selected)
        menu.add_command(label="刪除", command=self.delete_selected)
        menu.post(event.x_root, event.y_root)
 
    def copy_selected(self):
        """復(fù)制選中的記錄到剪貼板"""
        selected = self.tree.selection()
        if not selected:
            return
            
        text = ""
        for item in selected:
            values = self.tree.item(item)['values']
            text += "\t".join(str(v) for v in values) + "\n"
            
        self.root.clipboard_clear()
        self.root.clipboard_append(text)
 
    def enable_usn_journal(self, drive):
        """啟用USN日志"""
        try:
            handle = win32file.CreateFile(
                f"\\\\.\\{drive}",
                win32con.GENERIC_READ | win32con.GENERIC_WRITE,
                win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
                None,
                win32con.OPEN_EXISTING,
                0,
                None
            )
            
            if handle == win32file.INVALID_HANDLE_VALUE:
                return False
                
            try:
                # 啟用USN日志
                win32file.DeviceIoControl(
                    handle,
                    win32file.FSCTL_CREATE_USN_JOURNAL,
                    struct.pack("QQ", 0, 0),
                    None,
                    None
                )
                return True
            finally:
                win32file.CloseHandle(handle)
        except:
            return False
 
def main():
    # 如果不是管理員權(quán)限,則請(qǐng)求提升權(quán)限
    if not is_admin():
        ctypes.windll.shell32.ShellExecuteW(
            None, "runas", sys.executable, " ".join(sys.argv), None, 1)
        sys.exit()
 
    root = tk.Tk()
    app = PCActivityMonitor(root)
    root.mainloop()
 
if __name__ == "__main__":
    main() 

到此這篇關(guān)于基于Python編寫windows電腦用戶操作記錄查看器的文章就介紹到這了,更多相關(guān)Python電腦操作記錄查看器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python與Java進(jìn)行交互操作的方法與性能對(duì)比

    Python與Java進(jìn)行交互操作的方法與性能對(duì)比

    這篇文章主要為大家詳細(xì)介紹了Python與Java進(jìn)行交互操作的相關(guān)方法,包括子進(jìn)程調(diào)用,JPype,Py4J和REST/gRPC,并進(jìn)行了性能對(duì)比,感興趣的小伙伴可以了解下
    2025-04-04
  • Python操作Oracle數(shù)據(jù)庫(kù)的簡(jiǎn)單方法和封裝類實(shí)例

    Python操作Oracle數(shù)據(jù)庫(kù)的簡(jiǎn)單方法和封裝類實(shí)例

    這篇文章主要介紹了Python操作Oracle數(shù)據(jù)庫(kù)的簡(jiǎn)單方法和封裝類,結(jié)合實(shí)例形式分析了Python簡(jiǎn)單連接、查詢、關(guān)閉Oracle數(shù)據(jù)庫(kù)基本操作,并給出了一個(gè)Python針對(duì)Oracle各種操作的封裝類,需要的朋友可以參考下
    2018-05-05
  • pip?install?jupyterlab失敗的原因問題及探索

    pip?install?jupyterlab失敗的原因問題及探索

    在學(xué)習(xí)Yolo模型時(shí),嘗試安裝JupyterLab但遇到錯(cuò)誤,錯(cuò)誤提示缺少Rust和Cargo編譯環(huán)境,因?yàn)閜ywinpty包需要它們來(lái)編譯,由于在conda環(huán)境下操作,Rust和Cargo已經(jīng)安裝,問題是pywinpty包丟失,安裝pywinpty包后,再次執(zhí)行pip?install?jupyterlab即可正常下載
    2025-02-02
  • Python輕松實(shí)現(xiàn)查找高亮Excel指定數(shù)據(jù)

    Python輕松實(shí)現(xiàn)查找高亮Excel指定數(shù)據(jù)

    在日常工作中,Excel表格無(wú)疑是我們處理數(shù)據(jù)最常用的工具之一,本文將深入探討如何利用 Free Spire.XLS for Python 免費(fèi)庫(kù)完成這一任務(wù),讓你的數(shù)據(jù)處理工作效率倍增,希望對(duì)大家有所幫助
    2025-11-11
  • 詳解Python中的靜態(tài)方法與類成員方法

    詳解Python中的靜態(tài)方法與類成員方法

    這篇文章主要介紹了關(guān)于Python中靜態(tài)方法與類成員的相關(guān)資料,文中通過示例代碼給大家詳細(xì)總結(jié)了兩者在語(yǔ)法和使用上的區(qū)別,有需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-02-02
  • Python實(shí)現(xiàn)自動(dòng)訪問網(wǎng)頁(yè)的例子

    Python實(shí)現(xiàn)自動(dòng)訪問網(wǎng)頁(yè)的例子

    今天小編就為大家分享一篇Python實(shí)現(xiàn)自動(dòng)訪問網(wǎng)頁(yè)的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-02-02
  • Django和websocket實(shí)現(xiàn)簡(jiǎn)單的多人聊天的示例代碼

    Django和websocket實(shí)現(xiàn)簡(jiǎn)單的多人聊天的示例代碼

    本文主要介紹了使用Django和WebSocket實(shí)現(xiàn)一個(gè)簡(jiǎn)單的多人聊天應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • python分別打包出32位和64位應(yīng)用程序

    python分別打包出32位和64位應(yīng)用程序

    本文給大家分享的是如何使用python打包出32位和64位的應(yīng)用程序的方法,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下
    2020-02-02
  • Python通過計(jì)算圖片MD5值實(shí)現(xiàn)圖片去重

    Python通過計(jì)算圖片MD5值實(shí)現(xiàn)圖片去重

    這篇文章主要為大家詳細(xì)介紹了Python如何通過MD5實(shí)現(xiàn)圖片去重的3種計(jì)算方式并進(jìn)行了對(duì)比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2026-05-05
  • Python 的lru_cache裝飾器使用簡(jiǎn)介

    Python 的lru_cache裝飾器使用簡(jiǎn)介

    這篇文章主要介紹了Python 的lru_cache 裝飾器使用簡(jiǎn)介,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-03-03

最新評(píng)論

清水县| 蕉岭县| 隆化县| 周至县| 交口县| 东台市| 溧水县| 随州市| 大足县| 永寿县| 公安县| 慈溪市| 唐海县| 若羌县| 太白县| 泌阳县| 高州市| 揭东县| 邹城市| 沁源县| 赤壁市| 祁门县| 海晏县| 铁力市| 普安县| 莆田市| 揭东县| 客服| 濮阳县| 武陟县| 乐至县| 隆德县| 东明县| 镇安县| 浑源县| 临泉县| 姜堰市| 开封市| 三明市| 嵊州市| 枞阳县|