Skip to content

Releases: nojackno2-ctrl/WinBat-Lens

WinBat Lens v1.1.2

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 03 Aug 01:38
4dc33ad

📈 WinBat Lens v1.1.2

工程可靠性與效能

  • 升級至 .NET 10 LTS,並同步更新 Release、Inno Setup 與發行腳本路徑。
  • 即時硬體取樣移至背景工作,避免 WMI、GPU Performance Counter 或 DXGI 延遲阻塞 WPF UI。
  • 視窗顯示時維持 1 秒取樣;縮至系統托盤後改為 5 秒,並保留恢復時的最新快照。
  • 新增 BatteryReportParser 單元測試與 Windows GitHub Actions CI。
  • README 改為只描述能由目前硬體 API 證明的資料,移除變壓器額定瓦數與虛構系統總功耗敘述。

發行注意事項

v1.1.2 的 EXE 與安裝程式仍需在發行環境提供 Authenticode 憑證或簽章服務後簽署。未簽章檔案可能觸發 Windows SmartScreen 提示;簽章流程會驗證檔案並加入 RFC 3161 時間戳。

📈 WinBat Lens v1.1.1

波形圖的放電、充電與獨顯功耗現在共用同一個瓦數刻度。移除獨顯專用的右側刻度後,相同高度永遠代表相同 W,能直接比較整機電池放電與獨顯功耗。


🔌 WinBat Lens v1.1.0

USB-C 充電:能量到的量到底,量不到的說清楚 —— 順便修掉一個把最關鍵數字藏起來的 bug。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.1.0_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.1.0_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.1.0_Portable_x64.zip 71.0 MB

🐛 修正:插著電卻還在放電,之前完全看不見

這是本版最重要的修正。

RealTimePowerService 過去只在 !IsAcOnline 時才讀放電功率。所以「充電器帶不動、電池邊插邊掉」這個狀態,會落進「市電直供、電池未充放電」那條分支,畫面顯示 -- W、狀態寫「無可量測功率」。

而那正是用 USB-C 充電時最該看到的數字 —— 65W 的 PD 充電器撐不住一台吃更多瓦的機器,電池就默默補上差額,App 卻把它藏起來。

現在會標記為 IsChargerDeficit,缺口以實測放電瓦數呈現,並一致貫穿:

  • 主數字改為 -X.X W
  • 狀態徽章顯示「外接電源供電不足 — 電池補上 -X.X W(電池實測)」,配色為玫瑰紅(電真的在從電池流出,綠色會是謊話)
  • 60 秒波形圖的放電線正常繪出,不再是一條零
  • 工作列圖示顯示紅色瓦數、提示文字標註 (charger too weak)
  • 歷史紀錄不再自相矛盾(過去會寫「市電正常」卻同時記著非零放電),改記「⚠️ 外接電源不足」
  • 剩餘時間改由「電池剩餘 Wh ÷ 實測缺口」計算
  • BatteryCurrentA 跟著實際電流方向走,不再假設「在 AC 上就是充電」

🔋 新增:Windows 對充電器的供電判定

新的 PowerSupplyService 讀取 Windows.System.Power.PowerManager.PowerSupplyStatus —— Windows 唯一一個描述充電器本身而非電池的官方、免提權訊號:

顯示
Adequate 🔌 外接電源供電充足
Inadequate ⚠️ 外接電源供電能力不足以支撐目前的系統負載(琥珀色警示)
NotPresent / 讀取失敗 整列隱藏,不顯示佔位文字

手寫 WinRT activation(一個 IID、一個 vtable slot)而非 C# projection:projection 需要把目標框架換成 net8.0-windows10.0.x,會把整包 Windows SDK projection 組件塞進這個有在調校體積與冷啟動時間的 single-file bundle。實測讀取成本 0.022 µs,因此每秒直接讀取、不做快取。


❌ 為什麼沒有「變壓器 / 充電器瓦數」

會想要的是 USB-C Power Delivery 協商出來的電壓電流,也就是真正的充電器瓦數。在一般使用者權限的 Windows 程式裡拿不到。 這不是推測,是對實機(ASUS ROG Zephyrus G14,當時正以 USB-C 供電)逐條驗證的結果:

管道 結果
UCM-UCSI ACPI 裝置 (ACPI\USBC000\0) 存在,但它註冊的兩個 device interface 完全不在公開 SDK 中 —— 驅動對驅動用,沒有文件化的使用者模式 IOCTL
BATTERY_USB_CHARGER_STATUS (poclass.h) 確實帶有 PD 合約旗標、埠的 mA 與 mV,但走 IOCTL_BATTERY_SET_INFORMATION 寫入方向,由這類筆電沒有的 Charging Arbitration Driver 推入。不存在對應的查詢層級
POWER_ADAPTER_STATUS.MaxOutputPower 就是額定瓦數,但 batclass.h 僅透過核心模式 adapter miniclass callback 提供;ACPI\ACPI0003 上的通用 Microsoft AC Adapter 驅動不提供
電池 Customized I/O(OEM 專用逃生口) 實測回報 SupportedInputs = 0SupportedOutputs = 0 —— 什麼都沒開放
ASUS ATK WMI (AsusAtkWmi_WMNB / DSTS) ROG 機種確實知道充電來源,但每次查詢皆「拒絕存取」,需要提權,而本程式刻意不提權執行

所以整個儀表板不會出現任何變壓器瓦數。這與本專案一貫的原則一致:量不到的數字就不顯示,而不是估一個看起來合理的。 上面兩項新增的都是實測值。


⚙️ 相容性與成本

  • 穩態 CPU 佔用維持 2.8% / 單核,與前一版相同 —— 新增的讀取在量測誤差之內。
  • 目標框架、封裝方式、體積策略皆未變動。
  • 不支援 PowerManager 的環境會靜默降級:該列隱藏,其餘功能不受影響。

📈 WinBat Lens v1.1.1 — 波形圖共用瓦數刻度

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 02 Aug 09:30

📈 波形圖改用共用瓦數刻度

放電、充電與獨顯功耗現在共用同一個 W 軸;右側獨顯專用刻度已移除。相同高度現在永遠代表相同瓦數,可直接比較整機電池放電與獨顯功耗。

下載

類型 檔案
安裝版 WinBatLens_v1.1.1_Setup_x64.exe
免安裝單一執行檔 WinBatLens_v1.1.1_Portable_x64.exe
免安裝 ZIP WinBatLens_v1.1.1_Portable_x64.zip

SHA-256

  • Portable EXE: 3B0B3513ABD37F2EB3552002FD4F7DE695416709F66E29981A6A50BDD7E8279A
  • Portable ZIP: 553F082B27CB8F9F281F196FC409F86F3F146F1B0F1B4BBC5394F2BD01EDEC33
  • Setup EXE: E60F1A7C8C730AFD9E1B49584258B72FAF4BBB450A549F1CF8A138A440C8436E

目前執行檔尚未使用程式碼簽章憑證簽署;Windows SmartScreen 可能顯示未知發行者警告。

🔌 WinBat Lens v1.1.0 — USB-C 充電:量得到的量到底,量不到的說清楚

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 02 Aug 02:23

🔌 WinBat Lens v1.1.0

USB-C 充電:能量到的量到底,量不到的說清楚 —— 順便修掉一個把最關鍵數字藏起來的 bug。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.1.0_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.1.0_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.1.0_Portable_x64.zip 71.0 MB

🐛 修正:插著電卻還在放電,之前完全看不見

這是本版最重要的修正。

RealTimePowerService 過去只在 !IsAcOnline 時才讀放電功率。所以「充電器帶不動、電池邊插邊掉」這個狀態,會落進「市電直供、電池未充放電」那條分支,畫面顯示 -- W、狀態寫「無可量測功率」。

而那正是用 USB-C 充電時最該看到的數字 —— 65W 的 PD 充電器撐不住一台吃更多瓦的機器,電池就默默補上差額,App 卻把它藏起來。

