首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 定時關機程序開發:調用 Windows API 實現系統級關機功能

     編輯:關於C語言

需求場景

實驗室/辦公室電腦需在無人值守時自動關機(如每日午夜 12 點),既節能又延長硬件壽命。本文實現一個基於 Windows API 的定時關機工具,經 Win2K/XP/Win7/Win10 實測穩定可靠。

核心原理

調用 user32.dll 中的 ExitWindowsEx 函數發送系統關機消息,配合 Timer 組件實現定時觸發。

一、API 聲明與常量定義

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class AutoShutdown
{
    // 關機標誌常量
    private const int EWX_LOGOFF = 0x00;      // 注銷
    private const int EWX_SHUTDOWN = 0x01;    // 關機
    private const int EWX_REBOOT = 0x02;      // 重啟
    private const int EWX_FORCE = 0x04;       // 強制關閉應用
    private const int EWX_POWEROFF = 0x08;    // 切斷電源
    private const int EWX_FORCEIFHUNG = 0x10; // 僅強制掛起進程

    [DllImport("user32.dll", SetLastError = true, ExactSpelling = true)]
    private static extern bool ExitWindowsEx(int uFlags, int dwReason);
}

二、定時邏輯實現

public class ShutdownTimer
{
    private Timer _timer;
    private DateTime _targetTime;
    private bool _executed = false;

    public ShutdownTimer(DateTime targetTime)
    {
        _targetTime = targetTime;
        _timer = new Timer { Interval = 1000 }; // 每秒檢查一次
        _timer.Tick += Timer_Tick;
    }

    public void Start()
    {
        _timer.Start();
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        if (_executed) return; // 防止重複執行
        
        if (DateTime.Now >= _targetTime)
        {
            _timer.Stop(); // 關鍵:必須先停止 Timer!
            _executed = true;
            
            // 執行關機(強制關機 + 切斷電源)
            bool result = ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF, 0);
            
            if (!result)
            {
                int error = Marshal.GetLastWin32Error();
                MessageBox.Show($"關機失敗,錯誤碼: {error}");
            }
        }
    }
}

三、完整窗體程序 (Form1.cs)

public partial class Form1 : Form
{
    private ShutdownTimer _shutdownTimer;

    public Form1()
    {
        InitializeComponent();
        // 默認設置為今日 23:59:59
        dateTimePicker1.Value = DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59);
    }

    private void btnSet_Click(object sender, EventArgs e)
    {
        _shutdownTimer = new ShutdownTimer(dateTimePicker1.Value);
        _shutdownTimer.Start();
        lblStatus.Text = $"已設置定時關機:{dateTimePicker1.Value:HH:mm:ss}";
        btnSet.Enabled = false;
        btnCancel.Enabled = true;
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        _shutdownTimer?.Dispose();
        lblStatus.Text = "已取消定時關機";
        btnSet.Enabled = true;
        btnCancel.Enabled = false;
    }
}

四、關鍵技術點總結

  1. Timer 停止時機:調用 API 前 必須 停止 Timer,否則多次調用導致藍屏死機
  2. 權限要求:需管理員權限運行,否則 ExitWindowsEx 返回 false
  3. 強制標誌:EWX_FORCE 確保無響應程序不阻塞關機
  4. 原因代碼:第二參數 dwReason 可記錄關機原因(事件查看器可見)

五、擴展功能建議

  • 系統托盤最小化運行(參考文章 82945)
  • 熱鍵取消關機(如 Ctrl+Alt+S)
  • 關機前倒計時提示對話框(30 秒倒計時)
  • 命令行參數支持:AutoShutdown.exe /t 3600 /action reboot
  • 寫入 Windows 計劃任務實現開機自啟

💡 測試提示:開發調試時建議將關機動作改為 EWX_LOGOFF(注銷),避免頻繁重啟影響開發環境。

這個不到 100 行的工具類,解決了實際場景中的定時關機需求,代碼簡潔、無第三方依賴、兼容性極佳,適合集成到各類自動化運維腳本中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved