API函數是構築Windows應用程序的基石,是Windows編程的必備利器。每一種Windows應用程序開發工具都提供了間接或直接調用了Windows API函數的方法,或者是調用Windows API函數的接口,也就是説具備調用動態連接庫的能力。Visual C#和其它開發工具一樣也能夠調用動態鏈接庫的API函數。本文中筆者就結合實例向大家介紹在Visual C#中如何調用各種返回值的API,該實例就是一個通過API函數調用獲取系統信息的程序。

Visual C#中調用API的基本過程:

  首先,在調用API之前,你必須先導入System.Runtime.InteropServices這個名稱空間。該名稱空間包含了在Visual C#中調用API的一些必要集合,具體的方法如下:

   using System.Runtime.InteropServices; 
 在導入了名稱空間後,我們要聲明在程序中所要用到的API函數。我們的程序主要是獲取系統的相關信息,所以用到的API函數都是返回系統信息的。先給出在Visual C#中聲明API的方法:

[DllImport("kernel32")] 
public static extern void GetWindowsDirectory(StringBuilder WinDir,int count);

 

  其中,"DllImport"屬性用來從不可控代碼中調用一個方法,它指定了DLL的位置,該DLL中包含調用的外部方法;"kernel32"設定了類庫名;"public"指明函數的訪問類型為公有的;"static"修飾符聲明一個靜態元素,而該元素屬於類型本身而不是指定的對象;"extern"表示該方法將在工程外部執行,同時使用DllImport導入的方法必須使用"extern"修飾符;最後GetWindowsDirectory函數包含了兩個參數,一個為StringBuilder類型的,另一個為int類型的,該方法返回的內容存在於StringBuilder類型的參數中。同時,因為我們在這裏使用到了StringBuilder類,所以在程序的開始處,我們還得添加System.Text這個名稱空間,方法同上。

  其他幾個API函數的聲明如下:

[DllImport("kernel32")] 
public static extern void GetSystemDirectory(StringBuilder SysDir,int count);
[DllImport("kernel32")] 
public static extern void GetSystemInfo(ref CPU_INFO cpuinfo); 
[DllImport("kernel32")] 
public static extern void GlobalMemoryStatus(ref MEMORY_INFO meminfo); 
[DllImport("kernel32")] 
public static extern void GetSystemTime(ref SYSTEMTIME_INFO stinfo);

 

  以上幾個API的作用分別是獲取系統路徑,獲得CPU相關信息,獲得內存的相關信息,獲得系統時間等。

在聲明完所有的API函數後,我們發現後三個函數分別用到了CPU_INFO、MEMORY_INFO、SYSTEMTIME_INFO等結構,這些結構並非是.Net內部的,它們從何而來?其實,我們在用到以上API調用時均需用到以上結構,我們將函數調用獲得的信息存放在以上的結構體中,最後返回給程序輸出。這些結構體比較複雜,但是如果開發者能夠熟練運用,那麼整個API世界將盡在開發者的掌握之中。以下就是上述結構體的聲明:

//定義以下各結構
//定義CPU的信息結構
[StructLayout(LayoutKind.Sequential)] 
public struct CPU_INFO 
{ 
public uint dwOemId; 
public uint dwPageSize; 
public uint lpMinimumApplicationAddress; 
public uint lpMaximumApplicationAddress; 
public uint dwActiveProcessorMask; 
public uint dwNumberOfProcessors; 
public uint dwProcessorType; 
public uint dwAllocationGranularity; 
public uint dwProcessorLevel; 
public uint dwProcessorRevision; 
}
//定義內存的信息結構
[StructLayout(LayoutKind.Sequential)] 
public struct MEMORY_INFO 
{
public uint dwLength;
public uint dwMemoryLoad; 
public uint dwTotalPhys; 
public uint dwAvailPhys; 
public uint dwTotalPageFile; 
public uint dwAvailPageFile; 
public uint dwTotalVirtual; 
public uint dwAvailVirtual; 
}
//定義系統時間的信息結構
[StructLayout(LayoutKind.Sequential)] 
public struct SYSTEMTIME_INFO 
{ 
public ushort wYear; 
public ushort wMonth; 
public ushort wDayOfWeek; 
public ushort wDay; 
public ushort wHour; 
public ushort wMinute; 
public ushort wSecond; 
public ushort wMilliseconds; 
}

 

  結構體定義的主體部分和C++中的沒多大差別,具體每個結構體內部成員的定義可參考聯機幫助中的SDK文檔。同時,我們還發現在每個結構體定義的上面都有一句用中括號括起來的説明性文字。這些説明都是有關結構體成員的佈局的,共有三種選項,分別説明如下:

  LayoutKind.Automatic:為了提高效率允許運行態對類型成員重新排序。

    注意:永遠不要使用這個選項來調用不受管轄的動態鏈接庫函數。

  LayoutKind.Explicit:對每個域按照FieldOffset屬性對類型成員排序

  LayoutKind.Sequential:對出現在受管轄類型定義地方的不受管轄內存中的類型成員進行排序。

  在上面的程序中,為了方便起見我們都用到了第三種方式所有的API函數以及相關的結構體聲明完畢後,我們就運用這些API來實現我們的程序功能――獲取系統的相關信息。

  界面可按如下方式佈置,不過有興趣的讀者自然可以發揮自己的想象,將界面佈局做得更好。

 


 

  簡單的界面佈置好後,我們添加一個按鈕("獲取信息"按鈕)的消息處理函數如下:

