你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Linux开发
编写Windows服务程序实现特定环境下对文件的自动删除
 

陈剑辉

    摘要 本文首先描述了Windows服务程序的优点,然后通过具体编写Windows服务程序,实现了在特定环境下对文件的自动删除。
    关键词 Windows服务,程序,自动删除
一、引言
    2006年初,江阴电视台引进了南京格非公司“Aces数字硬盘录像系统”,该系统可以全天候、实时地把江阴电视台四个频道每天播出的电视节目以录像方式完全克隆到计算机硬盘上,并且以文件格式保存下来。
    由于该系统源源不断地把江阴电视台四个频道的播出节目内容写在计算机硬盘上,而计算机硬盘的容量毕竟有限,并且保存在硬盘上的播出数据具有一定的时效性,也就是说这些数据只保留一定时间(比如说两个月),不需要永久地保留。这样一来,就需要人工定期、不定期地根据剩余硬盘空间的大小,以播出时间为顺序,把一些保存在硬盘上以前的电视节目数据从硬盘上删除。以便腾出硬盘空间,存放即将播出的电视节目内容,否则,如果硬盘写满了,就没有空间存放正在播出(即将播出)的电视节目内容。经过一段时间的摸索,笔者在Visual Studio.NET环境下,利用Visual Basic.NET编程,实现了完全由计算机自己定期完成上述任务,而且这个程序只要计算机开机,就始终处于运行状态。
二、编写Windows服务程序的应用实践
    下面向大家具体介绍利用VB.NET编写Windows服务应用程序。
    首先,向大家简要介绍 “Aces数字硬盘录像系统”。“Aces数字硬盘录像系统”采用的是SATA结构,外挂四个小硬盘,它们分别是F盘,G盘,H盘,J盘。又把这四个小硬盘分为两组,其中F盘和H盘为一组,用于存放“新闻综合”频道和“城市”频道的节目,G盘和J盘为一组,用于存放“电视剧”频道和“电影”频道节目。“Aces数字硬盘录像系统”先把“新闻综合”频道和“城市”频道的节目内容按时间顺序,以每天一个文件夹的形式先写到F盘上,等到F盘写满后,“Aces数字硬盘录像系统”把接下来的上述两个频道的节目再往H盘上写,这样,当H盘快要写满的时候,就需要我们人工删除一些以前存放在F盘上的节目内容,腾出硬盘空间(以备当H盘写满后,用来存放这两个频道即将播出的节目内容)。这样,等到H盘写满后,“Aces数字硬盘录像系统”又自动把上述两个频道的节目内容往H盘上写,等到H盘快要写满的时候,又需要我们人工删除掉存放在F盘上以前的节目内容,以便腾出硬盘空间,存放上述两个频道即将播出的节目内容。
    就这样,按照“写F盘----写H盘----人工删除F盘----再写F盘----再人工删除H盘----再写H盘”的规律,循环往复。这样,“新闻综合”频道和“城市”频道的节目内容被保存在F和H盘上。
