许多软件都有自动关机功能,特别是在长时间下载的时候,这个功能可是使你不用以守候在计算机前面,而电脑却能按照您事先的设定自动关闭。现在我们用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的操作。上面给出的实例仅仅是一个简单的程序,不过有兴趣的读者可以进一步完善其功能,做出更完美的系统应用程序。 |
新闻热点
疑难解答