Releases: nojackno2-ctrl/WinBat-Lens
Release list
WinBat Lens v1.1.2
📈 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 = 0、SupportedOutputs = 0 —— 什麼都沒開放 |
ASUS ATK WMI (AsusAtkWmi_WMNB / DSTS) |
ROG 機種確實知道充電來源,但每次查詢皆「拒絕存取」,需要提權,而本程式刻意不提權執行 |
所以整個儀表板不會出現任何變壓器瓦數。這與本專案一貫的原則一致:量不到的數字就不顯示,而不是估一個看起來合理的。 上面兩項新增的都是實測值。
⚙️ 相容性與成本
- 穩態 CPU 佔用維持 2.8% / 單核,與前一版相同 —— 新增的讀取在量測誤差之內。
- 目標框架、封裝方式、體積策略皆未變動。
- 不支援
PowerManager的環境會靜默降級:該列隱藏,其餘功能不受影響。
📈 WinBat Lens v1.1.1 — 波形圖共用瓦數刻度
📈 波形圖改用共用瓦數刻度
放電、充電與獨顯功耗現在共用同一個 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 充電:量得到的量到底,量不到的說清楚
🔌 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 = 0、SupportedOutputs = 0 —— 什麼都沒開放 |
ASUS ATK WMI (AsusAtkWmi_WMNB / DSTS) |
ROG 機種確實知道充電來源,但每次查詢皆「拒絕存取」,需要提權,而本程式刻意不提權執行 |
所以整個儀表板不會出現任何變壓器瓦數。這與本專案一貫的原則一致:量不到的數字就不顯示,而不是估一個看起來合理的。 上面兩項新增的都是實測值。
⚙️ 相容性與成本
- 穩態 CPU 佔用維持 2.8% / 單核,與前一版相同 —— 新增的讀取在量測誤差之內。
- 目標框架、封裝方式、體積策略皆未變動。
- 不支援
PowerManager的環境會靜默降級:該列隱藏,其餘功能不受影響。
🔋 WinBat Lens v1.0.9 — 接上電池驅動的第三個 IOCTL
🔋 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_TAG 與 IOCTL_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 — 統一充放電配色
🎨 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 — 移除系統顯示卡清單
🗑️ 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模型:移除GpuTypeTag、VramText、DriverVersion、DriverDate、Status、StatusClass。只留下Name、IsDiscrete與VramBytes—— 最後一項純粹是因為判斷獨顯的邏輯要拿它跟 1 GB 比較。GpuInfoService:Win32_VideoController查詢不再撈DriverVersion、DriverDate、Status、Availability,也不再組字串。啟動時的 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 — 修正充電瓦數未顯示、移除無法量測的元件列
🔋 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 移除推估值時,刪掉了 TotalSystemHardwareW 與 AcTotalInputW 的賦值,卻漏掉欄位本身和 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 — 移除所有推估數值,只留真實量測
🔋 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 — 電池充放電瓦數改為真實量測
⚡ 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.DischargeRate(root\CIMV2)—— 這個屬性在本機和許多筆電上是空的。但 root\WMI BatteryStatus 和底層的 IOCTL_BATTERY_QUERY_STATUS 一直都正常運作。
換句話說,電池明明有回報真實數值,程式卻退回去用推估值。
之前判斷「EC 不支援」是錯的
所有先前的測試都是在電池滿電且插著電源的狀態下做的。RemainingCapacity 等於 FullChargedCapacity,此時電池沒有任何電流進出 —— 0 mW 就是正確答案,卻被誤判成「不支援」。
關鍵線索是:驅動回傳的是實實在在的 0,而不是規格保留給「真的讀不到」的 BATTERY_UNKNOWN_RATE(0x80000000)。
拔掉電源實測後完全證實:
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 — 改用真實硬體感測器、移除偽造的電池溫度
⚡ 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_ThermalZoneTemperature、MSBatteryClass)在這台機器上拿不到,因此溫度顯示已完全移除,而非改標示 —— 卡片、清單欄位、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 (推估) ← 來自使用率公式
🔧 過程中量測到的三件事
- 一次完整感測掃描要 85~256 ms —— 絕不能放在每秒一次的 UI 執行緒上。已改為背景執行緒輪詢,UI 只讀快取,成本降到 0.003 ms。
- CPU 硬體更新是掃描中最慢的部分,而在拿不到 RAPL 時毫無意義,因此偵測到不可用就直接跳過。
- 每個感測器預設會保留一整天的歷史數值 —— 以 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