現在會標記為 IsChargerDeficit,缺口以實測放電瓦數呈現,並一致貫穿:

  • 主數字改為 -X.X W
  • 狀態徽章顯示「外接電源供電不足 — 電池補上 -X.X W(電池實測)」,配色為玫瑰紅(電真的在從電池流出,綠色會是謊話)
  • 60 秒波形圖的放電線正常繪出,不再是一條零
  • 工作列圖示顯示紅色瓦數、提示文字標註 (charger too weak)
  • 歷史紀錄不再自相矛盾(過去會寫「市電正常」卻同時記著非零放電),改記「⚠️ 外接電源不足」
  • 剩餘時間改由「電池剩餘 Wh ÷ 實測缺口」計算
  • BatteryCurrentA 跟著實際電流方向走,不再假設「在 AC 上就是充電」

🔋 新增:Windows 對充電器的供電判定

新的 PowerSupplyService 讀取 Windows.System.Power.PowerManager.PowerSupplyStatus —— Windows 唯一一個描述充電器本身而非電池的官方、免提權訊號:

顯示
Adequate 🔌 外接電源供電充足
Inadequate ⚠️ 外接電源供電能力不足以支撐目前的系統負載(琥珀色警示)
NotPresent / 讀取失敗 整列隱藏,不顯示佔位文字

手寫 WinRT activation(一個 IID、一個 vtable slot)而非 C# projection:projection 需要把目標框架換成 net8.0-windows10.0.x,會把整包 Windows SDK projection 組件塞進這個有在調校體積與冷啟動時間的 single-file bundle。實測讀取成本 0.022 µs,因此每秒直接讀取、不做快取。


❌ 為什麼沒有「變壓器 / 充電器瓦數」

會想要的是 USB-C Power Delivery 協商出來的電壓電流,也就是真正的充電器瓦數。在一般使用者權限的 Windows 程式裡拿不到。 這不是推測,是對實機(ASUS ROG Zephyrus G14,當時正以 USB-C 供電)逐條驗證的結果:

管道 結果
UCM-UCSI ACPI 裝置 (ACPI\USBC000\0) 存在,但它註冊的兩個 device interface 完全不在公開 SDK 中 —— 驅動對驅動用,沒有文件化的使用者模式 IOCTL
BATTERY_USB_CHARGER_STATUS (poclass.h) 確實帶有 PD 合約旗標、埠的 mA 與 mV,但走 IOCTL_BATTERY_SET_INFORMATION 寫入方向,由這類筆電沒有的 Charging Arbitration Driver 推入。不存在對應的查詢層級
POWER_ADAPTER_STATUS.MaxOutputPower 就是額定瓦數,但 batclass.h 僅透過核心模式 adapter miniclass callback 提供;ACPI\ACPI0003 上的通用 Microsoft AC Adapter 驅動不提供
電池 Customized I/O(OEM 專用逃生口) 實測回報 SupportedInputs = 0SupportedOutputs = 0 —— 什麼都沒開放
ASUS ATK WMI (AsusAtkWmi_WMNB / DSTS) ROG 機種確實知道充電來源,但每次查詢皆「拒絕存取」,需要提權,而本程式刻意不提權執行

所以整個儀表板不會出現任何變壓器瓦數。這與本專案一貫的原則一致:量不到的數字就不顯示,而不是估一個看起來合理的。 上面兩項新增的都是實測值。


⚙️ 相容性與成本

  • 穩態 CPU 佔用維持 2.8% / 單核,與前一版相同 —— 新增的讀取在量測誤差之內。
  • 目標框架、封裝方式、體積策略皆未變動。
  • 不支援 PowerManager 的環境會靜默降級:該列隱藏,其餘功能不受影響。

🔋 WinBat Lens v1.0.9 — 接上電池驅動的第三個 IOCTL

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 27 Jul 01:24

🔋 WinBat Lens v1.0.9

接上電池驅動的第三個 IOCTL —— 過去只用了兩個,最有價值的那個一直沒被呼叫。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.9_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.9_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.9_Portable_x64.zip 71.0 MB

🔌 問題:只用了三分之二的電池 API

BatteryTelemetryService 只呼叫 IOCTL_BATTERY_QUERY_TAGIOCTL_BATTERY_QUERY_STATUS。第三個 IOCTL_BATTERY_QUERY_INFORMATION 從未使用,而驅動知道的大部分資訊都在裡面。同時 BATTERY_STATUS.Capacity(剩餘容量 mWh)已經讀進 struct 卻被丟掉。

