最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過(guò)C#調(diào)用Windows?API的具體方法

 更新時(shí)間:2025年08月11日 09:45:37   作者:墨夶  
在開(kāi)發(fā)系統(tǒng)監(jiān)控工具、性能分析器或自動(dòng)化管理程序時(shí),Windows?API?是你與操作系統(tǒng)對(duì)話的橋梁,通過(guò)C#調(diào)用Windows?API可以直接訪問(wèn)系統(tǒng)底層數(shù)據(jù)、實(shí)現(xiàn)注冊(cè)表讀寫與電源狀態(tài)監(jiān)控以及無(wú)需額外依賴,純?cè)a實(shí)現(xiàn),所以本文給大家介紹了具體的調(diào)用方法,需要的朋友可以參考下

為什么你需要掌握Windows API調(diào)用?

在開(kāi)發(fā)系統(tǒng)監(jiān)控工具、性能分析器或自動(dòng)化管理程序時(shí),Windows API 是你與操作系統(tǒng)對(duì)話的橋梁。

  • 痛點(diǎn)1:.NET框架提供的System.Environment類無(wú)法獲取CPU型號(hào)、電池狀態(tài)等深度信息
  • 痛點(diǎn)2:注冊(cè)表操作與電源管理需依賴復(fù)雜第三方庫(kù)
  • 痛點(diǎn)3:跨平臺(tái)兼容性限制了低級(jí)硬件訪問(wèn)能力

通過(guò)C#調(diào)用Windows API

  • 直接訪問(wèn)系統(tǒng)底層數(shù)據(jù)(如CPU核心數(shù)、內(nèi)存顆粒)
  • 實(shí)現(xiàn)注冊(cè)表讀寫與電源狀態(tài)監(jiān)控
  • 無(wú)需額外依賴,純?cè)a實(shí)現(xiàn)

一、基礎(chǔ)篇:調(diào)用API的核心技巧

1.1 DllImport聲明與結(jié)構(gòu)體定義

using System;
using System.Runtime.InteropServices;

// 定義Windows API函數(shù)簽名
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint GetSystemInfo(out SYSTEM_INFO lpSystemInfo);

// 對(duì)應(yīng)的結(jié)構(gòu)體定義(按字段順序與API匹配)
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_INFO
{
    public ushort processorArchitecture; // 處理器架構(gòu)
    public ushort reserved;             // 保留字段
    public uint pageSize;               // 頁(yè)面大小
    public IntPtr minimumApplicationAddress; // 應(yīng)用程序最低地址
    public IntPtr maximumApplicationAddress; // 應(yīng)用程序最高地址
    public IntPtr activeProcessorMask;  // 活躍處理器掩碼
    public uint numberOfProcessors;     // 處理器數(shù)量
    public uint processorType;          // 處理器類型
    public uint allocationGranularity;  // 內(nèi)存分配粒度
    public ushort processorLevel;       // 處理器級(jí)別
    public ushort processorRevision;    // 處理器修訂號(hào)
}

關(guān)鍵細(xì)節(jié)

  • CharSet.Auto:自動(dòng)適配ANSI/Unicode編碼
  • LayoutKind.Sequential:保證結(jié)構(gòu)體字段順序與原生API一致

1.2 調(diào)用示例:獲取系統(tǒng)基本信息

public static void GetSystemHardwareInfo()
{
    SYSTEM_INFO sysInfo;
    if (GetSystemInfo(out sysInfo) != 0)
    {
        Console.WriteLine($"處理器架構(gòu): {sysInfo.processorArchitecture}");
        Console.WriteLine($"處理器數(shù)量: {sysInfo.numberOfProcessors}");
        Console.WriteLine($"頁(yè)面大小: {sysInfo.pageSize} bytes");
        Console.WriteLine($"內(nèi)存分配粒度: {sysInfo.allocationGranularity} bytes");
    }
    else
    {
        throw new Win32Exception(Marshal.GetLastWin32Error());
    }
}

輸出示例

處理器架構(gòu): 9(x64)
處理器數(shù)量: 8
頁(yè)面大小: 4096 bytes
內(nèi)存分配粒度: 65536 bytes

二、進(jìn)階篇:深度系統(tǒng)信息獲取

2.1 獲取CPU詳細(xì)信息(注冊(cè)表方式)

// 注冊(cè)表API聲明
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern long RegOpenKeyEx(
    IntPtr hKey, 
    string subKey, 
    uint ulOptions, 
    RegSAM samDesired, 
    out IntPtr phkResult);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern long RegQueryValueEx(
    IntPtr hKey, 
    string lpValueName, 
    uint lpReserved, 
    out uint lpType, 
    byte[] lpData, 
    ref uint lpcbData);

// 注冊(cè)表根鍵常量
private const int HKEY_LOCAL_MACHINE = -2147483642;

// 訪問(wèn)權(quán)限標(biāo)志
[Flags]
public enum RegSAM : uint
{
    QueryValue = 0x0001,
    EnumerateSubKeys = 0x0008
}

// 獲取CPU名稱
public static string GetCpuName()
{
    IntPtr hKey;
    const string keyPath = @"HARDWARE\DESCRIPTION\System\CentralProcessor\0";
    
    // 打開(kāi)注冊(cè)表鍵
    long result = RegOpenKeyEx(
        (IntPtr)HKEY_LOCAL_MACHINE, 
        keyPath, 
        0, 
        RegSAM.QueryValue, 
        out hKey);
    
    if (result != 0)
    {
        throw new Win32Exception((int)result);
    }

    // 查詢ProcessorNameString值
    uint dataType = 0;
    uint dataSize = 1024;
    byte[] dataBuffer = new byte[dataSize];
    
    result = RegQueryValueEx(
        hKey, 
        "ProcessorNameString", 
        0, 
        out dataType, 
        dataBuffer, 
        ref dataSize);
    
    if (result != 0)
    {
        throw new Win32Exception((int)result);
    }

    // 轉(zhuǎn)換為字符串并清理無(wú)效字符
    return Encoding.Default.GetString(dataBuffer).Trim('\0');
}

實(shí)際應(yīng)用

Console.WriteLine($"CPU型號(hào): {GetCpuName()}");
// 輸出示例: "Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz"

2.2 獲取系統(tǒng)時(shí)間與電源狀態(tài)

// 獲取系統(tǒng)時(shí)間
[DllImport("kernel32.dll", SetLastError = true)]
public static extern void GetSystemTime(ref SYSTEMTIME st);

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
    public ushort wYear;
    public ushort wMonth;
    public ushort wDayOfWeek;
    public ushort wDay;
    public ushort wHour;
    public ushort wMinute;
    public ushort wSecond;
    public ushort wMilliseconds;
}

// 獲取電源狀態(tài)
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetSystemPowerStatus(ref SYSTEM_POWER_STATUS powerStatus);

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_POWER_STATUS
{
    public byte ACLineStatus;         // 交流電源狀態(tài)
    public byte BatteryFlag;          // 電池標(biāo)志
    public byte BatteryLifePercent;   // 電池百分比
    public byte Reserved1;
    public uint BatteryLifeTime;      // 剩余時(shí)間(秒)
    public uint BatteryFullLifeTime;  // 總?cè)萘浚耄?
}

調(diào)用示例

