Skip to content

Commit 7686ec6

Browse files
authored
feat: Add Windows x64 build target (#98)
* feat: Add Windows x64 build target support - Add Windows x86_64 (MSVC) target to release workflow matrix - Skip protoc setup on Windows (TPU support is Linux-only) - Add Windows-specific binary packaging using PowerShell - Add Windows-specific SHA256 checksum generation - Add Windows process priority handler in process_list.rs Closes #97 * fix: Update WMI crate API usage for Windows build compatibility - Update wmi crate 0.18.0 API: remove COMLibrary usage - WMIConnection::new() no longer takes COM argument - WMIConnection::with_namespace_path() takes only namespace path - Simplify process_list.rs Windows priority handling The wmi 0.18.0 release removed COMLibrary and simplified the API. This fix updates cpu_windows.rs and amd_windows.rs to use the new API.
1 parent 07f23b5 commit 7686ec6

File tree

4 files changed

+53
-58
lines changed

4 files changed

+53
-58
lines changed

.github/workflows/release.yml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ jobs:
6868
archive_ext: ".zip"
6969
protoc_platform: osx-aarch_64
7070

71+
# Windows x86_64
72+
- target: x86_64-pc-windows-msvc
73+
os: windows-latest
74+
artifact_name: all-smi.exe
75+
asset_name: all-smi-windows-x86_64
76+
archive_ext: ".zip"
77+
protoc_platform: "" # Not needed for Windows (TPU is Linux-only)
78+
7179
env:
7280
BIN_NAME: all-smi
7381
BUNDLE_ID: ${{ vars.BUNDLE_ID }}
@@ -117,8 +125,9 @@ jobs:
117125
sudo apt update
118126
sudo apt install -y libdrm-dev libdrm-amdgpu1
119127
120-
# 6) Setup protoc (cached)
128+
# 6) Setup protoc (cached) - skip on Windows as TPU support is Linux-only
121129
- name: Setup protoc
130+
if: runner.os != 'Windows'
122131
uses: ./.github/actions/setup-protoc
123132
with:
124133
version: ${{ env.PROTOC_VERSION }}
@@ -163,8 +172,19 @@ jobs:
163172
cp docs/man/all-smi.1 package/
164173
ditto -c -k --sequesterRsrc package "$ASSET"
165174
175+
- name: Package Windows binary (zip)
176+
if: runner.os == 'Windows'
177+
shell: pwsh
178+
run: |
179+
$BIN = "target/${{ matrix.target }}/release/${{ matrix.artifact_name }}"
180+
$ASSET = "${{ matrix.asset_name }}.zip"
181+
New-Item -ItemType Directory -Force -Path package
182+
Copy-Item $BIN -Destination package/
183+
Compress-Archive -Path package/* -DestinationPath $ASSET
184+
166185
# 10) Generate checksum
167-
- name: Generate checksum
186+
- name: Generate checksum (Linux/macOS)
187+
if: runner.os != 'Windows'
168188
run: |
169189
FILE="${{ matrix.asset_name }}${{ matrix.archive_ext }}"
170190
if [[ "$RUNNER_OS" == "Linux" ]]; then
@@ -173,6 +193,14 @@ jobs:
173193
shasum -a 256 "$FILE" > "$FILE.sha256"
174194
fi
175195
196+
- name: Generate checksum (Windows)
197+
if: runner.os == 'Windows'
198+
shell: pwsh
199+
run: |
200+
$FILE = "${{ matrix.asset_name }}${{ matrix.archive_ext }}"
201+
$hash = (Get-FileHash -Path $FILE -Algorithm SHA256).Hash.ToLower()
202+
"$hash $FILE" | Out-File -FilePath "$FILE.sha256" -Encoding ASCII -NoNewline
203+
176204
# 11) Upload release artifacts and checksum
177205
- name: Upload release artifacts
178206
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'

src/device/cpu_windows.rs

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use chrono::Local;
2020
use serde::Deserialize;
2121
use std::sync::RwLock;
2222
use sysinfo::{CpuRefreshKind, System};
23-
use wmi::{COMLibrary, WMIConnection};
23+
use wmi::WMIConnection;
2424

2525
// WMI structures for thermal zone temperature
2626
#[derive(Deserialize, Debug)]
@@ -49,17 +49,12 @@ fn with_cimv2_connection<T, F: FnOnce(&WMIConnection) -> T>(f: F) -> Option<T> {
4949
WMI_CIMV2_CONNECTION.with(|cell| {
5050
let mut conn_ref = cell.borrow_mut();
5151
if conn_ref.is_none() {
52-
match COMLibrary::new() {
53-
Ok(com) => match WMIConnection::new(com) {
54-
Ok(wmi_con) => {
55-
*conn_ref = Some(wmi_con);
56-
}
57-
Err(e) => {
58-
eprintln!("Failed to create WMI CIMV2 connection: {e}");
59-
}
60-
},
52+
match WMIConnection::new() {
53+
Ok(wmi_con) => {
54+
*conn_ref = Some(wmi_con);
55+
}
6156
Err(e) => {
62-
eprintln!("Failed to initialize COM library for CIMV2: {e}");
57+
eprintln!("Failed to create WMI CIMV2 connection: {e}");
6358
}
6459
}
6560
}
@@ -72,17 +67,12 @@ fn with_root_wmi_connection<T, F: FnOnce(&WMIConnection) -> T>(f: F) -> Option<T
7267
WMI_ROOT_WMI_CONNECTION.with(|cell| {
7368
let mut conn_ref = cell.borrow_mut();
7469
if conn_ref.is_none() {
75-
match COMLibrary::new() {
76-
Ok(com) => match WMIConnection::with_namespace_path("root\\WMI", com) {
77-
Ok(wmi_con) => {
78-
*conn_ref = Some(wmi_con);
79-
}
80-
Err(e) => {
81-
eprintln!("Failed to create WMI root\\WMI connection: {e}");
82-
}
83-
},
70+
match WMIConnection::with_namespace_path("root\\WMI") {
71+
Ok(wmi_con) => {
72+
*conn_ref = Some(wmi_con);
73+
}
8474
Err(e) => {
85-
eprintln!("Failed to initialize COM library for root\\WMI: {e}");
75+
eprintln!("Failed to create WMI root\\WMI connection: {e}");
8676
}
8777
}
8878
}

src/device/process_list.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,11 @@ fn get_process_priority_nice(pid: u32) -> (i32, i32) {
250250
}
251251
}
252252

253-
// Default values if unable to retrieve
253+
// On Windows, process priority is managed differently than Unix systems.
254+
// Windows uses priority classes (Idle, Below Normal, Normal, Above Normal, High, Realtime)
255+
// rather than nice values. The sysinfo crate doesn't expose priority directly.
256+
// Return default values as Unix-style nice values don't apply to Windows.
257+
// Default values if unable to retrieve (for Windows or any other OS)
254258
(20, 0)
255259
}
256260

src/device/readers/amd_windows.rs

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::utils::get_hostname;
2424
use chrono::Local;
2525
use serde::Deserialize;
2626
use std::collections::HashMap;
27-
use wmi::{COMLibrary, WMIConnection};
27+
use wmi::WMIConnection;
2828

2929
// Thread-local WMI connection for reuse within the same thread
3030
thread_local! {
@@ -36,17 +36,12 @@ fn with_wmi_connection<T, F: FnOnce(&WMIConnection) -> T>(f: F) -> Option<T> {
3636
WMI_CONNECTION.with(|cell| {
3737
let mut conn_ref = cell.borrow_mut();
3838
if conn_ref.is_none() {
39-
match COMLibrary::new() {
40-
Ok(com) => match WMIConnection::new(com) {
41-
Ok(wmi_con) => {
42-
*conn_ref = Some(wmi_con);
43-
}
44-
Err(e) => {
45-
eprintln!("AMD GPU: Failed to create WMI connection: {e}");
46-
}
47-
},
39+
match WMIConnection::new() {
40+
Ok(wmi_con) => {
41+
*conn_ref = Some(wmi_con);
42+
}
4843
Err(e) => {
49-
eprintln!("AMD GPU: Failed to initialize COM library: {e}");
44+
eprintln!("AMD GPU: Failed to create WMI connection: {e}");
5045
}
5146
}
5247
}
@@ -208,29 +203,7 @@ impl GpuReader for AmdWindowsGpuReader {
208203
/// Check if AMD GPU is present on Windows using WMI
209204
/// Note: This creates its own WMI connection since detection may run on a different thread
210205
pub fn has_amd_gpu_windows() -> bool {
211-
// Try multiple COM initialization strategies
212-
// Strategy 1: Try normal COM initialization
213-
let com = match COMLibrary::new() {
214-
Ok(c) => Some(c),
215-
Err(e) => {
216-
// Strategy 2: Try without_security for already-initialized COM
217-
match COMLibrary::without_security() {
218-
Ok(c) => Some(c),
219-
Err(e2) => {
220-
eprintln!(
221-
"AMD GPU detection: Failed to initialize COM library: {e}, fallback: {e2}"
222-
);
223-
None
224-
}
225-
}
226-
}
227-
};
228-
229-
let Some(com) = com else {
230-
return false;
231-
};
232-
233-
let wmi_con = match WMIConnection::new(com) {
206+
let wmi_con = match WMIConnection::new() {
234207
Ok(w) => w,
235208
Err(e) => {
236209
eprintln!("AMD GPU detection: Failed to create WMI connection: {e}");

0 commit comments

Comments
 (0)