天天看點

在C#中運用API函數編寫多功能關機程式

悉windows的使用者對作業系統的關機程式一定了解,您是不是覺得它的功能不是很多。許多軟體都有自動關機功能,比如一些下載下傳軟體,這一功能能讓您半夜踏踏實實地睡個好覺,而電腦卻能按照您事先的設定自動關閉 , 您在使用電腦聽音樂、看電影、或是下載下傳等一些自動功能的時候,是不是經常為忘記關機而心痛不已。現在我們用visual C#來編寫一個多功能的關機程式。該程式具有:定時關機、倒計時關機、關機提醒、系統資訊擷取等四項功能, 可設定關機時間精确到秒。并且讓你很快掌握Visual C#中對API的操作程式。編寫過程如下:

一、設計關閉Windows窗體

1.界面的設計

建立一個标準工程,向工程中增加一個Windows窗體并向窗體中添加如下控件,并分别設定其屬性:

控件名 類别 Text 控件名 類别 Text
CheckBox1 CheckBox 自動關機 GroupBox1 GroupBox 目前系統時間
CheckBox1 CheckBox 倒計時執行操作 GroupBox2 GroupBox 設定時間
CheckBox1 CheckBox 定時報警 TxtTime TextBox
ButCancle Button 取消 SetupTime DateTimePicker
ButReOpen Button 重新啟動 SetupDate DateTimePicker
ButClose Button 關機 Timer1 Timer 100
ButSysInto Button 系統資訊 ButReLogin Button 注消

Windows窗體界面:

在C#中運用API函數編寫多功能關機程式

将窗體屬性中的caption設定為“關閉windows”,名稱設定為“frmmain”。

2.在窗體類中引用API函數

API函數是構築Windows應用程式的基石,是Windows程式設計的必備利器。每一種Windows應用程式開發工具都提供了間接或直接調用了Windows API函數的方法,或者是調用Windows API函數的接口,也就是說具備調用動态連接配接庫的能力。Visual C#和其它開發工具一樣也能夠調用動态連結庫的API函數。

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

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

using System.Runtime.InteropServices ;

using System.Text ;

在導入了名稱空間後,我們要聲明在程式中所要用到的API函數。我們的程式主要是擷取系統的相關資訊,是以用到的API函數都是傳回系統資訊的。先給出在Visual C#中聲明API的方法:

[ DllImport("user32") ]

public static extern long SetWindowPos(long hwnd , long hWndInsertAfter, long X , long y , long cx, long cy, long wFlagslong) ;

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

聲明其它的在程式中所要用到的API函數:

[ DllImport("user32") ]

public static extern long ExitWindowsEx(long uFlags, long dwReserved ) ;

[ DllImport("shell32") ]

public static extern long ShellAbout(long uFlags, long dwReserved ) ;

3.增加窗體類的變量

long dwReserved ;

const int SHUTDOWN = 1 ;

const int REBOOT = 2 ;

const int LOGOFF = 0 ;

long sh ;

int counter , n ;

4.編寫窗體類的方法

在窗體的Load(事件過程中編寫如下代碼:

private void frmmain1_Load(object sender, System.EventArgs e )

{

//用系統時間初始化元件

Time.Text = System.DateTime.Today.ToShortDateString( ) + " "+ System.DateTime.Today.ToLongTimeString( ) ;

}

在元件Timer1的OnTimer事件過程中編寫如下代碼:

/ / 在元件Timer1的OnTimer事件過程中編寫如下代碼:

private void Timer1_Timer(object sender, System.EventArgs e )

{

//接收目前日期和時間,用于即時顯示

string CurrDate=System.DateTime.Today.ToShortDateString( ) ;

string CurrTime=System.DateTime.Today.ToShortTimeString( ) ;

//随時檢測設定的關機日期和時間是否有效

if( this.CheckBox1.Checked == true )

{

if(CurrDate== SetupDate.ToString( ) && CurrTime==SetupTime.ToString( ) )

ColseComputer( ) ;

}

}

private void ColseComputer( )

{ sh = ExitWindowsEx(SHUTDOWN, dwReserved) ; }

private void button1_Click(object sender, System.EventArgs e )

{

Form2 frm=new Form2( ) ;

frm.Show( ) ;

}

private void ButReOpen_Click(object sender, System.EventArgs e )

{ sh = ExitWindowsEx(REBOOT, dwReserved) ; }

private void ButReLogin_Click(object sender, System.EventArgs e )

{ sh = ExitWindowsEx(LOGOFF, dwReserved) ; }

private void ButCancle_Click(object sender, System.EventArgs e )

{ this.Close( ) ; }

private void ButClose_Click_1(object sender, System.EventArgs e )

{ sh = ExitWindowsEx(REBOOT, dwReserved) ; }

二、設計擷取系統資訊的Windows窗體

1.界面的設計

向工程中增加一個Windows窗體并向窗體中添加如下控件:

在C#中運用API函數編寫多功能關機程式

2.在窗體類中引用API函數

using System.Runtime.InteropServices ;

using System.Text ;

[ DllImport("kernel32") ]

public static extern void GetWindowsDirectory(StringBuilder WinDir,int count) ;

[ 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相關資訊,獲得記憶體的相關資訊,獲得系統時間等。

3.定義以下各結構

在聲明完所有的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 ;

}

4.編寫窗體類的方法

private void button1_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( ) +"秒" ;

}

三、結束語

上面介紹了Visual C#開發多功能關機程式的整個過程,該程式有一定的實用價值。通過本文的學習,我相信稍有API使用基礎的開發者可以馬上觸類旁通,很快掌握Visual C#中對API的操作。上面給出的執行個體僅僅是一個簡單的程式,不過有興趣的讀者可以進一步完善其功能,做出更完美的系統應用程式。

繼續閱讀