首页 > 开发 > 综合 > 正文

Visual C#设计多功能关机程序

2024-07-21 02:26:49
字体:
来源:转载
供稿:网友

许多软件都有自动关机功能,特别是在长时间下载的时候,这个功能可是使你不用以守候在计算机前面,而电脑却能按照您事先的设定自动关闭。现在我们用visual c#来编写一个多功能的关机程序。该程序具有:定时关机、倒计时关机、关机提醒、系统信息获取等四项功能, 可设定关机时间精确到秒。并且让你很快掌握visual c#中对api的操作程序。



  一. 设计关闭windows窗体

  1. 界面的设计

  新建一个标准工程,向工程中增加一个windows窗体并向窗体中添加如下控件,并分别设置其属性:

控件名类别text控件名类别text
checkbox1checkbox自动关机groupbox1groupbox当前系统时间
checkbox1checkbox倒计时执行操作groupbox2groupbox设定时间
checkbox1checkbox定时报警txttimetextbox 
butcanclebutton取消setuptimedatetimepicker 
butreopenbutton重新启动setupdatedatetimepicker 
butclosebutton关机timer1timer100
butsysintobutton系统信息butreloginbutton注消


  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的操作。上面给出的实例仅仅是一个简单的程序,不过有兴趣的读者可以进一步完善其功能,做出更完美的系统应用程序。
 
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表