Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions LiteMonitor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
<PlatformTarget>x64</PlatformTarget>
<ApplicationIcon>resources\assets\app.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<PublishSingleFile Condition="'$(RuntimeIdentifier)' != ''">true</PublishSingleFile>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<PublishTrimmed>false</PublishTrimmed>
<!-- 修复单文件+裁剪发布时,Resources.Designer 中 Bitmap/Icon 资源加载失败 -->
<CustomResourceTypesSupport>true</CustomResourceTypesSupport>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>

Expand All @@ -18,11 +23,18 @@
</PropertyGroup>


<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.6" />
<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.7-pre675" />
<PackageReference Include="System.Text.Json" Version="9.0.10" />
</ItemGroup>

<!-- 在 single-file + trimmed 模式下保留 WinForms 关键程序集,避免运行期 TypeLoadException -->
<ItemGroup>
<TrimmerRootAssembly Include="System.Windows.Forms" />
<TrimmerRootAssembly Include="System.Drawing.Common" />
<TrimmerRootAssembly Include="Accessibility" />
</ItemGroup>

<!-- 自动复制 themes 与 lang 目录下的所有文件 -->
<ItemGroup>
<Content Include="resources\themes\*.json">
Expand Down
16 changes: 8 additions & 8 deletions Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -119,30 +119,30 @@
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="AppIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\app.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\app.ico;System.Drawing.Icon, System.Drawing.Common</value>
</data>
<data name="CleanMem" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\CleanMem.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\CleanMem.png;System.Drawing.Bitmap, System.Drawing.Common</value>
<comment>CleanMem</comment>
</data>
<data name="HardwareInfo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\HardwareInfo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\HardwareInfo.png;System.Drawing.Bitmap, System.Drawing.Common</value>
<comment>HardwareInfo.png</comment>
</data>
<data name="NetworkIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\NetworkTest.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\NetworkTest.png;System.Drawing.Bitmap, System.Drawing.Common</value>
<comment>网络图标</comment>
</data>
<data name="Settings" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\Settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\Settings.png;System.Drawing.Bitmap, System.Drawing.Common</value>
<comment>Settings</comment>
</data>
<data name="ThemeIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\ThemeIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\ThemeIcon.png;System.Drawing.Bitmap, System.Drawing.Common</value>
<comment>主题图标</comment>
</data>
<data name="TrafficIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\assets\Traffic.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<value>..\resources\assets\Traffic.png;System.Drawing.Bitmap, System.Drawing.Common</value>
<comment>历史流量统计</comment>
</data>
</root>
</root>
41 changes: 41 additions & 0 deletions build/LiteMonitor.iss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#define MyAppName "LiteMonitor"
#define MyAppVersion "1.3.4"
#define MyAppPublisher "Diorser"
#define MyAppExeName "LiteMonitor.exe"

[Setup]
AppId={{8A6A4E34-36AF-430E-B42E-54793F51DE79}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
PrivilegesRequired=admin
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
OutputDir=..\artifacts\installer
OutputBaseFilename=LiteMonitor_Setup_{#MyAppVersion}_x64
SetupIconFile=..\resources\assets\app.ico
Compression=lzma2/ultra64
SolidCompression=yes
WizardStyle=modern
UninstallDisplayIcon={app}\{#MyAppExeName}
CloseApplications=yes

[Languages]
Name: "chinesesimp"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "创建桌面快捷方式"; GroupDescription: "附加任务:"; Flags: unchecked

[Files]
Source: "..\artifacts\publish-stable\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\卸载 {#MyAppName}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "启动 {#MyAppName}"; Flags: nowait postinstall skipifsilent
5 changes: 4 additions & 1 deletion resources/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
"TaskbarHoverShowAll": "Hover Details",
"TaskbarStyle": "Style",
"TaskbarMonitor": "Monitor",
"TaskbarMonitorSettings": "Screen Selection",
"TaskbarMonitorTip": "Choose which screens should show the taskbar widget. Auto mode follows the primary taskbar only.",
"TaskbarAllScreens": "Show On All Screens",
"TaskbarStyleBold": "Big",
"TaskbarStyleRegular": "Small",
"TaskbarAlign": "Position",
Expand Down Expand Up @@ -240,4 +243,4 @@
"PluginAddTarget": "+ Add Target",
"PluginDeleteConfirm": "Delete this plugin copy?"
}
}
}
5 changes: 4 additions & 1 deletion resources/lang/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@
"TaskbarHoverShowAll": "滑鼠懸停顯示詳情",
"TaskbarStyle": "工作列樣式",
"TaskbarMonitor": "顯示器螢幕",
"TaskbarMonitorSettings": "螢幕選擇",
"TaskbarMonitorTip": "可勾選工作列顯示在哪些螢幕上;勾選「自動模式」時,將只跟隨主螢幕工作列。",
"TaskbarAllScreens": "所有螢幕都顯示",
"TaskbarStyleBold": "大字模式",
"TaskbarStyleRegular": "小字模式",
"TaskbarAlign": "顯示位置",
Expand Down Expand Up @@ -238,4 +241,4 @@
"PluginAddTarget": "+ 新增監控目標",
"PluginDeleteConfirm": "確定要刪除此插件副本嗎?"
}
}
}
5 changes: 4 additions & 1 deletion resources/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
"TaskbarHoverShowAll": "鼠标悬停显示详情",
"TaskbarStyle": "任务栏样式",
"TaskbarMonitor": "显示器屏幕",
"TaskbarMonitorSettings": "显示屏选择",
"TaskbarMonitorTip": "可勾选任务栏显示在哪些屏幕上;勾选“自动模式”时,将只跟随主屏任务栏。",
"TaskbarAllScreens": "所有屏幕都显示",
"TaskbarStyleBold": "大字模式",
"TaskbarStyleRegular": "小字模式",
"TaskbarAlign": "显示位置",
Expand Down Expand Up @@ -240,4 +243,4 @@
"PluginAddTarget": "+ 添加新监控目标",
"PluginDeleteConfirm": "确定要删除此插件副本吗?"
}
}
}
5 changes: 5 additions & 0 deletions src/Core/Actions/SettingsChanger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public static void Merge(Settings live, Settings draft)
live.PluginInstances = System.Text.Json.JsonSerializer.Deserialize<List<PluginInstanceConfig>>(json) ?? new List<PluginInstanceConfig>();
continue;
}
if (p.Name == "TaskbarMonitorDevices")
{
live.TaskbarMonitorDevices = new List<string>(draft.TaskbarMonitorDevices ?? new List<string>());
continue;
}
if (p.Name == "Thresholds")
{
// 阈值是 Class 类型 (ThresholdsSet),必须深拷贝
Expand Down
2 changes: 2 additions & 0 deletions src/Core/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public class Settings

// ★★★ 新增:指定任务栏显示的屏幕设备名 ("" = 自动/主屏) ★★★
public string TaskbarMonitorDevice { get; set; } = "";
public List<string> TaskbarMonitorDevices { get; set; } = new List<string>();
public bool TaskbarShowOnAllScreens { get; set; } = false;

// 任务栏行为配置
public bool TaskbarClickThrough { get; set; } = false; // 鼠标穿透
Expand Down
42 changes: 40 additions & 2 deletions src/System/HardwareMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ private void InitializeAsync()
_perfCounterManager.InitializeAsync();

// 这句耗时 4-5 秒,但在执行过程中,硬件会陆续添加到 _computer.Hardware
_computer.Open();
OpenComputerSafe();

// ★★★ T0+级修复:彻底禁用历史记录,解决 SensorValue[] 飙升 ★★★
// 必须在 Open() 之后调用,此时传感器才被创建
Expand Down Expand Up @@ -442,7 +442,7 @@ private void ReloadComputerSafe()
_computer.Hardware.Clear();
}

