C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#自动化重启虚拟机

C#自动化重启虚拟机的实战指南

作者:墨夶

在虚拟化环境中,虚拟机崩溃是开发者和运维人员的噩梦,本文将手把手教你如何用C#构建一个自动化重启系统,通过调用系统命令、封装工具类、处理异常流程,实现对崩溃虚拟机的快速响应,需要的朋友可以参考下

在虚拟化环境中,虚拟机崩溃是开发者和运维人员的噩梦。本文将手把手教你如何用C#构建一个自动化重启系统,通过调用系统命令、封装工具类、处理异常流程,实现对崩溃虚拟机的快速响应。代码详解+实战技巧,助你打造企业级虚拟机维护方案。

一、问题场景与解决方案设计

1.1 虚拟机崩溃的典型表现

1.2 解决方案架构

二、核心功能实现:C#调用虚拟机管理命令

2.1 Hyper-V虚拟机重启

using System;
using System.Diagnostics;

/// <summary>
/// Hyper-V虚拟机管理器
/// </summary>
public class HyperVManager
{
    /// <summary>
    /// 重启指定虚拟机
    /// </summary>
    /// <param name="vmName">虚拟机名称</param>
    /// <param name="timeout">超时时间(毫秒)</param>
    /// <returns>操作结果</returns>
    public static bool RestartVM(string vmName, int timeout = 10000)
    {
        try
        {
            // 先执行关机命令
            if (!ShutdownVM(vmName, timeout))
            {
                Console.WriteLine($"[Hyper-V] {vmName} 关机失败");
                return false;
            }

            // 延迟等待确保关机完成
            System.Threading.Thread.Sleep(3000);

            // 执行启动命令
            return StartVM(vmName, timeout);
        }
        catch (Exception ex)
        {
            LogError($"[Hyper-V] 重启虚拟机异常: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 关闭虚拟机
    /// </summary>
    private static bool ShutdownVM(string vmName, int timeout)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "PowerShell.exe",
                Arguments = $"Stop-VM -Name \"{vmName}\" -Force",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            }
        };

        process.Start();
        bool success = process.WaitForExit(timeout);
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();

        if (!success || !string.IsNullOrEmpty(error))
        {
            LogError($"[Hyper-V] 关机失败: {error}");
            return false;
        }

        return true;
    }

    /// <summary>
    /// 启动虚拟机
    /// </summary>
    private static bool StartVM(string vmName, int timeout)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "PowerShell.exe",
                Arguments = $"Start-VM -Name \"{vmName}\"",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            }
        };

        process.Start();
        bool success = process.WaitForExit(timeout);
        string error = process.StandardError.ReadToEnd();

        if (!success || !string.IsNullOrEmpty(error))
        {
            LogError($"[Hyper-V] 启动失败: {error}");
            return false;
        }

        return true;
    }

    /// <summary>
    /// 错误日志记录
    /// </summary>
    private static void LogError(string message)
    {
        string logPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "VMRecovery", "log.txt");

        Directory.CreateDirectory(Path.GetDirectoryName(logPath));
        File.AppendAllLines(logPath, new[] { $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}" });
    }
}

代码注释详解

  1. PowerShell.exe调用:通过Stop-VM/Start-VM命令控制虚拟机
  2. 异常处理:包含超时检测和错误日志记录
  3. 日志路径:使用系统LocalAppData目录确保跨用户兼容性

2.2 VirtualBox虚拟机重启

using System;
using System.Diagnostics;

/// <summary>
/// VirtualBox虚拟机管理器
/// </summary>
public class VirtualBoxManager
{
    /// <summary>
    /// 重启指定虚拟机
    /// </summary>
    public static bool RestartVM(string vmName, int timeout = 30000)
    {
        try
        {
            // 先执行关机命令
            if (!ShutdownVM(vmName, timeout))
            {
                Console.WriteLine($"[VirtualBox] {vmName} 关机失败");
                return false;
            }

            // 延迟等待确保关机完成
            System.Threading.Thread.Sleep(5000);

            // 执行启动命令
            return StartVM(vmName, timeout);
        }
        catch (Exception ex)
        {
            LogError($"[VirtualBox] 重启虚拟机异常: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 关闭虚拟机
    /// </summary>
    private static bool ShutdownVM(string vmName, int timeout)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "VBoxManage.exe",
                Arguments = $"controlvm \"{vmName}\" poweroff",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            }
        };

        process.Start();
        bool success = process.WaitForExit(timeout);
        string error = process.StandardError.ReadToEnd();

        if (!success || !string.IsNullOrEmpty(error))
        {
            LogError($"[VirtualBox] 关机失败: {error}");
            return false;
        }

        return true;
    }

    /// <summary>
    /// 启动虚拟机
    /// </summary>
    private static bool StartVM(string vmName, int timeout)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "VBoxManage.exe",
                Arguments = $"startvm \"{vmName}\" --type headless",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            }
        };

        process.Start();
        bool success = process.WaitForExit(timeout);
        string error = process.StandardError.ReadToEnd();

        if (!success || !string.IsNullOrEmpty(error))
        {
            LogError($"[VirtualBox] 启动失败: {error}");
            return false;
        }

        return true;
    }

    /// <summary>
    /// 错误日志记录
    /// </summary>
    private static void LogError(string message)
    {
        string logPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "VMRecovery", "virtualbox_log.txt");

        Directory.CreateDirectory(Path.GetDirectoryName(logPath));
        File.AppendAllLines(logPath, new[] { $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}" });
    }
}

技术要点

三、高级功能:智能监控与自动触发