這些全是直接對已開啟的裝置 handle 下 IOCTL:不需提權、不經 WMI、不走 COM。

✅ 現在讀得到什麼

項目 來源
剩餘容量 (mWh)、真實 SoC BATTERY_STATUS.Capacity
設計 / 滿電容量、健康度 BatteryInformation
化學材質、電池名稱、製造商 BatteryInformation / BatteryDeviceName / BatteryManufactureName
循環次數 BatteryInformation
出廠日期與電池役齡 BatteryManufactureDate
電池封裝溫度 BatteryTemperature
驅動自身的續航估算 BatteryEstimatedTime

韌體沒實作的層級連續失敗 3 次後就永久停止查詢,因此不支援的項目只花啟動時 3 次 IOCTL,之後零成本。

📊 powercfg 報告的容量是舊的

並排量測:報告 55,969 mWh,驅動 56,032 mWh。 報告是 Windows 稍早記錄的快照,驅動才是當下的值。解析器現在優先採用驅動數值,健康度因此從 73.6% 修正為 73.7%、損耗從 20,029 修正為 19,966 mWh。

附帶效果:powercfg 報告空白或無法解析的機器,現在依然能得到真實健康度,不會再被誤判成「無電池裝置」。

手動開啟的 HTML 報告不會套用本機驅動資料 —— 那份報告可能來自另一台電腦。

🔧 移除寫死的 56 Wh 電池容量

充飽時間原本是 (100 − 電量%) / 100 × 56.0 ÷ 充電瓦數,把開發用筆電的容量寫死在公式裡,換一台機器就不對。現在改為 (滿電容量 − 目前容量) ÷ 充電瓦數,兩項都是實測值。

剩餘續航在 Windows 尚未給出估算時(拔除電源後約一分鐘內)多了兩層後備:驅動自身的估算,以及「剩餘 Wh ÷ 目前放電瓦數」。後者是兩個實測值的除法,不是負載推估曲線。

電量百分比改用電池自己的 容量 ÷ 滿電容量,充電上限停在 95% 的機器會顯示 95.0%,不再被四捨五入成「已充滿」。

🌡️ 這次的溫度是真的

舊版曾把 CPU 熱區當成電池溫度顯示(v1.0.3 已移除)。BatteryTemperature 是電池自己的感測器,換算自 0.1 K 單位,並排除 -40..80 °C 以外的數值 —— 沒有真正實作該層級的韌體通常回 0,否則會變成看起來很合理的 -273 °C。

開發用的這台機器並不支援。 程式碼保留,因為它在支援的硬體上正確且幾乎免費。畫面上不會出現任何永久空白:溫度、出廠日期、蓄電量三者都是讀不到就整列隱藏或改為說明文字。

🖥️ 介面

  • 電池規格參數:新增「出廠日期」列(含役齡年數),驅動沒提供時隱藏;容量、化學材質、循環次數改以驅動值為準。
  • 剩餘續航卡:電量列附上真實蓄電量,例如 100% · 56.0 / 56.0 Wh
  • 硬體實測功耗:新增「電池蓄電量 (Wh)」列,顯示 56.0 / 56.0 Wh真實 SoC 100.0%,副標為 滿電 56.0 / 76.0 Wh,健康度 73.7%
  • 智慧診斷:循環次數空白時明確說明是韌體未實作而非讀取失敗;有出廠日期時新增電池役齡項目。

📈 兩個順手修正

波形圖的電池線被獨顯壓扁。 Y 軸取三條線的最大值,獨顯滿載 76 W 時軸上限跳到 92 W,充放電線被壓在底部貼地。現在電池與獨顯各自縮放,獨顯改用右側青色刻度(與獨顯線、圖例同色),沒有量測到獨顯瓦數時整條右軸隱藏。

容量歷史的整數健康度沒對齊。 74.0 在一整欄 73.6 之中會顯示成 74,已改為固定一位小數。

🎨 WinBat Lens v1.0.8 — 統一充放電配色

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 25 Jul 16:39

🎨 WinBat Lens v1.0.8

統一充放電配色 —— 同一個意義,在任何地方都是同一個顏色。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.8_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.8_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.8_Portable_x64.zip 71.0 MB

🎨 問題:放電有三種顏色,而且跟獨顯撞色

