Skip to content

Commit 5db0c33

Browse files
committed
feat(hardware): 为 Get-SystemMemoryInfo 添加多平台支持
扩展 Get-SystemMemoryInfo 函数以支持 Windows、macOS 和 Linux 系统 添加备用方法处理获取内存信息失败的情况
1 parent d1301ce commit 5db0c33

1 file changed

Lines changed: 134 additions & 9 deletions

File tree

psutils/modules/hardware.psm1

Lines changed: 134 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,22 +159,147 @@ function Get-GpuInfo {
159159
获取系统内存信息
160160
161161
.DESCRIPTION
162-
获取系统总内存和可用内存大小
162+
获取系统总内存和可用内存大小,支持 Windows、macOS 和 Linux 系统
163163
164164
.OUTPUTS
165165
返回包含内存信息的哈希表
166166
#>
167167
function Get-SystemMemoryInfo {
168168
try {
169-
$totalMemory = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty TotalPhysicalMemory
170-
$availableMemory = Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty FreePhysicalMemory
169+
# 检测操作系统类型
170+
$osType = Get-OperatingSystem
171171

172-
$totalMemoryGB = [math]::Round($totalMemory / 1GB, 1)
173-
$availableMemoryGB = [math]::Round(($availableMemory * 1KB) / 1GB, 1)
174-
175-
return @{
176-
TotalGB = $totalMemoryGB
177-
AvailableGB = $availableMemoryGB
172+
switch ($osType) {
173+
"Windows" {
174+
# Windows 系统使用 WMI
175+
$totalMemory = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty TotalPhysicalMemory
176+
$availableMemory = Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty FreePhysicalMemory
177+
178+
$totalMemoryGB = [math]::Round($totalMemory / 1GB, 1)
179+
$availableMemoryGB = [math]::Round(($availableMemory * 1KB) / 1GB, 1)
180+
181+
return @{
182+
TotalGB = $totalMemoryGB
183+
AvailableGB = $availableMemoryGB
184+
}
185+
}
186+
"macOS" {
187+
# macOS 系统使用 sysctl 和 vm_stat
188+
try {
189+
# 获取总内存(字节)
190+
$totalMemoryBytes = sysctl -n hw.memsize
191+
$totalMemoryGB = [math]::Round([long]$totalMemoryBytes / 1GB, 1)
192+
193+
# 获取可用内存(使用 vm_stat)
194+
$vmStat = vm_stat | Where-Object { $_ -match "Pages free:|Pages inactive:|Pages speculative:" }
195+
$freePages = 0
196+
$inactivePages = 0
197+
$speculativePages = 0
198+
199+
foreach ($line in $vmStat) {
200+
if ($line -match "Pages free:\s+(\d+)") {
201+
$freePages = [long]$matches[1]
202+
}
203+
elseif ($line -match "Pages inactive:\s+(\d+)") {
204+
$inactivePages = [long]$matches[1]
205+
}
206+
elseif ($line -match "Pages speculative:\s+(\d+)") {
207+
$speculativePages = [long]$matches[1]
208+
}
209+
}
210+
211+
# 页面大小(通常是 4KB)
212+
$pageSize = sysctl -n hw.pagesize
213+
$availablePages = $freePages + $inactivePages + $speculativePages
214+
$availableMemoryBytes = $availablePages * [long]$pageSize
215+
$availableMemoryGB = [math]::Round($availableMemoryBytes / 1GB, 1)
216+
217+
return @{
218+
TotalGB = $totalMemoryGB
219+
AvailableGB = $availableMemoryGB
220+
}
221+
}
222+
catch {
223+
Write-Warning "macOS 内存信息获取失败,尝试备用方法: $($_.Exception.Message)"
224+
# 备用方法:只获取总内存
225+
$totalMemoryBytes = sysctl -n hw.memsize
226+
$totalMemoryGB = [math]::Round([long]$totalMemoryBytes / 1GB, 1)
227+
return @{
228+
TotalGB = $totalMemoryGB
229+
AvailableGB = [math]::Round($totalMemoryGB * 0.7, 1) # 估算可用内存为总内存的70%
230+
}
231+
}
232+
}
233+
"Linux" {
234+
# Linux 系统使用 /proc/meminfo
235+
try {
236+
$memInfo = Get-Content "/proc/meminfo"
237+
$totalMemoryKB = 0
238+
$availableMemoryKB = 0
239+
$freeMemoryKB = 0
240+
$buffersKB = 0
241+
$cachedKB = 0
242+
243+
foreach ($line in $memInfo) {
244+
if ($line -match "^MemTotal:\s+(\d+)\s+kB") {
245+
$totalMemoryKB = [long]$matches[1]
246+
}
247+
elseif ($line -match "^MemAvailable:\s+(\d+)\s+kB") {
248+
$availableMemoryKB = [long]$matches[1]
249+
}
250+
elseif ($line -match "^MemFree:\s+(\d+)\s+kB") {
251+
$freeMemoryKB = [long]$matches[1]
252+
}
253+
elseif ($line -match "^Buffers:\s+(\d+)\s+kB") {
254+
$buffersKB = [long]$matches[1]
255+
}
256+
elseif ($line -match "^Cached:\s+(\d+)\s+kB") {
257+
$cachedKB = [long]$matches[1]
258+
}
259+
}
260+
261+
$totalMemoryGB = [math]::Round($totalMemoryKB / 1MB, 1)
262+
263+
# 优先使用 MemAvailable,如果不存在则计算 Free + Buffers + Cached
264+
if ($availableMemoryKB -gt 0) {
265+
$availableMemoryGB = [math]::Round($availableMemoryKB / 1MB, 1)
266+
}
267+
else {
268+
$availableMemoryGB = [math]::Round(($freeMemoryKB + $buffersKB + $cachedKB) / 1MB, 1)
269+
}
270+
271+
return @{
272+
TotalGB = $totalMemoryGB
273+
AvailableGB = $availableMemoryGB
274+
}
275+
}
276+
catch {
277+
Write-Warning "Linux 内存信息获取失败,尝试备用方法: $($_.Exception.Message)"
278+
# 备用方法:使用 free 命令
279+
try {
280+
$freeOutput = free -m | Select-String "^Mem:"
281+
if ($freeOutput -match "Mem:\s+(\d+)\s+(\d+)\s+(\d+)") {
282+
$totalMemoryMB = [long]$matches[1]
283+
$availableMemoryMB = [long]$matches[3]
284+
285+
return @{
286+
TotalGB = [math]::Round($totalMemoryMB / 1KB, 1)
287+
AvailableGB = [math]::Round($availableMemoryMB / 1KB, 1)
288+
}
289+
}
290+
}
291+
catch {
292+
Write-Warning "Linux 备用方法也失败: $($_.Exception.Message)"
293+
}
294+
}
295+
}
296+
default {
297+
Write-Warning "不支持的操作系统: $osType"
298+
return @{
299+
TotalGB = 0
300+
AvailableGB = 0
301+
}
302+
}
178303
}
179304
}
180305
catch {

0 commit comments

Comments
 (0)