You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从远程机器获取系统信息并本地展示?远程Windows服务实现咨询

实现远程Windows服务监控方案的分步指南

看起来你已经迈出了关键的第一步,接下来我们一步步把这个监控服务搭起来——核心思路是在远程机器部署一个轻量的Windows服务(托管数据采集API),本地通过HTTP调用获取监控数据,这样既不会干扰远程进程,又能安全高效地拿到你需要的系统信息。

一、重构数据采集逻辑(确保无干扰)

你已经能获取本地磁盘信息,现在扩展到CPU和进程,核心原则是只读采集,绝对不操作远程进程:

1. 磁盘空间采集(复用你的代码,优化为可复用方法)

using System.IO;
using System.Linq;

public static class SystemMonitor
{
    public static List<DriveInfo> GetDiskInfo()
    {
        // 只获取就绪的固定磁盘,过滤光驱、网络驱动器这类无关设备
        return DriveInfo.GetDrives()
            .Where(d => d.DriveType == DriveType.Fixed && d.IsReady)
            .ToList();
    }
}

2. CPU使用率采集

注意:PerformanceCounter第一次调用会返回0,需要先刷新一次,避免频繁创建实例造成性能开销:

using System.Diagnostics;
using System.Threading;

private static readonly PerformanceCounter _cpuCounter = 
    new PerformanceCounter("Processor", "% Processor Time", "_Total");

public static float GetCpuUsage()
{
    // 第一次调用初始化计数器
    _cpuCounter.NextValue();
    Thread.Sleep(1000); // 等待1秒获取准确值,可根据需求调整间隔
    return _cpuCounter.NextValue();
}

3. 运行中进程采集

只读取进程的基础属性,绝对不调用Kill()、Start()等操作方法:

public static List<ProcessInfo> GetRunningProcesses()
{
    return Process.GetProcesses()
        .Select(p => new ProcessInfo
        {
            ProcessName = p.ProcessName,
            Id = p.Id,
            MemoryUsage = p.WorkingSet64 / 1024 / 1024, // 转换为MB单位
            StartTime = p.StartTime
        })
        .ToList();
}

// 定义DTO传递进程信息,避免直接序列化Process对象带来的问题
public class ProcessInfo
{
    public string ProcessName { get; set; }
    public int Id { get; set; }
    public double MemoryUsage { get; set; }
    public DateTime StartTime { get; set; }
}

二、将采集逻辑封装为可远程调用的服务(推荐用ASP.NET Core Web API托管Windows服务)

现在.NET Core/.NET 6+做Windows服务非常便捷,而且Web API的HTTP调用对本地客户端友好,不需要复杂的配置:

1. 创建ASP.NET Core Web API项目

选择「ASP.NET Core Web API」模板,然后修改项目文件,添加Windows服务支持:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net6.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <OutputType>Exe</OutputType> <!-- 必须设置为Exe才能作为Windows服务运行 -->
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.1" />
  </ItemGroup>
</Project>

2. 配置Program.cs,启用Windows服务托管

var builder = WebApplication.CreateBuilder(args);

// 添加Windows服务托管支持,设置服务名称
builder.Host.UseWindowsService(options =>
{
    options.ServiceName = "RemoteSystemMonitorService";
});

// 添加控制器支持
builder.Services.AddControllers();

var app = builder.Build();

// 配置API路由
app.MapControllers();

// 监听所有IP的5000端口,方便远程访问
app.Run("http://0.0.0.0:5000");

3. 创建监控API控制器

using Microsoft.AspNetCore.Mvc;
using System.Linq;

[ApiController]
[Route("api/monitor")]
public class MonitorController : ControllerBase
{
    [HttpGet("disk")]
    public IActionResult GetDiskInfo()
    {
        var disks = SystemMonitor.GetDiskInfo();
        return Ok(disks.Select(d => new 
        {
            DriveName = d.Name,
            TotalSpaceGB = d.TotalSize / 1024 / 1024 / 1024,
            FreeSpaceGB = d.AvailableFreeSpace / 1024 / 1024 / 1024,
            UsedSpaceGB = (d.TotalSize - d.AvailableFreeSpace) / 1024 / 1024 / 1024
        }));
    }

    [HttpGet("cpu")]
    public IActionResult GetCpuUsage()
    {
        var cpuUsage = SystemMonitor.GetCpuUsage();
        return Ok(new { UsagePercent = cpuUsage });
    }

    [HttpGet("processes")]
    public IActionResult GetProcesses()
    {
        var processes = SystemMonitor.GetRunningProcesses();
        return Ok(processes);
    }
}

三、部署远程Windows服务

  1. 发布项目:在Visual Studio中右键项目→发布,选择「文件夹」作为发布目标,生成可执行文件。
  2. 安装服务:以管理员身份打开命令提示符,运行以下命令(替换为你的发布路径):
    sc create RemoteSystemMonitorService binPath="C:\你的发布路径\RemoteSystemMonitorService.exe" start=auto
    
    • start=auto表示开机自动启动服务
    • 推荐使用LocalService账户运行服务(权限足够读取系统信息,安全性更高):
      sc config RemoteSystemMonitorService obj="NT AUTHORITY\LocalService"
      
  3. 启动服务:
    sc start RemoteSystemMonitorService
    
  4. 防火墙配置:在远程机器上开放5000端口(或你指定的端口),允许入站HTTP请求。

四、本地客户端调用远程服务

用HttpClient简单调用即可,示例代码如下:

using System.Net.Http.Json;

public class RemoteMonitorClient
{
    private readonly HttpClient _httpClient;

    public RemoteMonitorClient(string remoteIp)
    {
        _httpClient = new HttpClient { BaseAddress = new Uri($"http://{remoteIp}:5000/api/monitor/") };
    }

    public async Task<List<DiskInfo>> GetDiskInfoAsync()
    {
        return await _httpClient.GetFromJsonAsync<List<DiskInfo>>("disk");
    }

    public async Task<CpuInfo> GetCpuUsageAsync()
    {
        return await _httpClient.GetFromJsonAsync<CpuInfo>("cpu");
    }

    public async Task<List<ProcessInfo>> GetProcessesAsync()
    {
        return await _httpClient.GetFromJsonAsync<List<ProcessInfo>>("processes");
    }
}

// 对应API返回的DTO类
public class DiskInfo
{
    public string DriveName { get; set; }
    public double TotalSpaceGB { get; set; }
    public double FreeSpaceGB { get; set; }
    public double UsedSpaceGB { get; set; }
}

public class CpuInfo
{
    public float UsagePercent { get; set; }
}

关键注意事项

  • 权限控制:远程服务尽量使用LocalService或NetworkService账户,避免使用管理员账户,降低安全风险。
  • 性能优化:CPU采集不要过于频繁(比如10秒一次),进程采集可以缓存结果,避免每秒遍历所有进程。
  • 无干扰保证:所有采集逻辑都只读取系统/进程的属性,绝对不调用任何修改或操作进程的方法,完全不会影响远程机器的运行进程。

内容的提问来源于stack exchange,提问作者Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:00:11