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

在 C# 中透過 Windows API 取得磁碟區序號

     編輯:關於C語言

前言

常有開發者詢問如何在 VB.NET 中取得硬碟序號。最簡單的方式是透過 WMI 類別,但這實際上取得的是「磁碟區序號」,而非硬碟製造商燒錄的實體序號。磁碟區序號在格式化時產生,且無需重新格式化即可變更,雖然實務上較少這樣做。

本文嘗試使用 Windows 原生 API GetVolumeInformation 來達成同樣目的,這需要在 C# 中使用 P/Invoke。這項技術對軟體授權機制非常實用:例如在安裝時讀取使用者 C 槽的磁碟區序號,透過網路註冊模組送至 Web Service,作為加密金鑰產生合法授權碼,寫入登錄表。若嘗試將單機授權產品安裝至另一台電腦,金鑰將失效。

P/Invoke 簽章的關鍵細節

呼叫非受控 API 時,參數型別必須精確對應。GetVolumeInformation 的簽章如下:

[DllImport("kernel32.dll")]
private static extern long GetVolumeInformation(
    string PathName,
    StringBuilder VolumeNameBuffer,
    UInt32 VolumeNameSize,
    ref UInt32 VolumeSerialNumber,
    ref UInt32 MaximumComponentLength,
    ref UInt32 FileSystemFlags,
    StringBuilder FileSystemNameBuffer,
    UInt32 FileSystemNameSize
);

注意:部分直覺上應為 int 的參數,實際必須用 UInt32(對應 .NET 的 uint);字串參數則常需以 StringBuilder 傳遞。

完整實作範例

以下封裝方法回傳字串格式的序號,方便直接使用:

public string GetVolumeSerial(string strDriveLetter)
{
    uint serNum = 0;
    uint maxCompLen = 0;
    StringBuilder volLabel = new StringBuilder(256); // 磁碟標籤
    UInt32 volFlags = new UInt32();
    StringBuilder fsName = new StringBuilder(256);   // 檔案系統名稱

    strDriveLetter += ":\\"; // 補全路徑格式,例如 "C:\\"

    long ret = GetVolumeInformation(
        strDriveLetter,
        volLabel,
        (UInt32)volLabel.Capacity,
        ref serNum,
        ref maxCompLen,
        ref volFlags,
        fsName,
        (UInt32)fsName.Capacity
    );

    return Convert.ToString(serNum);
}

應用場景與注意事項

  • 軟體授權綁定:將序號作為機器指紋,搭配非對稱加密產生授權檔。
  • 磁碟區 vs 實體硬碟:重新格式化會改變磁碟區序號,若需更穩定的識別碼,需查詢 SMART 資訊或使用廠商專屬工具。
  • 權限需求:讀取系統磁碟區(如 C:)通常需要管理員權限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved