在C#中調用API的基本過程 .

 
  1. 首先,在調用API之前,你必須先導入System.Runtime.InteropServices這個名稱空間。該名稱空間包含了在Visual   C#中調用API的一些必要集合,具體的方法如下:     
  2.      using   System.Runtime.InteropServices;     
  3.     在導入了名稱空間後,我們要聲明在程序中所要用到的API函數。我們的程序主要是獲取系統的相關信息,所以用到的API函數都是返回系統信息的。先給出在Visual   C#中聲明API的方法:     
  4.   [DllImport("kernel32")]       
  5.   public   static   extern   void   GetWindowsDirectory(StringBuilder   WinDir,int   count);     
  6.       
  7.     其中,"DllImport"屬性用來從不可控代碼中調用一個方法,它指定了DLL的位置,該DLL中包含調用的外部方法;"kernel32"設定了類庫名;"public"指明函數的訪問類型爲公有的;"static"修飾符聲明一個靜態元素,而該元素屬於類型本身而不是指定的對象;"extern"表示該方法將在工程外部執行,同時使用DllImport導入的方法必須使用"extern"修飾符;最後GetWindowsDirectory函數包含了兩個參數,一個爲StringBuilder類型的,另一個爲int類型的,該方法返回的內容存在於StringBuilder類型的參數中。同時,因爲我們在這裏使用到了StringBuilder類,所以在程序的開始處,我們還得添加System.Text這個名稱空間,方法同上。     
  8.     其他幾個API函數的聲明如下:     
  9.   [DllImport("kernel32")]       
  10.   public   static   extern   void   GetSystemDirectory(StringBuilder   SysDir,int   count);     
  11.   [DllImport("kernel32")]       
  12.   public   static   extern   void   GetSystemInfo(ref   CPU_INFO   cpuinfo);       
  13.   [DllImport("kernel32")]       
  14.   public   static   extern   void   GlobalMemoryStatus(ref   MEMORY_INFO   meminfo);       
  15.   [DllImport("kernel32")]       
  16.   public   static   extern   void   GetSystemTime(ref   SYSTEMTIME_INFO   stinfo);     
  17.       
  18.     以上幾個API的作用分別是獲取系統路徑,獲得CPU相關信息,獲得內存的相關信息,獲得系統時間等。     
  19.   在聲明完所有的API函數後,我們發現後三個函數分別用到了CPU_INFO、MEMORY_INFO、SYSTEMTIME_INFO等結構,這些結構並非是.Net內部的,它們從何而來?其實,我們在用到以上API調用時均需用到以上結構,我們將函數調用獲得的信息存放在以上的結構體中,最後返回給程序輸出。這些結構體比較複雜,但是如果開發者能夠熟練運用,那麼整個API世界將盡在開發者的掌握之中。以下就是上述結構體的聲明:     
  20.   //定義以下各結構      
  21.   //定義CPU的信息結構      
  22.   [StructLayout(LayoutKind.Sequential)]       
  23.   public   struct   CPU_INFO       
  24.   {       
  25.   public   uint   dwOemId;       
  26.   public   uint   dwPageSize;       
  27.   public   uint   lpMinimumApplicationAddress;       
  28.   public   uint   lpMaximumApplicationAddress;       
  29.   public   uint   dwActiveProcessorMask;       
  30.   public   uint   dwNumberOfProcessors;       
  31.   public   uint   dwProcessorType;       
  32.   public   uint   dwAllocationGranularity;       
  33.   public   uint   dwProcessorLevel;       
  34.   public   uint   dwProcessorRevision;       
  35.   }     
  36.   //定義內存的信息結構      
  37.   [StructLayout(LayoutKind.Sequential)]       
  38.   public   struct   MEMORY_INFO       
  39.   {     
  40.   public   uint   dwLength;     
  41.   public   uint   dwMemoryLoad;       
  42.   public   uint   dwTotalPhys;       
  43.   public   uint   dwAvailPhys;       
  44.   public   uint   dwTotalPageFile;       
  45.   public   uint   dwAvailPageFile;       
  46.   public   uint   dwTotalVirtual;       
  47.   public   uint   dwAvailVirtual;       
  48.   }     
  49.   //定義系統時間的信息結構      
  50.   [StructLayout(LayoutKind.Sequential)]       
  51.   public   struct   SYSTEMTIME_INFO       
  52.   {       
  53.   public   ushort   wYear;       
  54.   public   ushort   wMonth;       
  55.   public   ushort   wDayOfWeek;       
  56.   public   ushort   wDay;       
  57.   public   ushort   wHour;       
  58.   public   ushort   wMinute;       
  59.   public   ushort   wSecond;       
  60.   public   ushort   wMilliseconds;       
  61.   }     
  62.       
  63.     結構體定義的主體部分和C++中的沒多大差別,具體每個結構體內部成員的定義可參考聯機幫助中的SDK文檔。同時,我們還發現在每個結構體定義的上面都有一句用中括號括起來的說明性文字。這些說明都是有關結構體成員的佈局的,共有三種選項,分別說明如下:     
  64.     LayoutKind.Automatic:爲了提高效率允許運行態對類型成員重新排序。       
  65.         注意:永遠不要使用這個選項來調用不受管轄的動態鏈接庫函數。       
  66.     LayoutKind.Explicit:對每個域按照FieldOffset屬性對類型成員排序       
  67.     LayoutKind.Sequential:對出現在受管轄類型定義地方的不受管轄內存中的類型成員進行排序。     
  68.     在上面的程序中,爲了方便起見我們都用到了第三種方式所有的API函數以及相關的結構體聲明完畢後,我們就運用這些API來實現我們的程序功能――獲取系統的相關信息。     
  69.     界面可按如下方式佈置,不過有興趣的讀者自然可以發揮自己的想象,將界面佈局做得更好。     
  70.   簡單的界面佈置好後,我們添加一個按鈕("獲取信息"按鈕)的消息處理函數如下:     
  71.   private   void   GetInfo_Click(object   sender,   System.EventArgs   e)     
  72.   {     
  73.   //調用GetWindowsDirectory和GetSystemDirectory函數分別取得Windows路徑和系統路徑      
  74.   const   int   nChars   =   128;     
  75.   StringBuilder   Buff   =   new   StringBuilder(nChars);     
  76.   GetWindowsDirectory(Buff,nChars);     
  77.   WindowsDirectory.Text   =   "Windows路徑:"+Buff.ToString();     
  78.   GetSystemDirectory(Buff,nChars);     
  79.   SystemDirectory.Text   =   "系統路徑:"+Buff.ToString();     
  80.   //調用GetSystemInfo函數獲取CPU的相關信息      
  81.   CPU_INFO   CpuInfo;     
  82.   CpuInfo   =   new   CPU_INFO();     
  83.   GetSystemInfo(ref   CpuInfo);     
  84.   NumberOfProcessors.Text   =   "本計算機中有"+CpuInfo.dwNumberOfProcessors.ToString()+"個CPU";     
  85.   ProcessorType.Text   =   "CPU的類型爲"+CpuInfo.dwProcessorType.ToString();     
  86.   ProcessorLevel.Text   =   "CPU等級爲"+CpuInfo.dwProcessorLevel.ToString();     
  87.   OemId.Text   =   "CPU的OEM   ID爲"+CpuInfo.dwOemId.ToString();     
  88.   PageSize.Text   =   "CPU中的頁面大小爲"+CpuInfo.dwPageSize.ToString();     
  89.   //調用GlobalMemoryStatus函數獲取內存的相關信息      
  90.   MEMORY_INFO   MemInfo;     
  91.   MemInfo   =   new   MEMORY_INFO();     
  92.   GlobalMemoryStatus(ref   MemInfo);     
  93.   MemoryLoad.Text   =   MemInfo.dwMemoryLoad.ToString()+"%的內存正在使用";     
  94.   TotalPhys.Text   =   "物理內存共有"+MemInfo.dwTotalPhys.ToString()+"字節";     
  95.   AvailPhys.Text   =   "可使用的物理內存有"+MemInfo.dwAvailPhys.ToString()+"字節";     
  96.   TotalPageFile.Text   =   "交換文件總大小爲"+MemInfo.dwTotalPageFile.ToString()+"字節";     
  97.   AvailPageFile.Text   =   "尚可交換文件大小爲"+MemInfo.dwAvailPageFile.ToString()+"字節";     
  98.   TotalVirtual.Text   =   "總虛擬內存有"+MemInfo.dwTotalVirtual.ToString()+"字節";     
  99.   AvailVirtual.Text   =   "未用虛擬內存有"+MemInfo.dwAvailVirtual.ToString()+"字節";     
  100.   //調用GetSystemTime函數獲取系統時間信息      
  101.   SYSTEMTIME_INFO   StInfo;     
  102.   StInfo   =   new   SYSTEMTIME_INFO();     
  103.   GetSystemTime(ref   StInfo);     
  104.   Date.Text   =   StInfo.wYear.ToString()+"年"+StInfo.wMonth.ToString()+"月"+StInfo.wDay.ToString()+"日";     
  105.   Time.Text   =   (StInfo.wHour+8).ToString()+"點"+StInfo.wMinute.ToString()+"分"+StInfo.wSecond.ToString()+"秒";     
  106.   }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章