public static void GetSystemTimeAndPowerStatus()
{
    SYSTEMTIME sysTime = new SYSTEMTIME();
    GetSystemTime(ref sysTime);
    
    Console.WriteLine($"系統(tǒng)時(shí)間: {sysTime.wYear}-{sysTime.wMonth}-{sysTime.wDay} {sysTime.wHour}:{sysTime.wMinute}:{sysTime.wSecond}");

    SYSTEM_POWER_STATUS powerStatus = new SYSTEM_POWER_STATUS();
    if (GetSystemPowerStatus(ref powerStatus))
    {
        string acStatus = powerStatus.ACLineStatus == 1 ? "已連接" : "未連接";
        string batteryStatus = powerStatus.BatteryFlag switch
        {
            1 => "電量不足",
            2 => "正在充電",
            4 => "電池未安裝",
            _ => "未知狀態(tài)"
        };

        Console.WriteLine($"電源狀態(tài): {acStatus}");
        Console.WriteLine($"電池狀態(tài): {batteryStatus}");
        Console.WriteLine($"剩余電量: {powerStatus.BatteryLifePercent}%");
        Console.WriteLine($"剩余時(shí)間: {powerStatus.BatteryLifeTime / 3600}小時(shí){(powerStatus.BatteryLifeTime % 3600) / 60}分鐘");
    }
}

輸出示例

系統(tǒng)時(shí)間: 2025-07-19 18:06:48
電源狀態(tài): 已連接
電池狀態(tài): 正在充電
剩余電量: 85%
剩余時(shí)間: 3小時(shí)45分鐘

三、實(shí)戰(zhàn)篇:綜合系統(tǒng)信息收集器

3.1 項(xiàng)目結(jié)構(gòu)設(shè)計(jì)

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("=== 系統(tǒng)信息收集器 ===\n");
        
        // 獲取硬件信息
        GetSystemHardwareInfo();
        Console.WriteLine("\n=== CPU信息 ===");
        Console.WriteLine($"CPU型號(hào): {GetCpuName()}");
        
        // 獲取時(shí)間與電源狀態(tài)
        Console.WriteLine("\n=== 系統(tǒng)時(shí)間與電源 ===");
        GetSystemTimeAndPowerStatus();
        
        // 獲取內(nèi)存信息
        Console.WriteLine("\n=== 內(nèi)存信息 ===");
        GetMemoryInfo();
        
        Console.WriteLine("\n=== 網(wǎng)絡(luò)信息 ===");
        GetNetworkInfo();
    }
}

3.2 獲取內(nèi)存信息

// 獲取內(nèi)存信息
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);

[StructLayout(LayoutKind.Sequential)]
public struct MEMORYSTATUS
{
    public uint dwLength;
    public uint dwMemoryLoad;         // 內(nèi)存使用百分比
    public ulong ullTotalPhys;        // 物理內(nèi)存總量
    public ulong ullAvailPhys;        // 可用物理內(nèi)存
    public ulong ullTotalPageFile;    // 頁(yè)面文件總量
    public ulong ullAvailPageFile;    // 可用頁(yè)面文件
    public ulong ullTotalVirtual;     // 虛擬內(nèi)存總量
    public ulong ullAvailVirtual;     // 可用虛擬內(nèi)存
}

public static void GetMemoryInfo()
{
    MEMORYSTATUS memoryStatus = new MEMORYSTATUS();
    memoryStatus.dwLength = (uint)Marshal.SizeOf(memoryStatus);
    
    if (!GlobalMemoryStatus(ref memoryStatus))
    {
        throw new Win32Exception(Marshal.GetLastWin32Error());
    }

    Console.WriteLine($"內(nèi)存使用率: {memoryStatus.dwMemoryLoad}%");
    Console.WriteLine($"物理內(nèi)存總量: {memoryStatus.ullTotalPhys / 1024 / 1024} MB");
    Console.WriteLine($"可用物理內(nèi)存: {memoryStatus.ullAvailPhys / 1024 / 1024} MB");
    Console.WriteLine($"虛擬內(nèi)存總量: {memoryStatus.ullTotalVirtual / 1024 / 1024} MB");
    Console.WriteLine($"可用虛擬內(nèi)存: {memoryStatus.ullAvailVirtual / 1024 / 1024} MB");
}

3.3 獲取網(wǎng)絡(luò)信息

// 獲取網(wǎng)絡(luò)適配器信息
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint GetAdaptersInfo(IntPtr pAdapterInfo, ref uint pOutBufLen);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct IP_ADAPTER_INFO
{
    public uint ComboIndex;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string AdapterName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string Description;
    public uint AddressLength;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    public byte[] Address;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string AddressString;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string DnsName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string DnsSuffix;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string DnsDescription;
    public uint PhysicalAddressLength;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    public byte[] PhysicalAddress;
    public uint Flags;
    public uint Mtu;
    public uint IfType;
    public uint EnableType;
    public uint OperStatus;
    public uint Ipv6IfIndex;
    public uint ZoneIndices;
    public IntPtr FirstUnicastAddress;
    public IntPtr FirstAnycastAddress;
    public IntPtr FirstMulticastAddress;
    public IntPtr FirstDnsServerAddress;
    public IntPtr FirstDnsSuffix;
}

public static void GetNetworkInfo()
{
    uint bufferSize = 15000;
    IntPtr buffer = Marshal.AllocHGlobal((int)bufferSize);
    
    uint result = GetAdaptersInfo(buffer, ref bufferSize);
    
    if (result == 0)
    {
        IP_ADAPTER_INFO adapterInfo = (IP_ADAPTER_INFO)Marshal.PtrToStructure(buffer, typeof(IP_ADAPTER_INFO));
        
        Console.WriteLine($"適配器名稱: {adapterInfo.AdapterName}");
        Console.WriteLine($"描述: {adapterInfo.Description}");
        Console.WriteLine($"MAC地址: {BitConverter.ToString(adapterInfo.Address).Replace("-", ":")}");
        Console.WriteLine($"IP地址: {adapterInfo.AddressString}");
    }
    else
    {
        throw new Win32Exception((int)result);
    }
    
    Marshal.FreeHGlobal(buffer);
}

四、性能優(yōu)化與注意事項(xiàng)

4.1 內(nèi)存安全與異常處理

  • 緩沖區(qū)溢出:使用StringBuilder時(shí)需預(yù)分配足夠容量
  • 結(jié)構(gòu)體對(duì)齊:通過(guò)[StructLayout(LayoutKind.Sequential)]保證字段順序
  • 錯(cuò)誤碼處理:始終檢查API返回值并調(diào)用Marshal.GetLastWin32Error()

4.2 跨平臺(tái)兼容性

  • Windows API僅適用于Windows系統(tǒng),Linux/macOS需改用POSIX接口
  • 使用條件編譯區(qū)分平臺(tái):
#if WINDOWS
// Windows-specific code
#else
// Cross-platform code
#endif

五、 何時(shí)選擇哪種方法?

需求推薦方法典型示例
獲取CPU型號(hào)注冊(cè)表讀取(RegQueryValueEx)GetCpuName()
獲取系統(tǒng)時(shí)間GetSystemTimeGetSystemTimeAndPowerStatus()
獲取內(nèi)存信息GlobalMemoryStatusGetMemoryInfo()
獲取網(wǎng)絡(luò)適配器信息GetAdaptersInfoGetNetworkInfo()
獲取電源狀態(tài)GetSystemPowerStatusGetSystemTimeAndPowerStatus()

立即行動(dòng)

  1. 升級(jí)代碼:將.NET Environment替換為原生API獲取更詳細(xì)信息
  2. 重構(gòu)工具:將現(xiàn)有系統(tǒng)監(jiān)控工具改為API調(diào)用以提升性能
  3. 探索注冊(cè)表:嘗試讀取其他系統(tǒng)配置信息(如啟動(dòng)項(xiàng)、服務(wù)列表)

以上就是C#調(diào)用Windows API的具體方法的詳細(xì)內(nèi)容,更多關(guān)于C#調(diào)用Windows API的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#11新特性預(yù)覽及使用介紹

    C#11新特性預(yù)覽及使用介紹

    這篇文章主要為大家介紹了C#11新特性預(yù)覽及使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 深入理解C#中回調(diào)函數(shù)

    深入理解C#中回調(diào)函數(shù)

    回調(diào)函數(shù)是一種在編程中常用的概念,本文將介紹回調(diào)函數(shù)的概念、語(yǔ)法和應(yīng)用,并討論如何設(shè)計(jì)優(yōu)化和重用回調(diào)函數(shù),以及它們?cè)诓l(fā)編程中的用途,感興趣的可以了解一下
    2024-02-02
  • C#中int[][]與int[,]的使用與區(qū)別

    C#中int[][]與int[,]的使用與區(qū)別

    本文主要介紹了C#中int[][]與int[,]的使用與區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • C# WebApi 接口返回值不困惑:返回值類型詳解

    C# WebApi 接口返回值不困惑:返回值類型詳解

    這篇文章主要介紹了C# WebApi 接口返回值不困惑:返回值類型詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 使用C#編寫簡(jiǎn)單的圖形化的可發(fā)送附件的郵件客戶端程序

    使用C#編寫簡(jiǎn)單的圖形化的可發(fā)送附件的郵件客戶端程序

    這篇文章主要介紹了使用C#編寫一個(gè)圖形化的可發(fā)送附件的郵件客戶端程序的方法,文中的示例同樣是基于支持smtp協(xié)議的郵件服務(wù)器,需要的朋友可以參考下
    2016-02-02
  • C#中如何使用Winform實(shí)現(xiàn)炫酷的透明動(dòng)畫界面

    C#中如何使用Winform實(shí)現(xiàn)炫酷的透明動(dòng)畫界面

    這篇文章講解了如何使用Winform實(shí)現(xiàn)炫酷的透明動(dòng)畫界面,Winform相對(duì)于Wpf使用更簡(jiǎn)單一些,系統(tǒng)要求更低,需要了解的朋友可以參考下
    2015-07-07
  • C#使用對(duì)象序列化類庫(kù)MessasgePack

    C#使用對(duì)象序列化類庫(kù)MessasgePack

    這篇文章介紹了C#使用對(duì)象序列化類庫(kù)MessasgePack的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • C# 計(jì)算標(biāo)準(zhǔn)偏差相當(dāng)于Excel中的STDEV函數(shù)實(shí)例

    C# 計(jì)算標(biāo)準(zhǔn)偏差相當(dāng)于Excel中的STDEV函數(shù)實(shí)例

    下面小編就為大家?guī)?lái)一篇C# 計(jì)算標(biāo)準(zhǔn)偏差相當(dāng)于Excel中的STDEV函數(shù)實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • C#線程入門教程之單線程介紹

    C#線程入門教程之單線程介紹

    這篇文章主要介紹了C#線程入門教程之單線程介紹,本文講解了什么是進(jìn)程、什么是線程、什么是多線程等內(nèi)容,并給出了一個(gè)單線程代碼示例,需要的朋友可以參考下
    2015-02-02
  • C#面向?qū)ο蟮?3種設(shè)計(jì)模式介紹

    C#面向?qū)ο蟮?3種設(shè)計(jì)模式介紹

    這篇文章介紹了C#面向?qū)ο蟮?3種設(shè)計(jì)模式,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02

最新評(píng)論

务川| 板桥市| 北川| 东辽县| 南投市| 黄浦区| 比如县| 乌兰察布市| 连南| 桂阳县| 马公市| 岳阳市| 柞水县| 孟州市| 吉首市| 习水县| 武胜县| 鹤壁市| 鹰潭市| 花垣县| 东港市| 同心县| 台前县| 朔州市| 灵川县| 卢氏县| 泰兴市| 贵定县| 嘉定区| 石棉县| 图木舒克市| 监利县| 嘉定区| 永仁县| 南通市| 富裕县| 随州市| 游戏| 任丘市| 梨树县| 绥化市|