zoukankan      html  css  js  c++  java
  • [小技术应用]使用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.源代码下载地址(右键另存为)

  • 相关阅读:
    Python 编程笔记(小白初学篇)
    博客园设置好看的主题!站在巨人的肩膀上眺望远方!!
    Matlab 画地图之 m_map
    SSO+PHS 同步问题修正解决
    从已删除邮箱copy数据到活动邮箱
    微软AD相关操作的免费工具
    phpize是什么
    apache的bin目录下的apxs有什么作用? PHP模块加载运行方式
    docker
    sed 命令
  • 原文地址:https://www.cnblogs.com/yunxizfj/p/1378628.html
Copyright © 2011-2022 走看看