許多軟件都有自動關機功能,特別是在長時間下載的時候,這個功能可是使你不用以守候在計算機前面,而電腦卻能按照您事先的設定自動關閉。現在我們用visual c#來編寫一個多功能的關機程序。該程序具有:定時關機、倒計時關機、關機提醒、系統信息獲取等四項功能, 可設定關機時間精確到秒。并且讓你很快掌握visual c#中對api的操作程序。
windows窗體界面:
將窗體屬性中的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 ) { file://用系統時間初始化組件 time.text = system.datetime.today.toshortdatestring( ) + " "+ system.datetime.today.tolongtimestring( ) ; } 在組件timer1的ontimer事件過程中編寫如下代碼: / / 在組件timer1的ontimer事件過程中編寫如下代碼: private void timer1_timer(object sender, system.eventargs e ) { file://接收當前日期和時間,用于即時顯示 string currdate=system.datetime.today.toshortdatestring( ) ; string currtime=system.datetime.today.toshorttimestring( ) ; file://隨時檢測設定的關機日期和時間是否有效 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窗體并向窗體中添加如下控件:
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 ; } file://定義內存的信息結構 [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 ; } file://定義系統時間的信息結構 [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 ; } 5. 編寫窗體類的方法 private void button1_click(object sender, system.eventargs e ) { file://調用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( ) ; file://調用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( ) ; file://調用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( ) +"字節" ; file://調用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的操作。上面給出的實例僅僅是一個簡單的程序,不過有興趣的讀者可以進一步完善其功能,做出更完美的系統應用程序。 |
新聞熱點
疑難解答