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

如何在C# WinForms应用中定时执行PowerShell脚本并展示结果

解决方案

1. 添加PowerShell依赖

要在C#中执行PowerShell脚本,首先需要添加System.Management.Automation程序集的引用。你可以通过NuGet包管理器安装Microsoft.PowerShell.SDK来获取这个依赖。

2. 在Timer Tick事件中集成PowerShell执行逻辑

修改你的timer1_Tick方法,加入PowerShell脚本的执行和结果处理逻辑:

private void timer1_Tick(object sender, EventArgs e)
{
    string psCommand = @"Get-Service -ComputerName ""DESKTOP"" -Name ""WinDefend""";

    try
    {
        using (PowerShell psInstance = PowerShell.Create())
        {
            psInstance.AddScript(psCommand);
            var results = psInstance.Invoke();

            // 处理执行结果
            if (results.Any())
            {
                var serviceInfo = results[0].BaseObject as ServiceController;
                if (serviceInfo != null)
                {
                    string statusContent = $"[{DateTime.Now:HH:mm:ss}] 服务器DESKTOP的WinDefend服务状态:{serviceInfo.Status}";
                    UpdateUi(statusContent);
                }
            }
            else
            {
                UpdateUi($"[{DateTime.Now:HH:mm:ss}] 无法获取WinDefend服务状态:未找到服务或远程连接失败");
            }

            // 处理执行过程中的错误
            if (psInstance.Streams.Error.Any())
            {
                string errorMsg = $"[{DateTime.Now:HH:mm:ss}] 执行错误:{psInstance.Streams.Error[0].Exception.Message}";
                UpdateUi(errorMsg);
            }
        }
    }
    catch (Exception ex)
    {
        UpdateUi($"[{DateTime.Now:HH:mm:ss}] 异常:{ex.Message}");
    }
}

3. 安全更新UI控件

WinForms控件只能在创建它的UI线程中更新,因此需要封装一个跨线程安全的更新方法,同时支持TextBox和Label的显示需求:

private void UpdateUi(string content)
{
    // 检查是否需要跨线程调用
    if (textBoxStatus.InvokeRequired)
    {
        textBoxStatus.Invoke(new Action<string>(UpdateUi), content);
        return;
    }

    // 更新TextBox:追加历史监控记录
    textBoxStatus.AppendText(content + Environment.NewLine);
    // 自动滚动到最新内容
    textBoxStatus.ScrollToCaret();

    // 更新Label:仅显示最新的监控状态
    labelLatestStatus.Text = content;
}

4. 扩展到多服务器多服务

如果要监控多台服务器的多个服务,可以预先定义监控目标列表,在Tick事件中批量执行:

// 定义监控目标,可根据实际需求修改
private readonly List<(string ServerName, string ServiceName)> _monitorList = new()
{
    ("DESKTOP", "WinDefend"),
    ("SERVER-01", "Spooler"),
    ("SERVER-02", "TermService")
};

// 修改后的Tick事件
private void timer1_Tick(object sender, EventArgs e)
{
    foreach (var target in _monitorList)
    {
        string psCommand = $"Get-Service -ComputerName ""{target.ServerName}"" -Name ""{target.ServiceName}""";
        ExecutePsCommandAndUpdateUi(psCommand);
    }
}

// 封装复用的执行方法
private void ExecutePsCommandAndUpdateUi(string psCommand)
{
    try
    {
        using (PowerShell psInstance = PowerShell.Create())
        {
            psInstance.AddScript(psCommand);
            var results = psInstance.Invoke();

            if (results.Any())
            {
                var service = results[0].BaseObject as ServiceController;
                if (service != null)
                {
                    string content = $"[{DateTime.Now:HH:mm:ss}] 服务器{service.MachineName}的{service.ServiceName}服务状态:{service.Status}";
                    UpdateUi(content);
                }
            }
            else
            {
                // 从命令中解析服务器和服务名
                string[] parts = psCommand.Split(new[] { "-ComputerName", "-Name" }, StringSplitOptions.RemoveEmptyEntries);
                string server = parts[1].Trim('"', ' ');
                string service = parts[2].Trim('"', ' ');
                UpdateUi($"[{DateTime.Now:HH:mm:ss}] 无法获取服务器{server}的{service}服务状态");
            }

            if (psInstance.Streams.Error.Any())
            {
                UpdateUi($"[{DateTime.Now:HH:mm:ss}] 执行错误:{psInstance.Streams.Error[0].Exception.Message}");
            }
        }
    }
    catch (Exception ex)
    {
        UpdateUi($"[{DateTime.Now:HH:mm:ss}] 异常:{ex.Message}");
    }
}

关键注意事项

  • 权限要求:运行程序的账号必须拥有远程服务器的服务访问权限,否则会出现权限不足的错误。
  • UI性能:如果监控目标较多,建议将PowerShell执行逻辑放到异步任务中(比如用Task.Run),避免阻塞UI线程导致界面卡顿。
  • 异常处理:务必处理网络中断、服务不存在、权限不足等各种异常场景,保证监控应用的稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:31:17