Compare commits
4 Commits
26d04daceb
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
daa0178185 | ||
|
|
4be0fdcb74 | ||
|
|
93164a86d8 | ||
|
|
0ff1014e62 |
BIN
app-icon.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
@@ -2,9 +2,8 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Tauri + Vue 3 App</title>
|
<title>System Doctor</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
<svg width="206" height="231" viewBox="0 0 206 231" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M143.143 84C143.143 96.1503 133.293 106 121.143 106C108.992 106 99.1426 96.1503 99.1426 84C99.1426 71.8497 108.992 62 121.143 62C133.293 62 143.143 71.8497 143.143 84Z" fill="#FFC131"/>
|
|
||||||
<ellipse cx="84.1426" cy="147" rx="22" ry="22" transform="rotate(180 84.1426 147)" fill="#24C8DB"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M166.738 154.548C157.86 160.286 148.023 164.269 137.757 166.341C139.858 160.282 141 153.774 141 147C141 144.543 140.85 142.121 140.558 139.743C144.975 138.204 149.215 136.139 153.183 133.575C162.73 127.404 170.292 118.608 174.961 108.244C179.63 97.8797 181.207 86.3876 179.502 75.1487C177.798 63.9098 172.884 53.4021 165.352 44.8883C157.82 36.3744 147.99 30.2165 137.042 27.1546C126.095 24.0926 114.496 24.2568 103.64 27.6274C92.7839 30.998 83.1319 37.4317 75.8437 46.1553C74.9102 47.2727 74.0206 48.4216 73.176 49.5993C61.9292 50.8488 51.0363 54.0318 40.9629 58.9556C44.2417 48.4586 49.5653 38.6591 56.679 30.1442C67.0505 17.7298 80.7861 8.57426 96.2354 3.77762C111.685 -1.01901 128.19 -1.25267 143.769 3.10474C159.348 7.46215 173.337 16.2252 184.056 28.3411C194.775 40.457 201.767 55.4101 204.193 71.404C206.619 87.3978 204.374 103.752 197.73 118.501C191.086 133.25 180.324 145.767 166.738 154.548ZM41.9631 74.275L62.5557 76.8042C63.0459 72.813 63.9401 68.9018 65.2138 65.1274C57.0465 67.0016 49.2088 70.087 41.9631 74.275Z" fill="#FFC131"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4045 76.4519C47.3493 70.6709 57.2677 66.6712 67.6171 64.6132C65.2774 70.9669 64 77.8343 64 85.0001C64 87.1434 64.1143 89.26 64.3371 91.3442C60.0093 92.8732 55.8533 94.9092 51.9599 97.4256C42.4128 103.596 34.8505 112.392 30.1816 122.756C25.5126 133.12 23.9357 144.612 25.6403 155.851C27.3449 167.09 32.2584 177.598 39.7906 186.112C47.3227 194.626 57.153 200.784 68.1003 203.846C79.0476 206.907 90.6462 206.743 101.502 203.373C112.359 200.002 122.011 193.568 129.299 184.845C130.237 183.722 131.131 182.567 131.979 181.383C143.235 180.114 154.132 176.91 164.205 171.962C160.929 182.49 155.596 192.319 148.464 200.856C138.092 213.27 124.357 222.426 108.907 227.222C93.458 232.019 76.9524 232.253 61.3736 227.895C45.7948 223.538 31.8055 214.775 21.0867 202.659C10.3679 190.543 3.37557 175.59 0.949823 159.596C-1.47592 143.602 0.768139 127.248 7.41237 112.499C14.0566 97.7497 24.8183 85.2327 38.4045 76.4519ZM163.062 156.711L163.062 156.711C162.954 156.773 162.846 156.835 162.738 156.897C162.846 156.835 162.954 156.773 163.062 156.711Z" fill="#24C8DB"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
11
src-tauri/Cargo.lock
generated
@@ -872,15 +872,6 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "encoding_rs_io"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
|
|
||||||
dependencies = [
|
|
||||||
"encoding_rs",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "endi"
|
name = "endi"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -3718,8 +3709,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"csv",
|
"csv",
|
||||||
"encoding_rs",
|
|
||||||
"encoding_rs_io",
|
|
||||||
"minidump",
|
"minidump",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "system-doctor"
|
name = "system-doctor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "A Tauri App"
|
description = "System diagnosis"
|
||||||
authors = ["you"]
|
authors = ["Julian"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[lib]
|
|
||||||
# The `_lib` suffix may seem redundant but it is necessary
|
|
||||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
|
||||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
|
||||||
name = "system_doctor_lib"
|
|
||||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "2", features = [] }
|
tauri-build = { version = "2", features = [] }
|
||||||
|
|
||||||
@@ -27,11 +20,7 @@ wmi = "0.13"
|
|||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
minidump = "0.19"
|
minidump = "0.19"
|
||||||
# [新增] 用于解析 BlueScreenView 导出的 CSV
|
|
||||||
csv = "1.3"
|
csv = "1.3"
|
||||||
# [新增] 用于处理可能的文件编码问题
|
|
||||||
encoding_rs = "0.8"
|
|
||||||
encoding_rs_io = "0.1"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 974 B After Width: | Height: | Size: 1.7 KiB |
BIN
src-tauri/icons/64x64.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 903 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
</adaptive-icon>
|
||||||
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 74 KiB |
BIN
src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#fff</color>
|
||||||
|
</resources>
|
||||||
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 80 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@1x.png
Normal file
|
After Width: | Height: | Size: 859 B |
BIN
src-tauri/icons/ios/AppIcon-20x20@2x-1.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@2x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-20x20@3x.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@1x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@2x-1.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@2x.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src-tauri/icons/ios/AppIcon-29x29@3x.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@1x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@2x-1.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@2x.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
src-tauri/icons/ios/AppIcon-40x40@3x.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
src-tauri/icons/ios/AppIcon-512@2x.png
Normal file
|
After Width: | Height: | Size: 215 KiB |
BIN
src-tauri/icons/ios/AppIcon-60x60@2x.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
src-tauri/icons/ios/AppIcon-60x60@3x.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src-tauri/icons/ios/AppIcon-76x76@1x.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src-tauri/icons/ios/AppIcon-76x76@2x.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
@@ -1,14 +0,0 @@
|
|||||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
||||||
#[tauri::command]
|
|
||||||
fn greet(name: &str) -> String {
|
|
||||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
||||||
pub fn run() {
|
|
||||||
tauri::Builder::default()
|
|
||||||
.plugin(tauri_plugin_opener::init())
|
|
||||||
.invoke_handler(tauri::generate_handler![greet])
|
|
||||||
.run(tauri::generate_context!())
|
|
||||||
.expect("error while running tauri application");
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
// src-tauri/src/main.rs
|
|
||||||
|
|
||||||
// 全局允许非标准命名风格
|
// 全局允许非标准命名风格
|
||||||
#![allow(non_camel_case_types, non_snake_case)]
|
#![allow(non_camel_case_types, non_snake_case)]
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
@@ -131,61 +129,112 @@ fn format_wmi_time(wmi_str: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [扩展] 翻译 BugCheck Code (u32) - 增加了更多常见代码
|
||||||
fn translate_bugcheck_u32(code: u32) -> (String, String) {
|
fn translate_bugcheck_u32(code: u32) -> (String, String) {
|
||||||
match code {
|
match code {
|
||||||
|
// 驱动与内存相关
|
||||||
|
0x0000000A => (
|
||||||
|
"IRQL_NOT_LESS_OR_EQUAL (0x0A)".to_string(),
|
||||||
|
"驱动程序使用了不正确的内存地址。通常由有缺陷的驱动程序(如杀毒软件、虚拟光驱驱动)或硬件兼容性问题引起。建议更新所有驱动程序。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
0x000000D1 => (
|
0x000000D1 => (
|
||||||
"DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1)".to_string(),
|
"DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1)".to_string(),
|
||||||
"驱动程序使用了不正确的内存地址。通常是驱动程序冲突或损坏。请检查最近安装的硬件驱动(显卡、网卡等),尝试回滚或更新驱动。"
|
"驱动程序尝试访问未分页内存。这是最常见的蓝屏之一,通常是驱动程序冲突或损坏。请检查最近安装的硬件驱动(显卡、网卡等)。"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
0x0000007E | 0x1000007E => (
|
0x0000007E | 0x1000007E => (
|
||||||
"SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (0x7E)".to_string(),
|
"SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (0x7E)".to_string(),
|
||||||
"系统线程抛出了未捕获的异常。可能是显卡驱动不兼容,或者BIOS设置问题。建议重装显卡驱动,或恢复BIOS默认设置。"
|
"系统线程抛出了未捕获的异常。可能是显卡驱动不兼容,或者BIOS设置问题。建议重装显卡驱动,或更新 BIOS。"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
0x0000001A => (
|
0x0000001E => (
|
||||||
"MEMORY_MANAGEMENT (0x1A)".to_string(),
|
"KMODE_EXCEPTION_NOT_HANDLED (0x1E)".to_string(),
|
||||||
"严重的内存管理错误。高度怀疑内存条物理故障。建议立即运行 Windows 内存诊断工具,或者尝试拔插内存条。"
|
"内核模式程序生成了处理器无法捕获的异常。通常是硬件兼容性问题或驱动程序错误。建议检查是否有新安装的硬件。"
|
||||||
.to_string(),
|
|
||||||
),
|
|
||||||
0x000000EF => (
|
|
||||||
"CRITICAL_PROCESS_DIED (0xEF)".to_string(),
|
|
||||||
"Windows 核心进程意外终止。通常是系统文件损坏或硬盘故障。建议运行 'sfc /scannow' 修复系统,并检查硬盘健康度。"
|
|
||||||
.to_string(),
|
|
||||||
),
|
|
||||||
0x00000124 => (
|
|
||||||
"WHEA_UNCORRECTABLE_ERROR (0x124)".to_string(),
|
|
||||||
"硬件发生无法纠正的物理错误。这是纯硬件故障。通常是 CPU 电压不足、超频失败、过热,或者主板/PCIe设备故障。"
|
|
||||||
.to_string(),
|
|
||||||
),
|
|
||||||
0x00000116 => (
|
|
||||||
"VIDEO_TDR_FAILURE (0x116)".to_string(),
|
|
||||||
"显卡响应超时。显卡驱动崩溃或显卡过热。如果你在玩游戏,可能是显卡超频不稳定或散热硅脂干了。"
|
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
0x00000050 => (
|
0x00000050 => (
|
||||||
"PAGE_FAULT_IN_NONPAGED_AREA (0x50)".to_string(),
|
"PAGE_FAULT_IN_NONPAGED_AREA (0x50)".to_string(),
|
||||||
"试图访问无效的内存地址。可能是内存条故障,或者是防病毒软件/驱动程序冲突。建议检查内存。"
|
"试图访问无效的内存地址。极大概率是内存条故障(接触不良或损坏),或者是防病毒软件/驱动程序冲突。建议运行内存诊断。"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
0x0000000A => (
|
0x0000001A => (
|
||||||
"IRQL_NOT_LESS_OR_EQUAL (0x0A)".to_string(),
|
"MEMORY_MANAGEMENT (0x1A)".to_string(),
|
||||||
"驱动程序使用了不正确的内存地址。通常由有缺陷的驱动程序或硬件兼容性问题引起。"
|
"严重的内存管理错误。高度怀疑内存条物理故障。建议立即运行 Windows 内存诊断工具,或者尝试拔插/更换内存条。"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
0x0000003B => (
|
|
||||||
"SYSTEM_SERVICE_EXCEPTION (0x3B)".to_string(),
|
// 硬件与系统核心相关
|
||||||
"系统服务执行异常。通常与图形驱动程序或过时的系统文件有关。"
|
0x00000124 => (
|
||||||
|
"WHEA_UNCORRECTABLE_ERROR (0x124)".to_string(),
|
||||||
|
"硬件发生无法纠正的物理错误。这是纯硬件故障。通常是 CPU 电压不足(缩缸)、超频失败、过热,或者主板/PCIe设备故障。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x00000101 => (
|
||||||
|
"CLOCK_WATCHDOG_TIMEOUT (0x101)".to_string(),
|
||||||
|
"CPU 核心死锁。系统检测到某个 CPU 核心在规定时间内没有响应。通常是因为 CPU 超频不稳定、电压不足或过热。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x000000EF => (
|
||||||
|
"CRITICAL_PROCESS_DIED (0xEF)".to_string(),
|
||||||
|
"Windows 核心进程意外终止。通常是系统文件严重损坏或硬盘出现坏道导致无法读取系统文件。建议运行 'sfc /scannow'。"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
0x00000133 => (
|
0x00000133 => (
|
||||||
"DPC_WATCHDOG_VIOLATION (0x133)".to_string(),
|
"DPC_WATCHDOG_VIOLATION (0x133)".to_string(),
|
||||||
"DPC 看门狗超时。通常是 SSD 固件过旧或无线网卡驱动冲突导致系统卡死时间过长。"
|
"DPC 看门狗超时。系统被某个驱动程序(通常是 SSD 固件、SATA 驱动或无线网卡驱动)卡死太久。建议更新 SSD 固件和主板芯片组驱动。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x00000139 => (
|
||||||
|
"KERNEL_SECURITY_CHECK_FAILURE (0x139)".to_string(),
|
||||||
|
"内核检测到关键数据结构损坏。通常由内存错误、驱动程序 Bug 或病毒导致。建议检查内存和更新驱动。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 显卡与电源相关
|
||||||
|
0x00000116 => (
|
||||||
|
"VIDEO_TDR_FAILURE (0x116)".to_string(),
|
||||||
|
"显卡响应超时。显卡驱动崩溃且无法恢复。如果你在玩游戏,可能是显卡超频不稳定、电源功率不足或散热硅脂干了。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x00000119 => (
|
||||||
|
"VIDEO_SCHEDULER_INTERNAL_ERROR (0x119)".to_string(),
|
||||||
|
"显卡调度器内部错误。这表明显卡驱动发送了无效数据,或者是显卡显存(VRAM)出现故障。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x0000009F => (
|
||||||
|
"DRIVER_POWER_STATE_FAILURE (0x9F)".to_string(),
|
||||||
|
"驱动程序电源状态故障。通常发生在电脑休眠、睡眠或唤醒时。某个设备的驱动程序没有正确响应电源指令。建议检查电源管理设置。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 存储与启动相关
|
||||||
|
0x0000007B => (
|
||||||
|
"INACCESSIBLE_BOOT_DEVICE (0x7B)".to_string(),
|
||||||
|
"无法访问启动设备。通常是 BIOS 中的硬盘模式设置错误(如 AHCI/RAID 切换)或引导扇区损坏。也可能是硬盘物理连接松动。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x00000024 => (
|
||||||
|
"NTFS_FILE_SYSTEM (0x24)".to_string(),
|
||||||
|
"NTFS 文件系统损坏。这通常意味着硬盘出现坏道或文件系统逻辑错误。建议立即运行 'chkdsk /f /r' 修复磁盘。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
0x00000154 => (
|
||||||
|
"UNEXPECTED_STORE_EXCEPTION (0x154)".to_string(),
|
||||||
|
"系统存储组件检测到意外异常。通常指向系统盘(SSD/HDD)出现故障或连接线松动,导致系统无法读取关键数据。"
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 系统服务异常
|
||||||
|
0x0000003B => (
|
||||||
|
"SYSTEM_SERVICE_EXCEPTION (0x3B)".to_string(),
|
||||||
|
"系统服务执行异常。通常与图形驱动程序、系统文件损坏或过时的驱动有关。"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
_ => (
|
_ => (
|
||||||
format!("未知错误代码: 0x{:X}", code),
|
format!("未知错误代码: 0x{:X}", code),
|
||||||
"建议手动搜索此错误代码。通用建议:更新驱动、检查内存、扫描病毒。".to_string(),
|
"此代码较为罕见,建议手动在搜索引擎中搜索此错误代码。通用排查步骤:1. 更新所有驱动;2. 运行内存诊断;3. 检查系统文件完整性。"
|
||||||
|
.to_string(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,34 +280,61 @@ where T: Deref<Target = [u8]>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlueScreenView 外部调用分析
|
// [修复] BlueScreenView 外部调用分析 (使用有损 UTF-8 转换)
|
||||||
fn analyze_with_bluescreenview(dump_path: &Path) -> Result<BsodAnalysisReport, String> {
|
fn analyze_with_bluescreenview(dump_path: &Path) -> Result<BsodAnalysisReport, String> {
|
||||||
let bsv_exe = "BlueScreenView.exe";
|
let bsv_exe = "BlueScreenView.exe";
|
||||||
|
|
||||||
let mut temp_csv_path = std::env::temp_dir();
|
let mut temp_csv_path = std::env::temp_dir();
|
||||||
temp_csv_path.push(format!("bsod_report_{}.csv", chrono::Utc::now().timestamp_millis()));
|
temp_csv_path.push(format!("bsod_report_{}.csv", chrono::Utc::now().timestamp_millis()));
|
||||||
|
|
||||||
|
// BlueScreenView.exe /LoadFrom 3 /SingleDumpFile <DumpFilePath> /scomma <OutFile>
|
||||||
let status = Command::new(bsv_exe)
|
let status = Command::new(bsv_exe)
|
||||||
|
.arg("/LoadFrom")
|
||||||
|
.arg("3")
|
||||||
|
.arg("/SingleDumpFile")
|
||||||
.arg(dump_path.to_string_lossy().to_string())
|
.arg(dump_path.to_string_lossy().to_string())
|
||||||
.arg("/scomma")
|
.arg("/scomma")
|
||||||
.arg(temp_csv_path.to_string_lossy().to_string())
|
.arg(temp_csv_path.to_string_lossy().to_string())
|
||||||
.status();
|
.status();
|
||||||
|
|
||||||
if status.is_err() {
|
if status.is_err() {
|
||||||
return Err("未找到 BlueScreenView.exe,无法分析内核转储文件。请将 BlueScreenView.exe 放入程序目录。".to_string());
|
return Err("未找到 BlueScreenView.exe,或没有以管理员运行。".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [修改] 使用 fs::read 读取原始字节,然后有损转换为 String
|
||||||
|
// 这样即使文件是 UTF-16 或者包含非法 UTF-8 字符,也不会 panic
|
||||||
let content_bytes = fs::read(&temp_csv_path).map_err(|_| "BlueScreenView 分析未生成有效数据。".to_string())?;
|
let content_bytes = fs::read(&temp_csv_path).map_err(|_| "BlueScreenView 分析未生成有效数据。".to_string())?;
|
||||||
let _ = fs::remove_file(temp_csv_path);
|
let _ = fs::remove_file(temp_csv_path);
|
||||||
let content = String::from_utf8_lossy(&content_bytes);
|
|
||||||
|
// 1. 简单判断:如果包含很多 0 字节,可能是 UTF-16,尝试手动过滤 0 (简单粗暴但对 CSV 有效)
|
||||||
|
// 2. 或者直接 lossy 转换,虽然 UTF-16 会乱码,但 CSV crate 有时能容忍乱码分隔符
|
||||||
|
// 最稳妥的方式其实是先尝试 UTF-16LE 转换逻辑(但我们刚才移除了 encoding_rs),
|
||||||
|
// 所以这里我们用一个简单的技巧:如果文件头两个字节是 FF FE,手动跳过 BOM
|
||||||
|
|
||||||
|
let content_string = if content_bytes.len() > 2 && content_bytes[0] == 0xFF && content_bytes[1] == 0xFE {
|
||||||
|
// 简易 UTF-16LE 转 UTF-8 (只针对 ASCII 字符有效,对中文可能会乱码,但在这个场景下够用了)
|
||||||
|
// BlueScreenView 的列名和关键 hex 代码都是 ASCII
|
||||||
|
let mut s = String::new();
|
||||||
|
for i in (2..content_bytes.len()).step_by(2) {
|
||||||
|
if i+1 < content_bytes.len() {
|
||||||
|
// 取低位字节,忽略高位 0x00
|
||||||
|
let c = content_bytes[i] as char;
|
||||||
|
s.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
String::from_utf8_lossy(&content_bytes).to_string()
|
||||||
|
};
|
||||||
|
|
||||||
let mut rdr = csv::ReaderBuilder::new()
|
let mut rdr = csv::ReaderBuilder::new()
|
||||||
.has_headers(false)
|
.has_headers(false)
|
||||||
.from_reader(content.as_bytes());
|
.from_reader(content_string.as_bytes());
|
||||||
|
|
||||||
for result in rdr.records() {
|
for result in rdr.records() {
|
||||||
if let Ok(record) = result {
|
if let Ok(record) = result {
|
||||||
if record.len() > 15 {
|
if record.len() > 15 {
|
||||||
|
// 跳过 Header 行
|
||||||
if &record[0] == "Dump File" { continue; }
|
if &record[0] == "Dump File" { continue; }
|
||||||
|
|
||||||
let bug_check_string = &record[2];
|
let bug_check_string = &record[2];
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "system-doctor",
|
"title": "系统检查 v0.1",
|
||||||
"width": 1200,
|
"width": 1200,
|
||||||
"height": 800
|
"height": 800
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
:class="{ active: currentTab === 'overview' }"
|
:class="{ active: currentTab === 'overview' }"
|
||||||
@click="currentTab = 'overview'"
|
@click="currentTab = 'overview'"
|
||||||
>
|
>
|
||||||
<span class="nav-icon">📊</span> 静态概览
|
<span class="nav-icon">📊</span> 健康概览
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="sidebar-footer">
|
<div class="sidebar-footer">
|
||||||
<span class="version">Pro v1.2</span>
|
<span class="version">Generated by AI</span>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
<span v-else>请先点击“全面体检”或“刷新日志”以获取数据。</span>
|
<span v-else>请先点击“全面体检”或“刷新日志”以获取数据。</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="report.events.length === 0" class="good-news large">
|
<div v-else-if="report.events.length === 0" class="good-news large">
|
||||||
✅ 过去30天内未发现 Kernel-Power(41) 或 WHEA(18/19) 等致命错误。
|
✅ 过去30天内未发现致命错误。
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="log-list-full">
|
<div v-else class="log-list-full">
|
||||||
<div v-for="(evt, idx) in report.events" :key="idx" class="log-card warning-item">
|
<div v-for="(evt, idx) in report.events" :key="idx" class="log-card warning-item">
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 496 B |