yunxizfj

等待...

导航

[小技术应用]使用windows服务备份数据

1.使用VS2005创建windows服务,从工具箱的组件表当中拖动一个Timer对象到这个设计表面上 (注意: 要确保是从组件列表而不是从Windows窗体列表当中使用Timer)  ,修改“.Designer.cs”文件,将timer组件修改为继承自System.Timers.Timer

2.在设计器右键选择添加安装程序,设置serviceInstaller1组件的属性:  
      1) ServiceName = My Sample Service
      2) StartType = Automatic (开机自动运行)
3. 设置serviceProcessInstaller1组件的属性    Account = LocalSystem

4.添加资源文件Config.xml,如下:

 

<?xml version="1.0" encoding="utf-8" ?>
<Table>
  
<Row>
    
<Server>.</Server>
    
<User>sa</User>
    
<Pwd>123456</Pwd>
    
<DataBase>Northwind</DataBase>
    
<Time></Time>
    
<Frequency>1</Frequency>
  
</Row>
</Table>

5.在双击这个Timer,然后在里面写一些数据库操作的代码,下面是Service1.cs全部代码:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Configuration.Install;
using Microsoft.Win32;
using System.Data.SqlClient;
using System.IO;

namespace DataBaseBakupServer
{
    
public partial class Service1 : ServiceBase
    {
        
#region 变量
        
private string Path;
        
//上次备份日期
        private string _time;
        
//间隔天数
        private int _Frequency;

        
private string _constr;
        
private string _server;
        
private string _user;
        
private string _pwd;
        
private string _database;
        
#endregion

        
public Service1()
        {
            InitializeComponent();
            GetServicePath();
            InitData();
        }

        
#region 初始化服务信息
        
private void InitData()
        {
            DataSet ds 
= new DataSet();
            ds.ReadXml(Path 
+ "Config.xml");
            DataRow dr 
= ds.Tables[0].Rows[0];

            _time 
= dr["Time"].ToString();
            _Frequency 
= Convert.ToInt32(dr["Frequency"].ToString());
            _server 
= dr["Server"].ToString();
            _user 
= dr["User"].ToString();
            _pwd 
= dr["Pwd"].ToString();
            _database 
= dr["DataBase"].ToString();

            _constr 
= string.Format("server={0};database={1};User Id={2};pwd={3}", _server, "master", _user, _pwd);
        }
        
private void GetServicePath()
        {
            
try
            {
                RegistryKey rk 
= Registry.LocalMachine;
                RegistryKey rkSub 
= rk.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\DataBaseBakupServer");
                
string servicePath = rkSub.GetValue("ImagePath").ToString();
                
string exePath = servicePath.Substring(servicePath.LastIndexOf("\\"+ 1);
                
string tmp = servicePath.Substring(1, servicePath.Length - exePath.Length-1);
                Path 
= tmp;
            }
            
catch { }
        }
        
#endregion

        
//必须注意:我明明是从“组件”下添加的“Timer”应该来自“System.Timers命名空间”(“System.Timers.Timer”才能在Windows服务程序中正常定时调用),但是现在Timer却继承至“System.Windows.Forms.Timer”。所以得修改“.Designer.cs”文件
        #region 启动和关闭
        
protected override void OnStart(string[] args)
        {
            
// TODO: 在此处添加代码以启动服务。
            timer1.Enabled = true;
            timer1.Start();
            WriteLog(
string.Format("{0}  数据库备份服务启动", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
        }

        
protected override void OnStop()
        {
            
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
            timer1.Stop();
            timer1.Enabled 
= false;
            WriteLog(
string.Format("{0}  数据库备份服务关闭", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
        }
       
        
#endregion


        
#region 备份操作
        
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            
//定时操作

            
if (_time == "" || _time == null)
            {
                
//没有保存上次本分时间,可能是第一次执行备份
                
//WriteLog(string.Format("{0}  开始备份操作", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
                Bakup();
                InitData();
                
//WriteLog(string.Format("{0}  备份操作完成", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
                return;
            }
            
string now = DateTime.Now.ToString("yyyy-MM-dd");
            
if (this.DateDiff(Convert.ToDateTime(now), Convert.ToDateTime(_time)) >= _Frequency)
            {
                
//WriteLog(string.Format("{0}  开始备份操作", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
                Bakup();
                InitData();
                
//WriteLog(string.Format("{0}  备份操作完成", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
                return;
            }
        }
        
#endregion

        
#region 方法
        
private bool Bakup()
        {
            
string file = DateTime.Now.ToString("yyyyMMddHHmm");
            
string sql = string.Format("BACKUP DATABASE {1} TO DISK = '{0}.bak'", Path + "Bak\\" + file, _database);
            SqlConnection con 
= new SqlConnection(_constr);
            SqlCommand cmd 
= new SqlCommand(sql, con);
            
try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                WriteBakDate();
                
return true;
            }
            
catch(Exception e)
            {
                WriteLog(
string.Format("{1}  备份数据库失败!原因可能是{0}", e.Message, DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
                
return false;
            }
            
finally
            {
                con.Close();
            }
        }
        
/// <summary>
        
/// 计算2个时间的差值(单位:天)
        
/// </summary>
        
/// <param name="DateTime1"></param>
        
/// <param name="DateTime2"></param>
        
/// <returns></returns>
        private int DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            
int dateDiff = 0;
            
try
            {
                TimeSpan ts1 
= new TimeSpan(DateTime1.Ticks);
                TimeSpan ts2 
= new TimeSpan(DateTime2.Ticks);
                TimeSpan ts 
= ts1.Subtract(ts2).Duration();
                dateDiff 
= ts.Days;
            }
            
catch
            {

            }
            
return dateDiff;
        }
        
private void WriteBakDate()
        {
            
try
            {
                DataSet ds 
= new DataSet();
                ds.ReadXml(Path 
+ "\\Config.xml");
                DataRow dr 
= ds.Tables[0].Rows[0];
                dr.BeginEdit();
                dr[
"Time"= DateTime.Now.ToString("yyyy-MM-dd");
                dr.EndEdit();
                ds.WriteXml(Path 
+ "Config.xml");
                WriteLog(
string.Format("{0}  备份数据库成功!", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
            }
            
catch (Exception e)
            {
                WriteLog(
string.Format("{1}  备份数据库成功!但写入配置文件最后备份时间项失败,原因可能是{0}", e.Message, DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
            }
        }
        
#endregion

        
#region 日志
        
private void WriteLog(string s)
        {
            FileStream fs 
= new FileStream(Path + "log.txt", FileMode.OpenOrCreate);
            StreamReader sr 
= new StreamReader(fs);
            StreamWriter sw 
= new StreamWriter(fs);
            
try
            {
                
string tmp = sr.ReadToEnd();
                tmp 
+= "\r\n" + s;
                sw.Write(tmp);
            }
            
catch
            { }
            
finally
            {
                sw.Close();
                sr.Close();
                fs.Close();
            }
        }
        
#endregion

        

    }
}

 

6.然后再生成项目,不能使用F5,只能使用命令,这是BAT的命令:

 

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe D:\C#\DataBaseBakupServer\DataBaseBakupServer\bin\Debug\DataBaseBakupServer.exe
net start DataBaseBakupServer
pause

注意:需要修改自己的目录路径

7.不多说了,希望小弟能在这里起到抛砖引玉的作用,网上关于这些的文章实在是很少啊,希望能和高手多多交流下

8.源代码下载地址(右键另存为)

posted on 2009-01-20 00:20  yunxizfj  阅读(649)  评论(3编辑  收藏  举报