[fix] powershell black screens and try to solve update re-start not working
This commit is contained in:
@@ -3,10 +3,8 @@ import { Card, CardBody, CardHeader, CardIcon, CardTool } from "@/components/win
|
||||
import { ToolButton } from "@/components/window/ToolButton"
|
||||
import { Chip, Skeleton } from "@heroui/react"
|
||||
import { Refresh, SettingConfig } from "@icon-park/react"
|
||||
// import { version } from "@tauri-apps/plugin-os"
|
||||
import { type AllSystemInfo, allSysInfo } from "tauri-plugin-system-info-api"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import useSWR, { useSWRConfig } from "swr"
|
||||
import { useHardwareStore } from "@/store/hardware"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
@@ -36,135 +34,47 @@ export default function Page() {
|
||||
}
|
||||
|
||||
function HardwareInfo() {
|
||||
const { mutate } = useSWRConfig()
|
||||
const { refreshHardwareInfo } = useHardwareStore()
|
||||
const [isRefreshing, setIsRefreshing] = useState(false)
|
||||
|
||||
return (
|
||||
<ToolButton
|
||||
onClick={() => {
|
||||
// 使用 SWR 的 mutate 来刷新数据
|
||||
mutate("/api/hardware-info")
|
||||
onClick={async () => {
|
||||
setIsRefreshing(true)
|
||||
try {
|
||||
await refreshHardwareInfo()
|
||||
} finally {
|
||||
setIsRefreshing(false)
|
||||
}
|
||||
}}
|
||||
disabled={isRefreshing}
|
||||
>
|
||||
<Refresh /> 刷新
|
||||
</ToolButton>
|
||||
)
|
||||
}
|
||||
|
||||
interface ComputerInfo {
|
||||
OsName?: string
|
||||
OSDisplayVersion?: string
|
||||
BiosSMBIOSBIOSVersion?: string
|
||||
CsManufacturer?: string
|
||||
CsName?: string
|
||||
ReleaseId?: string
|
||||
}
|
||||
|
||||
interface GpuInfo {
|
||||
vendor: string
|
||||
model: string
|
||||
family: string
|
||||
device_id: string
|
||||
total_vram: number
|
||||
used_vram: number
|
||||
load_pct: number
|
||||
temperature: number
|
||||
}
|
||||
|
||||
interface MemoryInfo {
|
||||
capacity?: number // 容量(字节)
|
||||
manufacturer?: string
|
||||
speed?: number // MHz,实际频率 ConfiguredClockSpeed
|
||||
default_speed?: number // MHz,默认频率 Speed(如果存在)
|
||||
}
|
||||
|
||||
interface MonitorInfo {
|
||||
name?: string
|
||||
refresh_rate?: number // Hz
|
||||
resolution_width?: number
|
||||
resolution_height?: number
|
||||
}
|
||||
|
||||
interface MotherboardInfo {
|
||||
manufacturer?: string // 制造商
|
||||
model?: string // 型号
|
||||
version?: string
|
||||
}
|
||||
|
||||
interface HardwareData {
|
||||
allSysData: AllSystemInfo
|
||||
computerInfo: ComputerInfo
|
||||
gpuInfo: GpuInfo | null
|
||||
memoryInfo: MemoryInfo[]
|
||||
monitorInfo: MonitorInfo[]
|
||||
motherboardInfo: MotherboardInfo | null
|
||||
}
|
||||
|
||||
// 硬件信息 fetcher
|
||||
const hardwareInfoFetcher = async (): Promise<HardwareData> => {
|
||||
// 并行获取系统信息、PowerShell 信息、GPU 信息、内存信息、显示器信息和主板信息
|
||||
const [sys, computerInfoData, gpuInfoData, memoryInfoData, monitorInfoData, motherboardInfoData] =
|
||||
await Promise.all([
|
||||
allSysInfo(),
|
||||
invoke<ComputerInfo>("get_computer_info").catch((error) => {
|
||||
console.error("获取 PowerShell 信息失败:", error)
|
||||
return {} as ComputerInfo
|
||||
}),
|
||||
invoke<GpuInfo | null>("get_gpu_info").catch((error) => {
|
||||
console.error("获取 GPU 信息失败:", error)
|
||||
return null
|
||||
}),
|
||||
invoke<MemoryInfo[]>("get_memory_info").catch((error) => {
|
||||
console.error("获取内存信息失败:", error)
|
||||
return [] as MemoryInfo[]
|
||||
}),
|
||||
invoke<MonitorInfo[]>("get_monitor_info").catch((error) => {
|
||||
console.error("获取显示器信息失败:", error)
|
||||
return [] as MonitorInfo[]
|
||||
}),
|
||||
invoke<MotherboardInfo>("get_motherboard_info").catch((error) => {
|
||||
console.error("获取主板信息失败:", error)
|
||||
return { manufacturer: undefined, model: undefined, version: undefined } as MotherboardInfo
|
||||
}),
|
||||
])
|
||||
|
||||
console.log("系统信息:", sys)
|
||||
console.log("PowerShell 信息:", computerInfoData)
|
||||
console.log("GPU 信息:", gpuInfoData)
|
||||
console.log("内存信息:", memoryInfoData)
|
||||
console.log("显示器信息:", monitorInfoData)
|
||||
console.log("主板信息:", motherboardInfoData)
|
||||
|
||||
if (sys?.cpus) {
|
||||
console.log("CPU数据:", sys.cpus)
|
||||
console.log("第一个CPU:", sys.cpus[0])
|
||||
if (sys.cpus[0]) {
|
||||
console.log("CPU字段:", Object.keys(sys.cpus[0]))
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
allSysData: sys,
|
||||
computerInfo: computerInfoData,
|
||||
gpuInfo: gpuInfoData,
|
||||
memoryInfo: memoryInfoData,
|
||||
monitorInfo: monitorInfoData,
|
||||
motherboardInfo: motherboardInfoData,
|
||||
}
|
||||
}
|
||||
|
||||
function HardwareInfoContent() {
|
||||
const { data, isLoading, isValidating } = useSWR<HardwareData>("/api/hardware-info", hardwareInfoFetcher, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
dedupingInterval: 5 * 60 * 1000, // 5分钟内相同请求去重
|
||||
})
|
||||
const { state, fetchHardwareInfo } = useHardwareStore()
|
||||
const [isLoading, setIsLoading] = useState(!state.allSysData)
|
||||
|
||||
const allSysData = data?.allSysData
|
||||
const computerInfo = data?.computerInfo || {}
|
||||
const gpuInfo = data?.gpuInfo
|
||||
const memoryInfo = data?.memoryInfo || []
|
||||
const monitorInfo = data?.monitorInfo || []
|
||||
const motherboardInfo = data?.motherboardInfo
|
||||
useEffect(() => {
|
||||
// 如果数据不存在,则加载数据
|
||||
if (!state.allSysData) {
|
||||
setIsLoading(true)
|
||||
void fetchHardwareInfo().finally(() => {
|
||||
setIsLoading(false)
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []) // 只在组件挂载时执行一次,state 是响应式的,不需要作为依赖
|
||||
|
||||
const allSysData = state.allSysData
|
||||
const computerInfo = state.computerInfo || {}
|
||||
const gpuInfo = state.gpuInfo
|
||||
const memoryInfo = state.memoryInfo || []
|
||||
const monitorInfo = state.monitorInfo || []
|
||||
const motherboardInfo = state.motherboardInfo
|
||||
|
||||
const formatBytes = (bytes?: number) => {
|
||||
if (!bytes) return "未知"
|
||||
@@ -243,8 +153,8 @@ function HardwareInfoContent() {
|
||||
})()
|
||||
: null
|
||||
|
||||
// 如果正在加载或正在验证(包括刷新),显示 Skeleton 骨架屏
|
||||
if (isLoading || isValidating) {
|
||||
// 如果正在加载,显示 Skeleton 骨架屏
|
||||
if (isLoading || !allSysData) {
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* 系统信息 Skeleton */}
|
||||
|
||||
@@ -1,48 +1,13 @@
|
||||
import { useState, useEffect } from "react"
|
||||
import { allSysInfo, type AllSystemInfo } from "tauri-plugin-system-info-api"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
|
||||
interface GpuInfo {
|
||||
vendor: string
|
||||
model: string
|
||||
family: string
|
||||
device_id: string
|
||||
total_vram: number
|
||||
used_vram: number
|
||||
load_pct: number
|
||||
temperature: number
|
||||
}
|
||||
|
||||
interface ComputerInfo {
|
||||
OsName?: string
|
||||
OSDisplayVersion?: string
|
||||
BiosSMBIOSBIOSVersion?: string
|
||||
CsManufacturer?: string
|
||||
CsName?: string
|
||||
ReleaseId?: string
|
||||
}
|
||||
|
||||
interface MemoryInfo {
|
||||
capacity?: number // 容量(字节)
|
||||
manufacturer?: string
|
||||
speed?: number // MHz,实际频率 ConfiguredClockSpeed
|
||||
default_speed?: number // MHz,默认频率 Speed(如果存在)
|
||||
}
|
||||
|
||||
interface MonitorInfo {
|
||||
manufacturer?: string
|
||||
model?: string
|
||||
name?: string
|
||||
refresh_rate?: number // Hz
|
||||
resolution_width?: number
|
||||
resolution_height?: number
|
||||
}
|
||||
|
||||
interface MotherboardInfo {
|
||||
manufacturer?: string // 制造商
|
||||
model?: string // 型号
|
||||
version?: string
|
||||
}
|
||||
import { useEffect } from "react"
|
||||
import { useHardwareStore } from "@/store/hardware"
|
||||
import type { AllSystemInfo } from "tauri-plugin-system-info-api"
|
||||
import type {
|
||||
GpuInfo,
|
||||
ComputerInfo,
|
||||
MemoryInfo,
|
||||
MonitorInfo,
|
||||
MotherboardInfo,
|
||||
} from "@/store/hardware"
|
||||
|
||||
export interface HardwareInfoWithGpu {
|
||||
systemInfo: AllSystemInfo | null
|
||||
@@ -54,49 +19,23 @@ export interface HardwareInfoWithGpu {
|
||||
}
|
||||
|
||||
export function useHardwareInfo() {
|
||||
const [hardwareInfo, setHardwareInfo] = useState<HardwareInfoWithGpu | null>(null)
|
||||
const { state, fetchHardwareInfo } = useHardwareStore()
|
||||
|
||||
useEffect(() => {
|
||||
const fetchHardwareInfo = async () => {
|
||||
try {
|
||||
const [sys, gpuInfo, computerInfo, memoryInfo, monitorInfo, motherboardInfo] = await Promise.all([
|
||||
allSysInfo(),
|
||||
invoke<GpuInfo | null>("get_gpu_info").catch((error) => {
|
||||
console.error("获取 GPU 信息失败:", error)
|
||||
return null
|
||||
}),
|
||||
invoke<ComputerInfo>("get_computer_info").catch((error) => {
|
||||
console.error("获取 PowerShell 信息失败:", error)
|
||||
return {} as ComputerInfo
|
||||
}),
|
||||
invoke<MemoryInfo[]>("get_memory_info").catch((error) => {
|
||||
console.error("获取内存信息失败:", error)
|
||||
return [] as MemoryInfo[]
|
||||
}),
|
||||
invoke<MonitorInfo[]>("get_monitor_info").catch((error) => {
|
||||
console.error("获取显示器信息失败:", error)
|
||||
return [] as MonitorInfo[]
|
||||
}),
|
||||
invoke<MotherboardInfo>("get_motherboard_info").catch((error) => {
|
||||
console.error("获取主板信息失败:", error)
|
||||
return { manufacturer: undefined, model: undefined, version: undefined } as MotherboardInfo
|
||||
})
|
||||
])
|
||||
setHardwareInfo({
|
||||
systemInfo: sys,
|
||||
gpuInfo,
|
||||
computerInfo,
|
||||
memoryInfo,
|
||||
monitorInfo,
|
||||
motherboardInfo
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("获取硬件信息失败:", error)
|
||||
}
|
||||
// 如果数据不存在,则加载数据(store 初始化时已经加载,这里只是确保)
|
||||
if (!state.allSysData) {
|
||||
void fetchHardwareInfo()
|
||||
}
|
||||
void fetchHardwareInfo()
|
||||
}, [])
|
||||
}, []) // 只在组件挂载时执行一次
|
||||
|
||||
return hardwareInfo
|
||||
// 将 store 中的数据转换为兼容的格式
|
||||
return {
|
||||
systemInfo: state.allSysData,
|
||||
gpuInfo: state.gpuInfo,
|
||||
computerInfo: state.computerInfo,
|
||||
memoryInfo: state.memoryInfo,
|
||||
monitorInfo: state.monitorInfo,
|
||||
motherboardInfo: state.motherboardInfo,
|
||||
} as HardwareInfoWithGpu
|
||||
}
|
||||
|
||||
|
||||
@@ -170,19 +170,22 @@ export function UpdateChecker({ useMirror = true, customEndpoint, includePrerele
|
||||
if (!installerPath) return
|
||||
|
||||
try {
|
||||
addToast({
|
||||
title: "安装已启动",
|
||||
description: "应用将在安装完成后自动重启",
|
||||
color: "success",
|
||||
})
|
||||
|
||||
// 调用安装命令(这会阻塞直到安装完成)
|
||||
await invoke("install_app_update", {
|
||||
installerPath: installerPath,
|
||||
})
|
||||
|
||||
addToast({
|
||||
title: "安装已启动",
|
||||
description: "应用将在安装完成后重启",
|
||||
color: "success",
|
||||
})
|
||||
|
||||
setTimeout(async () => {
|
||||
await relaunch()
|
||||
}, 1000)
|
||||
// 安装完成后,等待一小段时间确保安装程序完全退出
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
|
||||
// 启动新版本
|
||||
await relaunch()
|
||||
} catch (error) {
|
||||
console.error("安装更新失败:", error)
|
||||
addToast({
|
||||
|
||||
151
src/store/hardware.ts
Normal file
151
src/store/hardware.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
import { store } from "@tauri-store/valtio"
|
||||
import { useSnapshot } from "valtio"
|
||||
import { DEFAULT_STORE_CONFIG } from "./config"
|
||||
import { allSysInfo, type AllSystemInfo } from "tauri-plugin-system-info-api"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
|
||||
export interface ComputerInfo {
|
||||
OsName?: string
|
||||
OSDisplayVersion?: string
|
||||
BiosSMBIOSBIOSVersion?: string
|
||||
CsManufacturer?: string
|
||||
CsName?: string
|
||||
ReleaseId?: string
|
||||
}
|
||||
|
||||
export interface GpuInfo {
|
||||
vendor: string
|
||||
model: string
|
||||
family: string
|
||||
device_id: string
|
||||
total_vram: number
|
||||
used_vram: number
|
||||
load_pct: number
|
||||
temperature: number
|
||||
}
|
||||
|
||||
export interface MemoryInfo {
|
||||
capacity?: number // 容量(字节)
|
||||
manufacturer?: string
|
||||
speed?: number // MHz,实际频率 ConfiguredClockSpeed
|
||||
default_speed?: number // MHz,默认频率 Speed(如果存在)
|
||||
}
|
||||
|
||||
export interface MonitorInfo {
|
||||
name?: string
|
||||
refresh_rate?: number // Hz
|
||||
resolution_width?: number
|
||||
resolution_height?: number
|
||||
}
|
||||
|
||||
export interface MotherboardInfo {
|
||||
manufacturer?: string // 制造商
|
||||
model?: string // 型号
|
||||
version?: string
|
||||
}
|
||||
|
||||
export interface HardwareData {
|
||||
allSysData: AllSystemInfo | null
|
||||
computerInfo: ComputerInfo
|
||||
gpuInfo: GpuInfo | null
|
||||
memoryInfo: MemoryInfo[]
|
||||
monitorInfo: MonitorInfo[]
|
||||
motherboardInfo: MotherboardInfo | null
|
||||
lastUpdated: number // 最后更新时间戳
|
||||
}
|
||||
|
||||
const defaultValue: HardwareData = {
|
||||
allSysData: null,
|
||||
computerInfo: {},
|
||||
gpuInfo: null,
|
||||
memoryInfo: [],
|
||||
monitorInfo: [],
|
||||
motherboardInfo: null,
|
||||
lastUpdated: 0,
|
||||
}
|
||||
|
||||
// 硬件信息 fetcher
|
||||
const hardwareInfoFetcher = async (): Promise<HardwareData> => {
|
||||
// 并行获取系统信息、PowerShell 信息、GPU 信息、内存信息、显示器信息和主板信息
|
||||
const [sys, computerInfoData, gpuInfoData, memoryInfoData, monitorInfoData, motherboardInfoData] =
|
||||
await Promise.all([
|
||||
allSysInfo(),
|
||||
invoke<ComputerInfo>("get_computer_info").catch((error) => {
|
||||
console.error("获取 PowerShell 信息失败:", error)
|
||||
return {} as ComputerInfo
|
||||
}),
|
||||
invoke<GpuInfo | null>("get_gpu_info").catch((error) => {
|
||||
console.error("获取 GPU 信息失败:", error)
|
||||
return null
|
||||
}),
|
||||
invoke<MemoryInfo[]>("get_memory_info").catch((error) => {
|
||||
console.error("获取内存信息失败:", error)
|
||||
return [] as MemoryInfo[]
|
||||
}),
|
||||
invoke<MonitorInfo[]>("get_monitor_info").catch((error) => {
|
||||
console.error("获取显示器信息失败:", error)
|
||||
return [] as MonitorInfo[]
|
||||
}),
|
||||
invoke<MotherboardInfo>("get_motherboard_info").catch((error) => {
|
||||
console.error("获取主板信息失败:", error)
|
||||
return { manufacturer: undefined, model: undefined, version: undefined } as MotherboardInfo
|
||||
}),
|
||||
])
|
||||
|
||||
return {
|
||||
allSysData: sys,
|
||||
computerInfo: computerInfoData,
|
||||
gpuInfo: gpuInfoData,
|
||||
memoryInfo: memoryInfoData,
|
||||
monitorInfo: monitorInfoData,
|
||||
motherboardInfo: motherboardInfoData,
|
||||
lastUpdated: Date.now(),
|
||||
}
|
||||
}
|
||||
|
||||
export const hardwareStore = store("hardware", { ...defaultValue }, DEFAULT_STORE_CONFIG)
|
||||
|
||||
// 检查数据是否过期(30分钟)
|
||||
const isDataStale = (lastUpdated: number): boolean => {
|
||||
const thirtyMinutes = 30 * 60 * 1000
|
||||
return Date.now() - lastUpdated > thirtyMinutes
|
||||
}
|
||||
|
||||
// 获取硬件信息(如果数据过期或不存在则重新获取)
|
||||
export const fetchHardwareInfo = async (force = false): Promise<void> => {
|
||||
// 如果数据存在且未过期,且不是强制刷新,则直接返回
|
||||
if (!force && hardwareStore.state.allSysData && !isDataStale(hardwareStore.state.lastUpdated)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await hardwareInfoFetcher()
|
||||
hardwareStore.state.allSysData = data.allSysData
|
||||
hardwareStore.state.computerInfo = data.computerInfo
|
||||
hardwareStore.state.gpuInfo = data.gpuInfo
|
||||
hardwareStore.state.memoryInfo = data.memoryInfo
|
||||
hardwareStore.state.monitorInfo = data.monitorInfo
|
||||
hardwareStore.state.motherboardInfo = data.motherboardInfo
|
||||
hardwareStore.state.lastUpdated = data.lastUpdated
|
||||
} catch (error) {
|
||||
console.error("获取硬件信息失败:", error)
|
||||
}
|
||||
}
|
||||
|
||||
// 强制刷新硬件信息
|
||||
export const refreshHardwareInfo = async (): Promise<void> => {
|
||||
await fetchHardwareInfo(true)
|
||||
}
|
||||
|
||||
export const useHardwareStore = () => {
|
||||
void hardwareStore.start
|
||||
const state = useSnapshot(hardwareStore.state)
|
||||
|
||||
return {
|
||||
state,
|
||||
store: hardwareStore,
|
||||
fetchHardwareInfo,
|
||||
refreshHardwareInfo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { authStore } from "./auth"
|
||||
import { steamStore } from "./steam"
|
||||
import { toolStore } from "./tool"
|
||||
import { fpsTestStore } from "./fps_test"
|
||||
import { hardwareStore, fetchHardwareInfo } from "./hardware"
|
||||
|
||||
export async function init() {
|
||||
await appStore.start()
|
||||
@@ -10,4 +11,7 @@ export async function init() {
|
||||
await toolStore.start()
|
||||
await steamStore.start()
|
||||
await fpsTestStore.start()
|
||||
await hardwareStore.start()
|
||||
// 初始化时自动加载硬件信息(如果数据过期或不存在)
|
||||
await fetchHardwareInfo()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user