3.1 定时监控服务

using System;
using System.Timers;

/// <summary>
/// 虚拟机监控服务
/// </summary>
public class VMMonitorService
{
    private Timer _timer;
    private readonly string[] _vmNames;
    private readonly int _checkInterval = 60000; // 1分钟检查一次

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="vmNames">需要监控的虚拟机列表</param>
    public VMMonitorService(string[] vmNames)
    {
        _vmNames = vmNames;
        _timer = new Timer(_checkInterval);
        _timer.Elapsed += OnTimerElapsed;
    }

    /// <summary>
    /// 启动监控服务
    /// </summary>
    public void Start()
    {
        _timer.Start();
        Console.WriteLine("虚拟机监控服务已启动...");
    }

    /// <summary>
    /// 定时任务回调
    /// </summary>
    private void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        foreach (var vmName in _vmNames)
        {
            CheckAndRecoverVM(vmName);
        }
    }

    /// <summary>
    /// 检查虚拟机状态并恢复
    /// </summary>
    private void CheckAndRecoverVM(string vmName)
    {
        try
        {
            // 检测虚拟机状态(示例:检测Hyper-V)
            var status = GetVMStatus(vmName);
            if (status != "Running")
            {
                Console.WriteLine($"检测到虚拟机 {vmName} 状态异常,准备重启...");
                if (HyperVManager.RestartVM(vmName))
                {
                    Console.WriteLine($"虚拟机 {vmName} 重启成功");
                }
                else
                {
                    Console.WriteLine($"虚拟机 {vmName} 重启失败");
                }
            }
        }
        catch (Exception ex)
        {
            LogError($"监控虚拟机异常: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取虚拟机状态(Hyper-V示例)
    /// </summary>
    private string GetVMStatus(string vmName)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "PowerShell.exe",
                Arguments = $"Get-VM -Name \"{vmName}\" | Select-Object -ExpandProperty State",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            }
        };

        process.Start();
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
        process.WaitForExit();

        if (!string.IsNullOrEmpty(error))
        {
            LogError($"获取虚拟机状态失败: {error}");
            return "Unknown";
        }

        return output.Trim();
    }

    /// <summary>
    /// 错误日志记录
    /// </summary>
    private void LogError(string message)
    {
        string logPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "VMRecovery", "monitor_log.txt");

        Directory.CreateDirectory(Path.GetDirectoryName(logPath));
        File.AppendAllLines(logPath, new[] { $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}" });
    }
}

实现原理

  1. 使用System.Timers.Timer实现定时监控
  2. 通过PowerShell命令获取Hyper-V虚拟机状态
  3. 自动触发重启流程并记录完整日志

四、实战部署与性能优化

4.1 Windows服务部署

using System.ServiceProcess;

/// <summary>
/// Windows服务入口
/// </summary>
public class VMRecoveryService : ServiceBase
{
    private VMMonitorService _monitorService;

    public VMRecoveryService()
    {
        ServiceName = "VirtualMachineRecoveryService";
    }

    protected override void OnStart(string[] args)
    {
        string[] vmNames = { "TestVM1", "TestVM2" };
        _monitorService = new VMMonitorService(vmNames);
        _monitorService.Start();
    }

    protected override void OnStop()
    {
        _monitorService = null;
    }

    public static void Main()
    {
        ServiceBase.Run(new VMRecoveryService());
    }
}

部署步骤

  1. 使用InstallUtil.exe安装服务
  2. 配置服务启动类型为"自动"
  3. 通过服务管理器设置依赖项(如Hyper-V服务)

五、常见问题与解决方案

5.1 权限不足问题

// 修改ProcessStartInfo配置
new ProcessStartInfo
{
    Verb = "runas", // 请求管理员权限
    UseShellExecute = true // 必须为true才能使用Verb
}

5.2 超时时间调整

// 修改定时器间隔
private readonly int _checkInterval = 30000; // 30秒检查一次

// 修改命令超时时间
public static bool RestartVM(string vmName, int timeout = 60000) // 60秒超时

5.3 多平台兼容性处理

/// <summary>
/// 根据操作系统选择虚拟机管理器
/// </summary>
public static IVMMgr GetVMMgr()
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        return new HyperVManager();
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
        return new KvmManager();
    }
    else
    {
        throw new PlatformNotSupportedException("不支持的操作系统");
    }
}

六、扩展功能建议

  1. 邮件通知系统:集成SMTP服务发送告警邮件
  2. Web API接口:提供RESTful API实现远程控制
  3. 图形化界面:使用WPF开发监控仪表盘
  4. 资源监控:集成PerformanceCounter检测CPU/内存使用率

七、总结与最佳实践

通过本文的实现,你已经掌握了如何用C#构建完整的虚拟机自动重启系统。以下最佳实践供参考:

  1. 日志分级管理:区分错误日志、操作日志、调试日志
  2. 配置文件化:将虚拟机名称、检查间隔等参数外置
  3. 异常熔断机制:连续失败超过N次时触发人工干预
  4. 版本控制:使用Git管理代码变更,记录每次优化

关键命令速查表

操作系统命令说明
Hyper-VGet-VM获取虚拟机列表
Hyper-VStop-VM -Force强制关机
VirtualBoxVBoxManage list runningvms列出运行中的虚拟机
VirtualBoxVBoxManage startvm --type headless无界面启动
Linux KVMvirsh list列出虚拟机
Linux KVMvirsh shutdown正常关机

以上就是C#自动化重启虚拟机的实战指南的详细内容,更多关于C#自动化重启虚拟机的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文