1、在VS下新建一个Windows服务项目。里面自动添加了一个名称为Service1的windows 服务。(直接创建Windows运用程序项目的可以在项目上右键添加Windows服务)
<add key="strCon" value="Data Source=./SQLEXPRESS;Initial Catalog=ADV3;User ID=sa;Password=jcc"/>
3、添加System.Configuration引用
4、在Service1中添加代码:
备注:备份系统需要对数据库用户添加权限:grant backup database to 用户名
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Timers;
using System.Configuration;
namespace AdBackUpService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
Timer timer = null;
private int cTime = 604800000;//正常间隔时间7天(每周日23点59分开始备份)
private string logPath = ConfigurationManager.AppSettings["logPath"];
private string dbPath = ConfigurationManager.AppSettings["dbPath"];
/// <summary>
/// 服务启动
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
// TODO: 在此处添加代码以启动服务。
Start();//启动创建日志
//BackUp();//启动时即时备份一次
if(timer == null)
timer = new Timer();
timer.Interval = GetBackMillisecond();
timer.Enabled = true;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
protected override void OnStop()
{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
timer.Enabled = false;
timer.Dispose();
timer = null;
Stop();
}
/// <summary>
/// 获取执行备份剩余时间(毫秒)
/// </summary>
/// <returns></returns>
protected double GetBackMillisecond()
{
double millisecond = 3;//默认监控间隔3秒,给系统一个缓冲时间
DateTime dt = DateTime.Now;
DateTime temp1 = dt;
DateTime temp2;
if(dt.DayOfWeek.ToString() == "Tuesday")
{
temp1 = temp1.AddDays(6);
}
else if(dt.DayOfWeek.ToString() == "Wednesday")
{
temp1 = temp1.AddDays(5);
}
else if(dt.DayOfWeek.ToString() == "Thursday")
{
temp1 = temp1.AddDays(4);
}
else if(dt.DayOfWeek.ToString() == "Friday")
{
temp1 = temp1.AddDays(3);
}
else if(dt.DayOfWeek.ToString() == "Saturday")
{
temp1 = temp1.AddDays(2);
}
else if(dt.DayOfWeek.ToString() == "Monday")
{
temp1 = temp1.AddDays(1);
}
temp2 = new DateTime(temp1.Year, temp1.Month, temp1.Day, 23, 59, 0, 0);
TimeSpan ts = temp2.Subtract(dt);
if(ts.TotalMilliseconds > 0)
millisecond = ts.TotalMilliseconds;
return millisecond;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
BackUp();
if(timer.Interval != cTime)
timer.Interval = cTime;
}
protected void BackUp()
{
string backName = "V3" + GetDateStr(DateTime.Now);
string sql = "backup database ADOnlineV3 to disk='" + dbPath + backName + ".bak'";
try
{
DBHelper.ExecuteCommand(sql, CommandType.Text);
WriteRecord("Success:" + backName + ".bak Time:" + DateTime.Now.ToString());
}
catch(Exception ex)
{
WriteRecord("Error:" + ex.Message + " Time:" + DateTime.Now.ToString());
}
}
#region 服务日志
/// <summary>
/// 服务启动创建日志并添加记录
/// </summary>
public void Start()
{
FileStream fs = new FileStream(logPath, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine(DateTime.Now.ToString() + "--------------------------------------------------------------------------------------------/n");
m_streamWriter.WriteLine("AdBackUpService: Service Started! Time:" + DateTime.Now.ToString() + "/n");
m_streamWriter.Flush();
m_streamWriter.Close();
fs.Close();
}
/// <summary>
/// 备份操作日志记录
/// </summary>
/// <param name="record"></param>
public void WriteRecord(string record)
{
FileStream fs = new FileStream(logPath, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine(record + "/n");
m_streamWriter.Flush();
m_streamWriter.Close();
fs.Close();
}
/// <summary>
/// 服务停止日志
/// </summary>
public void Stop()
{
FileStream fs = new FileStream(logPath, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(fs);
m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamWriter.WriteLine("AdBackUpService: Service Stopped! Time: " + DateTime.Now.ToString() + "/n");
m_streamWriter.Flush();
m_streamWriter.Close();
fs.Close();
}
#endregion
/// <summary>
/// 转换时间字符串,精确到毫秒
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public string GetDateStr(DateTime dt)
{
StringBuilder strDate = new StringBuilder();
strDate.Append(dt.Year);
strDate.Append(dt.Month < 10 ? "0" + dt.Month.ToString() : dt.Month.ToString());
strDate.Append(dt.Day < 10 ? "0" + dt.Day.ToString() : dt.Day.ToString());
strDate.Append(dt.Hour < 10 ? "0" + dt.Hour.ToString() : dt.Hour.ToString());
strDate.Append(dt.Minute < 10 ? "0" + dt.Minute.ToString() : dt.Minute.ToString());
strDate.Append(dt.Second < 10 ? "0" + dt.Second.ToString() : dt.Second.ToString());
if(dt.Millisecond < 10)
strDate.Append("00").Append(dt.Millisecond);
else if(dt.Millisecond < 100)
strDate.Append("0").Append(dt.Millisecond);
else
strDate.Append(dt.Millisecond);
return strDate.ToString();
}
}
}
数据库操作类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
namespace AdBackUpService
{
public class DBHelper
{
//获取数据库链接字符串
public static String ConnectionString = ConfigurationManager.AppSettings["strCon"];
/// <summary>
/// 获取影响多少行
/// </summary>
/// <param name="queryString">T-SQL语句</param>
/// <param name="commandType">命令类型</param>
/// <param name="param">T-SQL参数</param>
/// <returns>影响多少行</returns>
public static int ExecuteCommand(string queryString, CommandType commandType, params SqlParameter[] param)
{
int flag = 0;
using(SqlConnection con = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(queryString, con);
command.CommandType = commandType;
if(param != null)
{
for(int i = 0; i < param.Length; i++)
{
command.Parameters.Add(param[i]);
}
}
try
{
command.Connection.Open();
flag = command.ExecuteNonQuery();
}
catch(Exception ex)
{
throw ex;
}
finally
{
command.Connection.Close();
command.Dispose();
command = null;
}
}
return flag;
}
/// <summary>
/// 获取DataSet对象
/// </summary>
/// <param name="queryString">T-SQL语句</param>
/// <param name="commandType">命令类型</param>
/// <param name="param">T-SQL参数</param>
/// <returns>DataSet对象</returns>
public static DataSet GetDataSet(string queryString, CommandType commandType, params SqlParameter[] param)
{
DataSet ds = new DataSet();
using(SqlConnection con = new SqlConnection(ConnectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter(queryString, con);
adapter.SelectCommand.CommandType = commandType;
if(param != null)
{
adapter.SelectCommand.Parameters.Clear();
for(int i = 0; i < param.Length; i++)
{
adapter.SelectCommand.Parameters.Add(param[i]);
}
}
try
{
adapter.Fill(ds);
}
catch(Exception ex)
{
throw ex;
}
finally
{
adapter.Dispose();
adapter = null;
}
}
return ds;
}
/// <summary>
/// 获取DataReader对象
/// </summary>
/// <param name="queryString">T-SQL语句</param>
/// <param name="commandType">命令类型</param>
/// <param name="param">T-SQL参数</param>
/// <returns>DataReader对象</returns>
public static SqlDataReader GetDataReader(string queryString, CommandType commandType, params SqlParameter[] param)
{
SqlDataReader dataReader = null;
SqlConnection con = new SqlConnection(ConnectionString);
SqlCommand command = new SqlCommand(queryString, con);
command.CommandType = commandType;
if(param != null)
{
for(int i = 0; i < param.Length; i++)
{
command.Parameters.Add(param[i]);
}
}
try
{
command.Connection.Open();
dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);
}
catch(Exception ex)
{
throw ex;
}
return dataReader;
}
/// <summary>
/// 查询单个数据
/// </summary>
/// <param name="queryString">T-SQL语句</param>
/// <param name="commandType">命令类型</param>
/// <param name="param">T-SQL参数</param>
/// <returns>Object对象</returns>
public static Object GetScalar(string queryString, CommandType commandType, params SqlParameter[] param)
{
Object obj = null;
using(SqlConnection con = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(queryString, con);
command.CommandType = commandType;
if(param != null)
{
for(int i = 0; i < param.Length; i++)
{
command.Parameters.Add(param[i]);
}
}
try
{
command.Connection.Open();
obj = command.ExecuteScalar();
}
catch(Exception ex)
{
throw ex;
}
finally
{
command.Connection.Close();
command.Dispose();
command = null;
}
}
return obj;
}
}
}
5、代码编写完成后Service1视图上右键,添加安装程序。系统会添加一个名为ProjectInstaller的安装程序。里面包含两个组件
serviceProjectInstaller1和serviceInstaller1
修改serviceProjectInstaller1的属性:Account为LocalSystem,该属性其他枚举值说明
枚 举 值
|
说 明
|
LocalService
|
充当本地计算机上非特权用户的账户,该账户将匿名凭据提供给所有远程服务器
|
LocalSystem
|
具有高特权级别的账户
|
NetworkService
|
提供广泛的本地特权的账户,该账户将计算机的凭据提供给所有远程服务器
|
User
|
由网络上特定的用户定义的账户。如果为ServiceProcessInstaller.Account成员指定 User,则会使系统在安装服务时提示输入有效的用户名和密码,除非为Service ProcessInstaller实例的Username和Password这两个属性设置值
|
ServiceProcessInstaller控件属性及说明
属 性
|
说 明
|
Account
|
获取或设置运行该服务应用程序时所使用的账户类型
|
HelpText
|
已重写。获取为服务安装选项显示的帮助文本
|
Parent
|
获取或设置包含该安装程序所属的集合的安装程序
|
Password
|
获取或设置与运行服务应用程序时所使用用户账户关联的密码
|
Username
|
获取或设置运行服务应用程序时将使用的用户账户
|
选中ServiceInstaller控件,在“属性”窗口中,将其StartType属性设置为Manual
该属性其他枚举值说明:
值
|
说 明
|
Automatic
|
指示服务在系统启动时将由(或已由)操作系统启动。如果某个自动启动的服务依赖于某个手动启动的服务,则手动启动的服务也会在系统启动时自动启动
|
Disabled
|
指示禁用该服务,以便它无法由用户或应用程序启动
|
Manual
|
指示服务只由用户(使用“服务控制管理器”)或应用程序手动启动
|
ServiceInstaller控件属性
属 性
|
说 明
|
DisplayName
|
指示向用户标识服务的友好名称
|
HelpText
|
获取安装程序集合中所有安装程序的帮助文字
|
ServiceName
|
指示系统用于标识此服务的名称。此属性必须与要安装的服务的ServiceBase. ServiceName相同
|
ServicesDependedOn
|
指示为使该服务能够运行而必须正在运行的服务
|
StartType
|
指示启动此服务的方式和时间
|
最后生成解决方案,到这里服务已经创建完毕。
接下来需要使用命令窗口进行安装:
可以使用Visual Studio下的Visual Studio 2005命令提示工具,也可以使用Microsoft .NET Framework SDK v2.0下的SDK命令提示 工具
安装卸载命令:
installutil 服务物理路径.exe
installutil /u 服务物理路径.exe
好了。就是这么简单。需要的话,不妨试试!
注:有可能有的服务器没有上述两个命令工具,那一般的命令行工具能不能行呢