对于G盘和J盘同样如此,只不过他们存放的是“电视剧”频道和“电影频道的节目内容”。
不难发现,F、H盘上节目内容的删除和G、J盘上节目内容的删除,这两个操作是相互独立的,为此,在编程时把它们作为独立的过程分别来处理。
    下边谈谈通过编程对“Aces数字硬盘录像系统”功能的改进:
    通过观察,电视台每个频道每天的节目(包括节目结束后INFOTV的内容)大概需要8G的空间来保存,而F,G,H,J每个盘空间为400G,按此推算,要写满它们,大概需要两个月时间,就需要人工删除一些节目内容,也就是说,电视节目内容最多可以保存两个月的时间。
    经过反复推算,当F、G、H、J的剩余空间为50G时,开始执行“删除”操作比较合理。因为这样可使电视节目内容保存地时间更长一些。
    再简述编程思路:把Widows服务程序称为:DiskSpaceManagementService。为了方便处理,首先在定义一个数据结构,用以定义各个盘符以及它们的剩余空间的最小值(这里,定义为50G)。同时定义了几个函数DiskSpaceManagement(),DiskSpace(),GetEarlestFolder()。其中DiskSpace()用以获得某一逻辑盘的剩余空间,GetEarlestFolder()用以获得逻辑盘上的创建日期最早的一个目录。DiskSpaceManagement用以检查逻辑盘上剩余空间是否已经小于规定的空间,如果小于,则进行删除操作。
    在OnStart()函数中定义相应的四个盘符和它们的最小允许剩余空间、启动了一个周期为1小时的定时器、并调用DiskSpaceManagement()进行检查。而在定时器的Elapsed()事件中通过比较上一时刻与下一时刻的日期是否相同,确定是否跨越了一天,如果跨越了一天,则调用DiskSpaceManagement()进行检查,从而实现了每天检测一次的需求,就是说,在每天零点左右程序都要检查一次F和H盘(G和J)的剩余空间,如果F和H盘(G和J盘)的剩余空间都小于50G时,程序便自动删除F和H盘(G和J盘)上最早的一天的节目内容;如果F和H盘(G和J盘)的剩余空间都大于50G时,则程序什么也不做,然后等新的一天来临时,程序则又重复上述操作。这样,就实现了节目内容的自动删除。
    程序实现的核心代码如下:
Public Class DiskSpaceManagementService
    Inherits System.ServiceProcess.ServiceBase
    Private WithEvents controltimer As Timer
    Dim tempDate As Date

    Structure DriverInformation
       Dim strDriverName As String
        Dim intMinVol As Integer

    End Structure

    Dim Driver(4) As DriverInformation
#Region " 组件设计器生成的代码 "
    Public Sub New()
        MyBase.New()
        InitializeComponent()
        ' 在 InitializeComponent() 调用之后添加任何初始化
    End Sub

    'UserService 重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    ' 进程的主入口点
  <MTAThread()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBaseServicesToRun = New System.ServiceProcess.ServiceBase() {New DiskSpaceManagementService}
        System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub

    Private components As System.ComponentModel.IContainer
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        'DiskSpaceManagementService
        Me.CanShutdown = True
        Me.ServiceName = "DiskSpaceManagementService"
    End Sub
#End Region

 Protected Overrides Sub OnStart(ByVal args() As String)
        tempDate = Now
        controltimer = New Timer
        controltimer.Interval = 3600000
        controltimer.AutoReset = True
        controltimer.Start()
'此处设置需要整理的盘符和最小剩余空间(以M为单位)
        Driver(0).strDriverName = "F"
        Driver(0).intMinVol = 50000
        Driver(1).strDriverName = "H"
        Driver(1).intMinVol = 50000
        Driver(2).strDriverName = "G"
        Driver(2).intMinVol = 50000
        Driver(3).strDriverName = "J"
        Driver(3).intMinVol = 50000

        '一启动就先整理一下
        DiskSpaceManagement(Driver(0), Driver(1))
        DiskSpaceManagement(Driver(2), Driver(3))
    End Sub

    Protected Overrides Sub OnStop()
        ' 在此处添加代码以执行停止服务所需的关闭操作。
        controltimer.Close()
    End Sub

    Public Sub DiskSpaceManagement(ByVal driverA As DriverInformation, ByVal driverB As DriverInformation)
        Dim Fld1 As Scripting.Folder
        Dim Fld2 As Scripting.Folder
        Dim Fld3 As Scripting.Folder
        Dim Fld4 As Scripting.Folder
        On Error GoTo ErrorInfor
If (DiskSpace(driverA.strDriverName) < driverA.intMinVol) And (DiskSpace(driverB.strDriverName) < driverB.intMinVol) Then
            Fld1 = GetEarlestFolder(driverA)
            Fld2 = GetEarlestFolder(driverB)
            '如果没有取出最早目录,则什么都不做
            If Fld1 Is Nothing Then Return
            If Fld2 Is Nothing Then Return
            If Fld1.DateCreated < Fld2.DateCreated Then
                '记录进日志
       EventLog.WriteEntry(ServiceName & " - Delete", "Delete Folder " & Fld1.Name)
                Fld1.Delete(True)
    Else
                '记录进日志
      EventLog.WriteEntry(ServiceName & " - Delete", "Delete Folder " & Fld2.Name)
                Fld2.Delete(True)
    End If