_computer.Open();
OpenComputerSafe();

DisableSensorHistory();
}
Expand All @@ -467,6 +467,44 @@ private void DisableSensorHistory()
catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[MemoryFix] Failed: {ex.Message}"); }
}

private void OpenComputerSafe()
{
try
{
_computer.Open();
}
catch (ArgumentNullException ex) when (IsMutexBootstrapFailure(ex))
{
System.Diagnostics.Debug.WriteLine($"[HardwareMonitor] Computer.Open mutex bootstrap failed, retrying in compatibility mode: {ex.Message}");
OpenComputerWithoutMutex();
}
}

private void OpenComputerWithoutMutex()
{
var type = typeof(Computer);
var addGroups = type.GetMethod("AddGroups", BindingFlags.Instance | BindingFlags.NonPublic);
var openField = type.GetField("_open", BindingFlags.Instance | BindingFlags.NonPublic);

if (addGroups == null || openField == null)
throw new MissingMemberException("LibreHardwareMonitor compatibility entry points were not found.");

bool isOpen = openField.GetValue(_computer) as bool? ?? false;
if (!isOpen)
{
addGroups.Invoke(_computer, null);
openField.SetValue(_computer, true);
}
}

private static bool IsMutexBootstrapFailure(ArgumentNullException ex)
{
if (!string.Equals(ex.ParamName, "identity", StringComparison.OrdinalIgnoreCase))
return false;

return ex.StackTrace?.Contains("LibreHardwareMonitor.Hardware.Mutexes", StringComparison.Ordinal) == true;
}

// 递归更新子硬件,确保 SuperIO 刷新
private void UpdateWithSubHardware(IHardware hw)
{
Expand Down
39 changes: 36 additions & 3 deletions src/System/HardwareServices/HardwareRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ public static int GetHwPriority(IHardware hw)
// 3. AMD 显卡
if (hw.HardwareType == HardwareType.GpuAmd)
{
// 通用名 "AMD Radeon(TM) Graphics" 通常是核显 -> 优先级 2
if (name.Equals("AMD Radeon(TM) Graphics", StringComparison.OrdinalIgnoreCase)) return 2;
// 其他具体型号 (如 RX 7900 XTX) 视为独显 -> 优先级 0
// AMD 核显常见命名:Radeon(TM) Graphics / 610M / 780M / Vega 等
// 这类设备应低于独显,避免覆盖独显的 GPU.Load 映射
if (IsAmdIntegratedGpu(name)) return 2;

// 其他具体型号 (如 RX 7900 XTX / RX 7600M) 视为独显 -> 优先级 0
return 0;
}

Expand Down Expand Up @@ -77,6 +79,37 @@ public static bool IsDiscreteArc(string name)
return Has(name, " A") || Has(name, " B") || Has(name, " Pro");
}

private static bool IsAmdIntegratedGpu(string name)
{
if (string.IsNullOrEmpty(name)) return false;

if (name.Equals("AMD Radeon(TM) Graphics", StringComparison.OrdinalIgnoreCase))
return true;

// 独显关键字:RX / PRO / FIREPRO 优先视作独显
if (Has(name, "rx") || Has(name, "pro") || Has(name, "firepro"))
return false;

// 常见核显命名关键字
if (Has(name, "vega")) return true;
if (Has(name, "radeon") && Has(name, "graphics")) return true;

if (Has(name, "radeon"))
{
// 典型 RDNA 核显尾缀(610M/660M/680M/760M/780M/880M/890M)
string[] igpuTokens = { "610m", "660m", "680m", "760m", "780m", "880m", "890m" };
foreach (var token in igpuTokens)
{
if (Has(name, token)) return true;
}

// 没有 RX/PRO/FIREPRO 且标记为 Radeon(TM),大概率为核显
if (Has(name, "radeon(tm)")) return true;
}

return false;
}

/// <summary>
/// 判断是否应该使用共享内存 (Shared Memory)
/// </summary>
Expand Down
Loading