private void GetInfo_Click(object sender, System.EventArgs e)
{
//調用GetWindowsDirectory和GetSystemDirectory函數分別取得Windows路徑和系統路徑
const int nChars = 128;
StringBuilder Buff = new StringBuilder(nChars);
GetWindowsDirectory(Buff,nChars);
WindowsDirectory.Text = "Windows路徑:"+Buff.ToString();
GetSystemDirectory(Buff,nChars);
SystemDirectory.Text = "系統路徑:"+Buff.ToString();
//調用GetSystemInfo函數獲取CPU的相關信息
CPU_INFO CpuInfo;
CpuInfo = new CPU_INFO();
GetSystemInfo(ref CpuInfo);
NumberOfProcessors.Text = "本計算機中有"+CpuInfo.dwNumberOfProcessors.ToString()+"個CPU";
ProcessorType.Text = "CPU的類型為"+CpuInfo.dwProcessorType.ToString();
ProcessorLevel.Text = "CPU等級為"+CpuInfo.dwProcessorLevel.ToString();
OemId.Text = "CPU的OEM ID為"+CpuInfo.dwOemId.ToString();
PageSize.Text = "CPU中的頁面大小為"+CpuInfo.dwPageSize.ToString();
//調用GlobalMemoryStatus函數獲取內存的相關信息
MEMORY_INFO MemInfo;
MemInfo = new MEMORY_INFO();
GlobalMemoryStatus(ref MemInfo);
MemoryLoad.Text = MemInfo.dwMemoryLoad.ToString()+"%的內存正在使用";
TotalPhys.Text = "物理內存共有"+MemInfo.dwTotalPhys.ToString()+"字節";
AvailPhys.Text = "可使用的物理內存有"+MemInfo.dwAvailPhys.ToString()+"字節";
TotalPageFile.Text = "交換文件總大小為"+MemInfo.dwTotalPageFile.ToString()+"字節";
AvailPageFile.Text = "尚可交換文件大小為"+MemInfo.dwAvailPageFile.ToString()+"字節";
TotalVirtual.Text = "總虛擬內存有"+MemInfo.dwTotalVirtual.ToString()+"字節";
AvailVirtual.Text = "未用虛擬內存有"+MemInfo.dwAvailVirtual.ToString()+"字節";
//調用GetSystemTime函數獲取系統時間信息
SYSTEMTIME_INFO StInfo;
StInfo = new SYSTEMTIME_INFO();
GetSystemTime(ref StInfo);
Date.Text = StInfo.wYear.ToString()+"年"+StInfo.wMonth.ToString()+"月"+StInfo.wDay.ToString()+"日";
Time.Text = (StInfo.wHour+8).ToString()+"點"+StInfo.wMinute.ToString()+"分"+StInfo.wSecond.ToString()+"秒";
}

 

  在上面的消息處理函數中,我們運用了在程序開始處聲明的各個API函數獲取了系統的相關信息,並最終在界面上以文本標籤的方式顯示結果。各個文本標籤的命名方式可以參見文後附帶的源代碼,此處暫略。

最後,運行程序如下:

langchain api 調用次數 多少錢_Windows


 

結束語:

  通過本文的學習,我相信稍有API使用基礎的開發者可以馬上觸類旁通,很快掌握Visual C#中對API的操作。上面給出的實例僅僅是一個非常簡單的示例程序,不過有興趣的讀者可以進一步完善其功能,做出更完美的系統信息檢測程序。