End If
Return
ErrorInfor:
        EventLog.WriteEntry(ServiceName & "-" & Err.Description)
End Sub

'获得磁盘分区的剩余空间的函数,以M为单位
 Public Function DiskSpace(ByVal DrivePath As String) As Double
        Dim Fso As New FileSystemObject
        Dim drvDisk As Drive, strResult As String
        drvDisk = Fso.GetDrive(Left(Trim(DrivePath), 1) & ":\")
        DiskSpace = drvDisk.FreeSpace / 1024 ^ 2
    End Function

    '获得一个磁盘分区的包含的文件夹中创建日期最早的一个文件夹
    Public Function GetEarlestFolder(ByVal Driver As DriverInformation) As Folder
        Dim Flds As Folders
        Dim Fld As Folder
        Dim Fld1 As Folder
        Dim tempFld As Folder
        Dim Date1 As Date
        Dim Fso As New FileSystemObject
        '取最早日期目录夹
    Flds = Fso.GetFolder(Left(Trim(Driver.strDriverName), 1) & ":\").SubFolders()
        Date1 = Now
        If Flds.Count > 0 Then
            For Each Fld In Flds
                If Fld.DateCreated() < Date1 Then
                    Date1 = Fld.DateCreated
                    tempFld = Fld
                End If
            Next
            Fld1 = tempFld
        Else
            Fld1 = Nothing
        End If
     Return Fld1
    End Function

Private Sub controltimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles controltimer.Elapsed
        '如果日期变了,意味着跨越12PM时,进行整理
        If Now.Day > tempDate.Day Then
            EventLog.WriteEntry(ServiceName, "Disk check began...")
            DiskSpaceManagement(Driver(0), Driver(1))
            DiskSpaceManagement(Driver(2), Driver(3))
            EventLog.WriteEntry(ServiceName, "Disk check finished...")
        End If
        tempDate = Now
    End Sub

    Protected Overrides Sub OnPause()
        controltimer.Close()
    End Sub

  Protected Overrides Sub OnContinue()
        controltimer.Interval = 3600000
        controltimer.AutoReset = True
        controltimer.Start()
    End Sub
End Class

    最后,通过Windows服务安装工具Srvinstw使DiskSpaceManagementService成为Windows服务程序。

    该服务程序启动后,就在后台始终处于运行状态,结果如图1所示。


                           
                              图 1  服务程序启动
    然后,再通过计算机“事件服务查看器”,就能看到该服务程序的运行结果。下面通过“事件服务查看器”来详细介绍其某一天的运行结果,如图2所示。



                                           图2  日志查看
    正如在图2中所看到的,当2006年9月26日这天来临时,该服务程序共进行三项操作,然后,按照时间发生的顺序,分别将它们称为:A、B、C。然后,通过鼠标分别“双击”它们,就能进一步看到它们的具体操作:
    通过鼠标“双击”A项,这时,看到的结果如图3所示:在2006年9月26日零时零分(即9月26日这一天来临时),该服务程序开始检查F盘和H盘的剩余空间。



               图3 显示属性


    通过鼠标双击“B”项,这时,看到的结果如图4所示。在2006年9月26日零点零分30秒时,由于该服务程序检测到F和H盘的剩余空间都小于50G,此时,便把保存在F和H盘上最早这一天(2006年7月19日)的节目内容被删除了。



             图4 删除F盘的数据

     对于G和J盘来讲,该服务程序同样进行相同的操作,只不过删除的是G和盘(电视剧和电影频道)的内容而已。
     就这样,每当新的一天到来时,该服务程序就开始检查F和H盘、G和J盘的剩余空间,并且进行相应的操作,随后把所进行的操作信息写在计算机的“事件查看器”当中。如果不人为删除,这些信息就一直保存在计算机当中。

三、结语
   本例只是利用VB.NET编写Windows服务应用程序简单的具体实践,随着计算机技术的不断发展,利用VB.NET编写Windows服务程序会更加方便,功能会更强,更加完善。


 

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089