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

C++ Builder 偵測 Windows 啟動模式:正常、安全模式與網路安全模式完整判斷

     編輯:VC 教學

核心 API:GetSystemMetrics 與 SM_CLEANBOOT

Windows 提供 `GetSystemMetrics` 系統指標查詢 API,參數 `SM_CLEANBOOT` (值 67) 專門用於檢測啟動模式。此為**唯一官方文件化**的啟動模式檢測方法,支援 Windows 95 至 Windows 11 全版本。

返回值對照表

返回值啟動模式特徵典型用途
0正常模式完整驅動、服務、網路、圖形介面標準應用程式執行環境
1安全模式最小驅動集、無網路、標準 VGA 顯示、僅核心服務疑難排解、病毒掃描、驅動衝突修復
2含網路安全模式安全模式基礎上啟用網路驅動與服務遠端管理、網路修復、域環境疑難排解

C++ Builder 完整實作範例

基本偵測與提示


void __fastcall TForm1::Button1Click(TObject* Sender) {
    int bootMode = GetSystemMetrics(SM_CLEANBOOT);
    AnsiString msg;
    
    switch (bootMode) {
        case 0: msg = "正常模式啟動"; break;
        case 1: msg = "安全模式啟動"; break;
        case 2: msg = "安全模式啟動,但帶網路功能"; break;
        default: msg = "未知啟動模式 (" + IntToStr(bootMode) + ")"; break;
    }
    
    ShowMessage(msg);
    
    // 實際應用:安全模式下禁用特定功能
    if (bootMode != 0) {
        // 禁用多媒體、網路進階功能、硬體加速等
        MediaPlayer1->Enabled = false;
        NetworkComponent->Enabled = false;
    }
}

進階:啟動時自動檢測並決定是否繼續執行


#pragma startup CheckBootMode 33 // 早期執行優先級

void CheckBootMode() {
    int mode = GetSystemMetrics(SM_CLEANBOOT);
    if (mode != 0) {
        // 記錄事件日誌
        HANDLE hEventLog = RegisterEventSource(NULL, "MyApplication");
        if (hEventLog) {
            char* strings[] = { "Application blocked in Safe Mode" };
            ReportEvent(hEventLog, EVENTLOG_WARNING_TYPE, 0, 0, NULL, 1, 0, (const char**)strings, NULL);
            DeregisterEventSource(hEventLog);
        }
        
        // 彈出對話框並退出
        MessageBox(NULL, 
            "偵測到安全模式啟動,本程式需要完整系統環境執行。\n請在正常模式下重新啟動電腦後再試。",
            "啟動模式不支援", MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
        ExitProcess(0);
    }
}

替代檢測方法 (備援/驗證)

1. 登錄檢查


bool IsSafeModeRegistry() {
    HKEY hKey;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
        "SYSTEM\\CurrentControlSet\\Control\\SafeBoot", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
        DWORD type, size = 256;
        char value[256];
        // OptionValue = "Minimal" 或 "Network"
        if (RegQueryValueEx(hKey, "OptionValue", NULL, &type, (LPBYTE)value, &size) == ERROR_SUCCESS) {
            RegCloseKey(hKey);
            return (strcmp(value, "Minimal") == 0 || strcmp(value, "Network") == 0);
        }
        RegCloseKey(hKey);
    }
    return false;
}

2. WMI 查詢


bool IsSafeModeWMI() {
    // 需引入 wbemidl.h, 鏈接 wbemuuid.lib
    // SELECT BootState FROM Win32_ComputerSystem
    // BootState = "Safe mode" / "Safe mode with Networking" / "Normal"
    // 實作略 (需 COM 初始化、IWbemLocator、IWbemServices、查詢執行)
}

3. 檢查關鍵服務狀態


bool IsLikelySafeMode() {
    // 安全模式下通常停用的服務
    const char* criticalServices[] = { "Themes", "AudioSrv", "W32Time", "wuauserv" };
    SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (!hSCM) return false;
    
    for (const char* svc : criticalServices) {
        SC_HANDLE hSvc = OpenService(hSCM, svc, SERVICE_QUERY_STATUS);
        if (hSvc) {
            SERVICE_STATUS_PROCESS ssp;
            DWORD bytesNeeded;
            if (QueryServiceStatusEx(hSvc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(ssp), &bytesNeeded)) {
                if (ssp.dwCurrentState == SERVICE_RUNNING) {
                    CloseServiceHandle(hSvc);
                    CloseServiceHandle(hSCM);
                    return false; // 關鍵服務正在運行,極可能是正常模式
                }
            }
            CloseServiceHandle(hSvc);
        }
    }
    CloseServiceHandle(hSCM);
    return true; // 多數關鍵服務未運行
}

版本差異與注意事項

  • Windows 9x/Me:`SM_CLEANBOOT` 同樣有效,但安全模式定義不同 (無網路安全模式)
  • Windows 10/11:新增「安全模式 (命令提示字元)」,`SM_CLEANBOOT` 仍返回 1
  • Hyper-V/虛擬機:增強工作階段模式可能影響檢測,建議結合多種方法驗證
  • 快速啟動:混合關機/啟動不影響 `SM_CLEANBOOT` 返回值

實務應用場景

場景處理策略
硬體加速依賴應用 (遊戲、CAD、視訊編輯)安全模式下顯示警告並退出,或降級為軟體渲染模式
網路依賴服務 (雲端同步、授權驗證)僅在模式 2 (含網路安全模式) 允許網路功能,模式 1 禁用
系統工具 (註冊表清理、啟動項管理)安全模式下提供精簡功能集,避免誤刪關鍵項目
企業部署軟體記錄啟動模式至事件日誌/遙測,供 IT 稽核

結語

`GetSystemMetrics(SM_CLEANBOOT)` 是檢測 Windows 啟動模式的**標準、可靠、跨版本**方法。結合登錄、WMI、服務狀態等備援檢測,可構建健壯的環境適應性邏輯。開發者應在程式啟動早期 (如專案啟動順序優先級) 執行檢測,根據模式動態調整功能可用性、記錄診斷資訊、引導使用者切換至適當環境,提升軟體穩定度與用戶體驗。

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