顯示位置 放電(修正前) 獨顯(修正前)
主數字 琥珀 #F59E0B
圖表線 / 圖例 #38BDF8 琥珀 #F59E0B
托盤圖示 #EF4444

同一個「放電」換了三次顏色;更糟的是主數字的琥珀色和圖表上的琥珀線代表兩件不同的事 —— 一個是電池放電,一個是獨顯功耗。

✅ 修正後

意義 顏色 套用範圍
放電 琥珀 #F59E0B 主數字、圖表線、圖例、托盤圖示
充電 #10B981 同上
獨顯 #38BDF8 圖表線、圖例

充電本來就全部是綠色,沒有改動。放電選琥珀是因為主數字是最常被看的地方;獨顯則接手空出來的青色。

🗑️ 順手清掉

  • CPU 折線:自 v1.0.5 移除 CPU 功耗後,這條紫色虛線就一直平貼在 0,等於一條假線。
  • 圖例上多餘的紫色色塊:更早之前刪掉文字時漏掉的 Border,變成一個沒有標籤的孤兒色塊。
  • 圖表歷史資料的 tuple 也跟著少一個欄位(4 → 3)。

目前畫面上的瓦數仍是三個

項目 來源
電池放電 IOCTL_BATTERY_QUERY_STATUS
電池充電 同上
獨顯功耗 NVML

執行檔未經數位簽章,首次執行 SmartScreen 會警告,請點「其他資訊」→「仍要執行」。

完整差異: v1.0.7...v1.0.8

🗑️ WinBat Lens v1.0.7 — 移除系統顯示卡清單

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 25 Jul 15:59

🗑️ WinBat Lens v1.0.7

移除「系統顯示卡清單」卡片,以及所有只為它存在的程式碼。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.7_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.7_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.7_Portable_x64.zip 71.0 MB

移除的內容

「系統顯示卡清單」列的是顯示卡名稱、顯示記憶體、驅動版本與發布日期 —— 那是硬體清單資料,不是功耗,而且程式裡沒有任何其他地方用到它。

刪掉卡片後,一整串只為它存在的程式碼也跟著清掉:

  • GpuInfo 模型:移除 GpuTypeTagVramTextDriverVersionDriverDateStatusStatusClass。只留下 NameIsDiscreteVramBytes —— 最後一項純粹是因為判斷獨顯的邏輯要拿它跟 1 GB 比較。
  • GpuInfoServiceWin32_VideoController 查詢不再撈 DriverVersionDriverDateStatusAvailability,也不再組字串。啟動時的 WMI 查詢更輕。
  • RealTimePowerService.InstalledGpus:這個公開屬性只為餵那張卡片而存在,已移除。內部的顯示卡清單保留,因為獨顯/內顯名稱還要用。
  • MainWindow.LoadGpuSpecs()GpuListTitle 語系字串一併刪除。

淨減 83 行

順手修掉的文案錯誤

底部提示框還寫著「即時監測每 1 秒自動更新一次 CPU、獨顯、內顯、螢幕背光、Wi-Fi、磁碟與記憶體功耗」—— 這在 v1.0.6 移除那些列之後就已經不是事實了。現在改為「即時監測每 1 秒自動更新一次。」


目前畫面上的瓦數仍是三個

項目 來源
電池放電 IOCTL_BATTERY_QUERY_STATUS
電池充電 同上
獨顯功耗 NVML

執行檔未經數位簽章,首次執行 SmartScreen 會警告,請點「其他資訊」→「仍要執行」。

完整差異: v1.0.6...v1.0.7

🔋 WinBat Lens v1.0.6 — 修正充電瓦數未顯示、移除無法量測的元件列

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 25 Jul 15:20

🔋 WinBat Lens v1.0.6

修正:充電時主畫面顯示 0.0 W 的錯誤。 同時移除無法量測功耗的元件列。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.6_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.6_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.6_Portable_x64.zip 71.0 MB

🐛 修正:充電中卻顯示 0.0 W

v1.0.5 移除推估值時,刪掉了 TotalSystemHardwareWAcTotalInputW賦值,卻漏掉欄位本身和 6 處介面引用。這兩個值因此永遠是 0 —— 接電源時主卡片就顯示 ~0.0 W,即使副標題上明明已經印出 電池充電 +56.1W 實測

現在主數字改為顯示真正量到的那一個

狀態 主畫面顯示
充電中 +56.1 W(綠色)
電池放電中 -48.9 W(琥珀色)
接電源、電池靜止 -- W

托盤圖示與提示文字有相同問題,一併修正(沒有可量測數值時顯示灰色的 )。托盤圖示的重繪快取原本以「是否接電源」為判斷鍵,但顏色已不再由它決定,現在改用實際繪製的文字+顏色,避免數字沒變但顏色該變時沒有重繪。

主卡片標題也從「電池總放電 / AC 變壓器總供電功率」改為 「電池充放電功率 (實測)」 —— 它從來沒有、將來也不會顯示變壓器功率。

🗑️ 移除無法量測功耗的元件列

既然量不到功耗,放在功耗頁面上就沒有意義。已移除:CPU、內顯、螢幕、Wi-Fi、硬碟、記憶體

只保留獨立顯示卡,因為 NVML 能給出真實瓦數。

這些元件的使用率仍在背景收集,系統負載評級與歷史紀錄照常運作,只是不再出現在談瓦數的頁面上。頁面下方會直接說明每個元件缺席的原因。區塊標題改為 「硬體實測功耗」


✅ 目前畫面上的每個瓦數

項目 來源
電池放電功率 IOCTL_BATTERY_QUERY_STATUS
電池充電功率 同上(本版實測 54.5 W
獨顯功耗 NVML

沒有第四個。


執行檔未經數位簽章,首次執行 SmartScreen 會警告,請點「其他資訊」→「仍要執行」。

完整差異: v1.0.5...v1.0.6

🔋 WinBat Lens v1.0.5 — 移除所有推估數值,只留真實量測

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 25 Jul 14:45

🔋 WinBat Lens v1.0.5

所有推估的瓦數全部移除。 現在畫面上出現的每一個瓦數,都是真的從硬體讀出來的。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.5_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.5_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.5_Portable_x64.zip 71.0 MB

🗑️ 刪掉的東西

之前這些「功耗」全都是拿使用率去套線性公式算出來的,不是量測值:

已移除 原本的公式
CPU 功耗 2.5 + 使用率 × 22.5
內顯功耗 1.0 + 使用率 × 12.0
螢幕功耗 1.0 + 亮度 × 5.5
硬碟功耗 0.4 + 使用率 × 3.2
Wi-Fi 功耗 0.6 + 流量換算
記憶體功耗 0.8 + 使用率 × 1.7
主機板功耗 寫死的 2.5,完全沒有資料來源
全系統總功耗 以上全部加總
AC 變壓器輸入 充電功率 + 上述總和

「主機板與 USB 外設」那一列因為完全沒有真實資料,整列從介面移除。波形圖的 CPU (W) 曲線與圖例也一併拿掉。

CPU、內顯、螢幕、硬碟、Wi-Fi、記憶體這幾列保留 —— 它們的使用率、傳輸量、亮度、容量都是真的量測值,只是把那行編造的瓦數拿掉。

✅ 留下來的三個瓦數,全部來自硬體

  • 電池放電功率IOCTL_BATTERY_QUERY_STATUS 直接讀電池驅動。實測驗證:電池供電時讀到 48.9 W,這是整台機器的真實耗電
  • 電池充電功率 — 同一個 IOCTL。
  • 獨立顯卡功耗 — NVML,免管理員權限。

其餘一律顯示 -- W,並在提示文字說明原因,而不是填一個看起來合理的數字。


⚠️ 你會注意到的改變

接著市電時,現在不再顯示任何系統瓦數。

這是正確的,不是功能退步。電池滿電接電源時沒有任何電流進出,而變壓器輸入功率屬於各家 EC 的私有實作,Windows 完全沒有提供 API(這也是為什麼原廠工具讀得到、第三方讀不到)。舊版就是用一個編造的數字填補這個空缺。

此時提示會直接說明:

市電直供中,電池無充放電電流,此狀態下沒有可量測的系統功率(變壓器輸入功率 Windows 並未提供)。

想看整機真實耗電,請拔掉變壓器 —— 電池會誠實告訴你答案。


🔧 其他

  • 「全系統功耗評級」改名為「系統負載評級」,改用使用率判定(原本混入了已刪除的推估總功耗)
  • CSV 匯出的「螢幕功耗(W)」欄(推估值)換成「獨顯功耗(W)」(NVML 實測值)

執行檔未經數位簽章,首次執行 SmartScreen 會警告,請點「其他資訊」→「仍要執行」。

完整差異: v1.0.4...v1.0.5

🔋 WinBat Lens v1.0.4 — 電池充放電瓦數改為真實量測

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 25 Jul 14:12

⚡ WinBat Lens v1.0.4

電池充放電瓦數現在是真實量測值了。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.4_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.4_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.4_Portable_x64.zip 71.0 MB

🔋 核心修正:電池瓦數一直都讀得到,是程式問錯地方

程式原本讀 Win32_Battery.DischargeRateroot\CIMV2)—— 這個屬性在本機和許多筆電上是空的。但 root\WMI BatteryStatus 和底層的 IOCTL_BATTERY_QUERY_STATUS 一直都正常運作。

換句話說,電池明明有回報真實數值,程式卻退回去用推估值。

之前判斷「EC 不支援」是錯的

所有先前的測試都是在電池滿電且插著電源的狀態下做的。RemainingCapacity 等於 FullChargedCapacity,此時電池沒有任何電流進出 —— 0 mW 就是正確答案,卻被誤判成「不支援」。

關鍵線索是:驅動回傳的是實實在在的 0,而不是規格保留給「真的讀不到」的 BATTERY_UNKNOWN_RATE0x80000000)。

拔掉電源實測後完全證實:

21:54:24  電池  放電中   -5.51 W    ← 剛拔電、閒置
21:54:38  電池  放電中  -22.29 W
21:54:57  電池  放電中  -30.91 W
21:58:45  電池  放電中  -39.90 W    ← 負載上升
21:58:51  市電            0.00 W    ← 插回電源

✨ 新增 BatteryTelemetryService

直接對電池類別驅動下 IOCTL_BATTERY_QUERY_STATUS

  • 不需要系統管理員權限,也不經過 WMI/COM
  • 實測每次讀取 平均 0.4 ms(對照 LibreHardwareMonitor 掃描要 85~256 ms),因此可以安心地每秒更新
  • 電壓在同一次呼叫就取得,省掉一次 WMI 查詢
  • IsRateKnown 區分「真的是 0」與「讀不到」,確保這個 bug 不會重演
  • 方向以驅動的充/放電旗標判定並取絕對值(不是每家驅動都遵守「負值代表放電」的慣例)

🎯 電池供電時,數字是整台機器的真實耗電

這個值直接量測自電池本身,不做任何元件加總推估。同時也巧妙繞過了 v1.0.3 遇到的問題 —— CPU 功耗因為 Armoury Crate 佔用 AMD SMU 而讀不到。

🧹 順手移除另外兩個編造的數值

  • 充電瓦數原本會依電量退回寫死的 12.5 / 28.0 / 45.0 W。現在讀不到就顯示 --
  • 是否充電原本用 電量 >= 98% 推斷。這在有充電上限的筆電上是錯的 —— 本機約 95% 就停止充電,舊邏輯會誤判成「仍在充電」。現在改用驅動本身的充電旗標。

⚠️ 市電輸入瓦數仍是推估值

Windows 沒有任何標準 API 可以讀變壓器輸入功率,那屬於各家 EC 的私有實作(所以原廠工具讀得到,第三方讀不到)。此數值維持為「充電功率 + 硬體推估」,並以 ~ 明確標示。


執行檔未經數位簽章,首次執行 SmartScreen 會警告,請點「其他資訊」→「仍要執行」。

完整差異: v1.0.3...v1.0.4

⚡ WinBat Lens v1.0.3 — 改用真實硬體感測器、移除偽造的電池溫度

Choose a tag to compare

@nojackno2-ctrl nojackno2-ctrl released this 25 Jul 13:12

⚡ WinBat Lens v1.0.3

這一版修正了兩個真實的數據錯誤。 起因是使用者發現跑 3DMark 時,本程式顯示的瓦數與 ASUS Armoury Crate 對不上 —— 確實對不上,而且原因有兩個。


📥 下載

版本 檔案 大小
安裝版 WinBatLens_v1.0.3_Setup_x64.exe 71.8 MB
免安裝版(單一執行檔) WinBatLens_v1.0.3_Portable_x64.exe 76.7 MB
免安裝版(ZIP) WinBatLens_v1.0.3_Portable_x64.zip 71.0 MB

❌ 錯誤一:所有瓦數都是「用使用率套公式猜的」

程式碼裡沒有任何一個瓦數是量測來的。用當時的截圖反推可以完全吻合:

dGPU: 3.0 + 0.869 × 35.0 = 33.4 W   ← 畫面顯示 ~33.4 W
CPU : 2.5 + 0.184 × 22.5 =  6.6 W   ← 畫面顯示 ~6.6 W

而且公式有寫死的天花板:dGPU 最高只能算到 38 W,全系統最高 93.5 W。這台的 RTX 3060 Laptop 光 GPU 的 TGP 就能到 115 W(當下 Armoury Crate 顯示 60 W)。更明顯的是,閒置時公式直接回報 0 W,但 nvidia-smi 實測是 18.76 W

❌ 錯誤二:「電池溫度」其實是 CPU 溫度

該數值來自 Win32_PerfFormattedData_Counters_ThermalZoneInformation,這台機器上唯一的熱感測區是 \_TZ.THRM,卻被標示成「🔋 電池物理狀態(電壓/電流/溫度)」,副標還寫「WMI & ACPI 即時電氣感測」。

截圖當下顯示「電池」81.1 °C,而 Armoury Crate 顯示 CPU 81 °C —— 同一個數字。鋰電池到 81 °C 早就起火了。

真正的電池溫度來源(MSAcpi_ThermalZoneTemperatureMSBatteryClass)在這台機器上拿不到,因此溫度顯示已完全移除,而非改標示 —— 卡片、清單欄位、CSV 欄位、中英文字串全部拿掉。


✅ 改用真實硬體感測器

新增 HardwareSensorService,整合 LibreHardwareMonitor。每個讀數都是可為空的:取不到就明確標示為推估,絕不編造數字。

本機(Ryzen + RTX 3060 Laptop)一般權限下的實測結果:

感測器 結果
NVIDIA GPU 功耗 真實,11~19 W 即時跟隨
GPU 核心 / 熱點溫度 ✅ 真實
電池電壓 ✅ 15.83 V
CPU 功耗 ❌ RAPL 需要核心驅動(需系統管理員權限)
AMD 內顯功耗 ❌ 硬體根本沒有此感測器

畫面上現在會明確區分:

18.8 W (實測)   ← 來自硬體感測器
~6.6 W (推估)   ← 來自使用率公式

🔧 過程中量測到的三件事

  1. 一次完整感測掃描要 85~256 ms —— 絕不能放在每秒一次的 UI 執行緒上。已改為背景執行緒輪詢,UI 只讀快取,成本降到 0.003 ms
  2. CPU 硬體更新是掃描中最慢的部分,而在拿不到 RAPL 時毫無意義,因此偵測到不可用就直接跳過。
  3. 每個感測器預設會保留一整天的歷史數值 —— 以 1 Hz 輪詢約 40 個感測器,3 分鐘內私有記憶體就從 139 MB 漲到 159 MB。關閉歷史保留後穩定在 ~139 MB,托盤背景工作集甚至降到 23.8 MB(比上一版的 26.4 MB 更好)。

啟動速度僅從 ~373 ms 變成 ~383 ms,因為感測器初始化(約 1 秒)掛在既有的背景預熱執行緒上,不影響首次繪製。


⚠️ 已知限制

CPU 功耗仍為推估值。 Intel/AMD 的 RAPL 需要核心驅動,也就是需要以系統管理員權限執行。要讓它變成實測值,代價是每次啟動都跳 UAC,而且會讓開機自動啟動的登錄設定變複雜 —— 這是產品取捨,尚未決定。

執行檔未經數位簽章,首次執行 SmartScreen 會警告,請點「其他資訊」→「仍要執行」。


完整差異: v1.0.2...v1.0.3