欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于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中的偏函數(shù)(Partial Functions)

    詳解Python中的偏函數(shù)(Partial Functions)

    Python中的偏函數(shù)是來(lái)自函數(shù)式編程的一個(gè)強(qiáng)大工具,它的主要目標(biāo)是減少函數(shù)調(diào)用的復(fù)雜性這個(gè)概念可能起初看起來(lái)有點(diǎn)困難理解,但一旦你明白了它的工作方式,它可能會(huì)成為你的編程工具箱中的重要組成部分,文中有相關(guān)的代碼介紹,需要的朋友可以參考下
    2023-06-06
  • Python 閉包的使用方法

    Python 閉包的使用方法

    這篇文章主要介紹了Python 閉包的使用方法的相關(guān)資料,了解閉包及定義方法和使用,需要的朋友可以參考下
    2017-09-09
  • 代碼實(shí)例講解python3的編碼問題

    代碼實(shí)例講解python3的編碼問題

    在本篇內(nèi)容里小編給各位分享了關(guān)于python3的編碼問題以及相關(guān)實(shí)例代碼,有需要的朋友們參考一下。
    2019-07-07
  • python 的賦值語(yǔ)句和基本輸入輸出詳解

    python 的賦值語(yǔ)句和基本輸入輸出詳解

    這篇文章主要為大家介紹了python 賦值語(yǔ)句和基本輸入輸出,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • python獲取引用對(duì)象的個(gè)數(shù)方式

    python獲取引用對(duì)象的個(gè)數(shù)方式

    今天小編就為大家分享一篇python獲取引用對(duì)象的個(gè)數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-12-12
  • Scrapy基于Python構(gòu)建強(qiáng)大網(wǎng)絡(luò)爬蟲框架實(shí)例探究

    Scrapy基于Python構(gòu)建強(qiáng)大網(wǎng)絡(luò)爬蟲框架實(shí)例探究

    這篇文章主要為大家介紹了Scrapy基于Python構(gòu)建強(qiáng)大網(wǎng)絡(luò)爬蟲框架實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Python在游戲中的熱更新實(shí)現(xiàn)

    Python在游戲中的熱更新實(shí)現(xiàn)

    本文主要介紹了Python在游戲中的熱更新實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • PyCharm+PySpark遠(yuǎn)程調(diào)試的環(huán)境配置的方法

    PyCharm+PySpark遠(yuǎn)程調(diào)試的環(huán)境配置的方法

    今天小編就為大家分享一篇PyCharm+PySpark遠(yuǎn)程調(diào)試的環(huán)境配置的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2018-11-11
  • Spark處理數(shù)據(jù)排序問題如何避免OOM

    Spark處理數(shù)據(jù)排序問題如何避免OOM

    這篇文章主要介紹了Spark處理數(shù)據(jù)排序問題如何避免OOM,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 高效測(cè)試用例組織算法pairwise之Python實(shí)現(xiàn)方法

    高效測(cè)試用例組織算法pairwise之Python實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇高效測(cè)試用例組織算法pairwise之Python實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2017-07-07

最新評(píng)論