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

Windows 7 開發實戰:版本檢查正確姿勢 — 管理代碼篇

     編輯:關於.NET

實驗目標

  • 理解版本檢查失敗的常見原因與相容模式應對
  • 掌握「檢查最低版本」而非「檢查特定版本」的正確邏輯
  • 學會「功能檢測」取代「版本檢測」的最佳實踐

系統需求

  • Microsoft Visual Studio 2008
  • Microsoft Windows 7

練習:版本檢測陷阱與破解之道

任務 1:體驗錯誤的版本檢查

  1. 開啟 VersionCheck 方案,設定 Debug/x86
  2. 設定 VersionCheckManagedBroken 為啟動專案
  3. 檢視 Program.cs:Environment.OSVersion.Version != new Version(5,1) 硬編碼要求 Windows XP (5.1)
  4. 執行 → 彈出「不相容的作業系統」錯誤(因在 Win 7 上運行,版本為 6.1)
建置設定 Debug/x86
版本檢查失敗錯誤訊息
> ⚠️ **注意**:相容模式對純受控代碼 Environment.OSVersion 無效。若為混合模式應用程式(透過 P/Invoke 呼叫原生版本 API),相容模式仍可生效。

任務 2:修正為「最低版本」檢查

// 檢查作業系統是否至少為 Windows XP
if (Environment.OSVersion.Version < new Version(5, 1))
{
    MessageBox.Show("Windows XP or later required.",
        "Incompatible Operating System", MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}
  • 將 != 改為 <:允許 5.1 (XP)、6.0 (Vista)、6.1 (Win 7) 等所有大於等於 5.1 的版本
  • 重新執行 → 應用程式正常啟動

任務 3:功能檢測 — 不依賴版本號判斷 API 可用性

情境:SetWaitableTimerEx (Win 7 新增) 支援計時器合併容錯,節省 CPU/電力。舊版用 SetWaitableTimer。

模式:先試新 API,失敗再落回舊 API

public void Start(long dueTime, int period)
{
    ReasonContext rc = new ReasonContext();
    rc.Version = 0;
    rc.Flags = 1;
    rc.SimpleReasonString = "MyTimer";

    try
    {
        // 嘗試 Win 7 新版 API
        if (!Win32.SetWaitableTimerEx(_hTimer, ref dueTime, period,
            IntPtr.Zero, IntPtr.Zero, ref rc, 5000))
            throw new Win32Exception(Marshal.GetLastWin32Error(), "SetWaitableTimerEx failed.");

        IsCoalescingtimer = true;
    }
    catch (EntryPointNotFoundException)
    {
        // 找不到函數 → 落回舊版
        IsCoalescingtimer = false;
        if (!Win32.SetWaitableTimer(_hTimer, ref dueTime, period,
            IntPtr.Zero, IntPtr.Zero, false))
            throw new Win32Exception(Marshal.GetLastWin32Error(), "SetWaitableTimer failed.");
    }

    _waiterThread = new Thread(WaiterThreadProc);
    _waiterThread.Name = "Waiter thread for WaitableTimer";
    _waiterThread.Start();
}

關鍵點:

  • EntryPointNotFoundException 捕捉「DLL 中找不到函數」
  • 優雅降級:功能存在用新版,不存在用舊版,而非直接拒絕運行
  • 執行結果會顯示是否使用了新版計時器 API
執行結果顯示 API 版本
> 💡 **架構建議**:此範例為教學簡化將邏輯寫在 UI 層。實際專案請遵循 MVP/MVVM,將版本/功能檢測封裝於獨立服務層,便於測試與維護。

核心原則總結

錯誤做法正確做法
檢查 Version == 5.1 (硬編碼特定版本)檢查 Version >= 5.1 (最低版本門檻)
阻擋未測試的未來版本允許未來版本運行,靠功能檢測處理差異
依賴 GetVersionEx/Environment.OSVersion優先 VerifyVersionInfo (原生) / Version 比較 (受控)
版本檢測決定功能可用性直接檢測功能 (P/Invoke GetProcAddress、COM QueryInterface、捕捉 EntryPointNotFoundException)

工具與資源

  • 應用程式相容性工具組 (ACT)
  • 相容模式手動設定:.exe 內容 → 相容性標籤
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved