我也来学着写写WINDOWS服务-解析xml抓取数据并插入数据库
项目告一段落,快到一年时间开发了两个系统,一个客户已经在试用,一个进入客户测试阶段,中间突然被项目经理(更喜欢叫他W工)分派一个每隔两小时用windows服务去抓取客户提供的外网xml,解析该xml,然后将截取的节点字段值插入到已经建好相应结构的表中。并记录日志。
xml结构概要如下:
<?xml version="1.0" encoding="UTF-8"?>
<list>
<info>
<id>93ef7c7cccd2ecb13ed01dd6e30020b4136</id>
<title>剔骨刀一握六年练过硬本领 女庖丁解牛割肉有拿手好戏</title>
<posttime class="sql-timestamp">2015-05-25 06:38:20.0</posttime>
<institution>浙江省物价局</institution>
<url>http://dsb.66wz.com/html/2015-05/25/content_1822593.htm</url>
<webName>温州都市报数字版</webName>
<infotype>新闻</infotype>
<summary>内容</summary>
<fl>其他类</fl>
</info>
<info>
...
</info>
<info>
...
</info>
。。。
</list>
1.首先,让我们新建一个解决方案,该解决方案中包含9个项目:
(1)由于需要操作的是Oracle数据库系统,所以在MSDN上找了个Oracle数据操作类库DatabaseLib和DatabaseLink直接拿来用,一个是数据库连接类,一个是数据库操作类,里面包含各种对数据库的操作;
其中,DatabaseLink主要包括以下三个文件:
DbLink.cs
using System.Data;
namespace DataBaseLink
{
/// <summary>
/// DATA :2010-07-01
/// Author :虞健超(James.Yu)
/// Describe :数据库连接对象
/// </summary>
public class DbLink : IDbLink
{
public string ConnectionStr { get; set; }
public DbLink(string connectStr)
{
ConnectionStr = connectStr;
}
#if MSSQL
public IDbConnection CreateConnection()
{
return new System.Data.SqlClient.SqlConnection(ConnectionStr);
}
public IDataAdapter CreateAdapter(IDbCommand cmd)
{
return new System.Data.SqlClient.SqlDataAdapter((System.Data.SqlClient.SqlCommand)cmd);
}
#endif
}
}
IDbLink.cs
using System.Data;
namespace DataBaseLink
{
/// <summary>
/// DATA :2010-07-01
/// Author :虞健超(James.Yu)
/// Describe :连接创建对象借口
/// </summary>
public interface IDbLink
{
/// <summary>
/// 连接字符串
/// </summary>
string ConnectionStr { get; set; }
/// <summary>
/// 创建连接
/// </summary>
/// <returns>连接</returns>
IDbConnection CreateConnection();
/// <summary>
/// 创建Adapter
/// </summary>
/// <param name="cmd">cmd</param>
/// <returns></returns>
IDataAdapter CreateAdapter(IDbCommand cmd);
}
}
以及存储过程映射类DBStoreProcedureManager.cs
namespace DataBaseLink
{
/// <summary>
/// DATA :2010-07-01
/// Author :虞健超(James.Yu)
/// Describe :存储过程接口,里面存储存储过程名,以及参数列表方便调用时反射
/// </summary>
public interface IDbStoreProcedureManager
{
//存储过程映射,这里是名为SP_TestApply的存储过程
void SP_TestApply(string c1, int? c2);
}
}
在这个程序中主要用到前两个类;
而对于数据库操作主要用到以下代码:
OracleDBHelper.cs中的
public static int ExecuteNonQuery(string sql, OracleParameter[] para, CommandType cmdType)
{
int rows = -1;
using (OracleConnection conn = new OracleConnection(ConnectionString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
if (para != null)
{
cmd.Parameters.AddRange(para);
}
cmd.CommandType = cmdType;
conn.Open();
rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
conn.Close();
}
return rows;
}
public override unsafe int ExecuteNonQuery()
{
string[] ppOpoPrmRefCtx = null;
IntPtr[] pOpoPrmValCtx = null;
OracleParameter parameter;
int num7;
int num8;
IntPtr zero = IntPtr.Zero;
IntPtr opsSubscrCtx = IntPtr.Zero;
int isSubscrRegistered = 0;
OracleDependency dep = null;
int bQueryBasedNTFNRegistration = 0;
int bchgNTFNExcludeRowidInfo = 0;
long num4 = 0L;
int errCode = 0;
int prmCnt = 0;
bool flag = false;
int bFromPool = 0;
CmdTimeoutCtx state = null;
Timer timer = null;
if (OraTrace.m_TraceLevel != 0)
{
OraTrace.Trace(1, new string[] { " (ENTRY) OracleCommand::ExecuteNonQuery()\n" });
}
if (this.m_connection == null)
{
throw new InvalidOperationException();
}
if (this.m_cmdTxtModified && ((this.m_commandText == null) || (this.m_commandText.Length == 0)))
{
throw new InvalidOperationException(OpoErrResManager.GetErrorMesg(ErrRes.ODP_INVALID_VALUE, new string[] { "OracleCommand.CommandText" }));
}
if (this.m_xmlCommandType != OracleXmlCommandType.None)
{
if (OracleXmlCommandType.Query == this.m_xmlCommandType)
{
this.ExecuteXmlQuery(false);
return -1;
}
return this.ExecuteXmlSave();
}
this.CheckConStatus();
if (this.m_cmdTxtModified || (this.m_commandType == System.Data.CommandType.StoredProcedure))
{
if (this.m_commandType == System.Data.CommandType.Text)
{
this.m_selectStmt = isSelectStatement(this.m_commandText);
this.m_pooledCmdText = this.m_commandText;
}
else if (this.m_commandType == System.Data.CommandType.TableDirect)
{
this.m_selectStmt = true;
this.m_pooledCmdText = "Select * from " + this.m_commandText;
}
else if (this.m_commandType == System.Data.CommandType.StoredProcedure)
{
this.BuildCommandText();
this.m_selectStmt = false;
this.m_utf8CmdText = null;
this.m_addParam = true;
}
UTF8CommandText text = UTF8CommandText.m_pooler.Get(this.m_connection.m_internalConStr, this.m_pooledCmdText) as UTF8CommandText;
if ((text != null) && (text.m_utf8CmdText != IntPtr.Zero))
{
this.m_utf8CmdText = text;
this.m_addParam = this.m_utf8CmdText.m_addParam;
this.m_parsed = this.m_utf8CmdText.m_parsed;
bFromPool = 1;
}
if (!this.m_parsed && (this.m_commandType == System.Data.CommandType.Text))
{
this.ParseCommandText();
}
this.m_cmdTxtModified = false;
}
if (this.m_bindByName && (this.m_commandType != System.Data.CommandType.StoredProcedure))
{
flag = true;
}
if (((this.m_NTFNReq != null) && this.m_NTFNAutoEnlist) && (!this.m_connection.m_contextConnection && (OracleNotificationRequest.s_idTable[this.m_NTFNReq.Id] != null)))
{
opsSubscrCtx = OracleNotificationRequest.PopulateChgNTFNSubscrCtx(this, this.m_addRowid, out dep);
if ((dep != null) && dep.m_bIsRegistered)
{
isSubscrRegistered = 1;
}
if (dep != null)
{
if (dep.m_OracleRowidInfo == OracleRowidInfo.Exclude)
{
bchgNTFNExcludeRowidInfo = 1;
}
if (dep.QueryBasedNotification && this.m_connection.IsDBVer11gR1OrHigher)
{
bQueryBasedNTFNRegistration = 1;
}
}
}
this.SetSqlValCtx(false);
if ((this.m_connection.m_opoConCtx.m_bSelfTuning && !OracleTuningAgent.bHighMemoryAlertFlag) && (1 == this.m_pOpoSqlValCtx.AddToStmtCache))
{
this.m_connection.AcceptStatementData(this.m_pooledCmdText);
}
OpoMetValCtx* pOpoMetValCtx = null;
try
{
if (this.m_utf8CmdText != null)
{
zero = this.m_utf8CmdText.m_utf8CmdText;
if (zero != IntPtr.Zero)
{
bFromPool = 1;
}
}
if ((this.m_parameters != null) && this.m_addParam)
{
prmCnt = this.m_parameters.Count;
if ((prmCnt > 0) && ((this.m_addToStmtCache || (this.m_pOpoPrmCtx == null)) || (this.m_pOpoPrmCtx.NumValCtxElems < prmCnt)))
{
try
{
errCode = OpsSql.Prepare2(this.m_opsConCtx, ref this.m_opsErrCtx, ref this.m_opsSqlCtx, ref this.m_opsDacCtx, ref this.m_pOpoSqlValCtx, (zero == IntPtr.Zero) ? this.m_pooledCmdText : null, ref zero, ref pOpoMetValCtx, prmCnt);
}
catch (Exception exception)
{
if (OraTrace.m_TraceLevel != 0)
{
OraTrace.TraceExceptionInfo(exception);
}
errCode = ErrRes.INT_ERR;
throw;
}
finally
{
if (errCode != 0)
{
if (!this.m_addToStmtCache && (this.m_pOpoSqlValCtx.pOpoPrmCtx == null))
{
this.m_pOpoPrmCtx = null;
}
if (errCode != ErrRes.INT_ERR)
{
string commandText;
if (this.m_commandType == System.Data.CommandType.StoredProcedure)
{
commandText = this.m_commandText;
}
else
{
commandText = string.Empty;
}
OracleException.HandleError(errCode, this.m_connection, commandText, this.m_opsErrCtx, this.m_pOpoSqlValCtx, this);
}
}
}
if (!this.m_addToStmtCache && (this.m_pOpoPrmCtx == null))
{
this.m_pOpoPrmCtx = this.m_pOpoSqlValCtx.pOpoPrmCtx;
}
}
if (flag)
{
ppOpoPrmRefCtx = new string[prmCnt];
}
pOpoPrmValCtx = new IntPtr[prmCnt];
for (num7 = 0; num7 < prmCnt; num7++)
{
parameter = this.m_parameters[num7];
parameter.m_pOpoPrmValCtx = this.m_pOpoSqlValCtx.pOpoPrmCtx.pOpoPrmValCtx + num7;
try
{
parameter.PreBind(this.m_connection, this.m_opsErrCtx, this.m_arrayBindCount, this.m_isFromEF, this.m_selectStmt);
}
catch (Exception)
{
num8 = 0;
while (num8 < num7)
{
parameter = this.m_parameters[num8];
parameter.PreBindFree(this.m_connection, this.m_arrayBindCount);
num8++;
}
throw;
}
if (flag)
{
ppOpoPrmRefCtx[num7] = parameter.m_paramName;
}
pOpoPrmValCtx[num7] = (IntPtr) parameter.m_pOpoPrmValCtx;
}
}
try
{
if (this.m_commandTimeout > 0)
{
state = new CmdTimeoutCtx(this.m_opsConCtx, this.m_commandTimeout);
TimerCallback callback = new TimerCallback(state.TimeoutNew);
long dueTime = this.m_commandTimeout * 0x3e8L;
if (dueTime > 0xf7314000L)
{
dueTime = 0xf7314000L;
}
timer = new Timer(callback, state, dueTime, -1L);
if (state.m_bDoneOCIBreak)
{
string procedure = null;
if (this.m_commandType == System.Data.CommandType.StoredProcedure)
{
procedure = this.m_commandText;
}
else
{
procedure = string.Empty;
}
errCode = 0x3f5;
OracleException.HandleError(errCode, this.m_connection, procedure, this.m_opsErrCtx, this.m_pOpoSqlValCtx, this);
}
}
errCode = 0;
if (this.m_connection.m_opoConCtx.m_bSelfTuning && (this.m_connection.m_opoConCtx.pOpoConValCtx.StmtCacheSize > OraTrace.MaxStatementCacheSize))
{
this.m_connection.m_opoConCtx.pOpoConValCtx.StmtCacheSize = OraTrace.MaxStatementCacheSize;
errCode = OpsCon.SetStatementCacheSize(this.m_opsConCtx, ref this.m_opsErrCtx, this.m_connection.m_opoConCtx.pOpoConValCtx);
if (this.m_connection.m_opoConCtx.m_conPooler != null)
{
this.m_connection.m_opoConCtx.m_conPooler.ModifyConPoolerSize(this.m_connection.m_opoConCtx.pOpoConValCtx.StmtCacheSize);
}
}
if (errCode == 0)
{
this.m_opsDacCtx = IntPtr.Zero;
errCode = OpsSql.ExecuteNonQuery(this.m_opsConCtx, ref this.m_opsErrCtx, ref this.m_opsSqlCtx, ref this.m_opsDacCtx, opsSubscrCtx, ref isSubscrRegistered, bchgNTFNExcludeRowidInfo, bQueryBasedNTFNRegistration, ref num4, ref this.m_pOpoSqlValCtx, ((zero == IntPtr.Zero) || this.m_selectStmt) ? this.m_pooledCmdText : null, ref zero, pOpoPrmValCtx, ppOpoPrmRefCtx, ref pOpoMetValCtx, prmCnt, bFromPool);
}
}
catch (Exception exception2)
{
if (OraTrace.m_TraceLevel != 0)
{
OraTrace.TraceExceptionInfo(exception2);
}
errCode = ErrRes.INT_ERR;
throw;
}
}
finally
{
if ((this.m_commandTimeout > 0) && (state != null))
{
state.m_bDoneExecution = true;
if (!state.m_hWaitForOciBreakEvent.WaitOne(0x1388, false) && (OraTrace.m_TraceLevel != 0))
{
OraTrace.Trace(1, new string[] { " (WARN) OracleCommand::ExecuteNonQuery() WaitOne() timed out \n" });
}
timer.Dispose();
state.Dispose();
}
if (((dep != null) && (isSubscrRegistered == 1)) && !this.m_connection.m_contextConnection)
{
dep.SetRegisterInfo(this.m_connection.m_opoConCtx.opoConRefCtx.userID, this.m_connection.DataSource, this.m_NTFNReq.IsNotifiedOnce, this.m_NTFNReq.IsPersistent, this.m_NTFNReq.Timeout);
}
if ((this.m_connection.m_contextConnection && (pOpoMetValCtx != null)) && (pOpoMetValCtx->bHasUdtType == 1))
{
errCode = ErrRes.CLR_UDT_NOTSUPPORTED_CTX_CONN;
}
if (zero != IntPtr.Zero)
{
if (!(UTF8CommandText.m_pooler.Get(this.m_connection.m_internalConStr, this.m_pooledCmdText) is UTF8CommandText))
{
if (this.m_utf8CmdText == null)
{
this.m_utf8CmdText = new UTF8CommandText(zero);
}
this.m_utf8CmdText.m_parsed = this.m_parsed;
this.m_utf8CmdText.m_addParam = this.m_addParam;
UTF8CommandText.m_pooler.Put(this.m_connection.m_internalConStr, this.m_pooledCmdText, this.m_utf8CmdText);
}
else if (this.m_utf8CmdText == null)
{
this.m_utf8CmdText = new UTF8CommandText(zero);
}
}
if (errCode != 0)
{
for (num7 = 0; num7 < prmCnt; num7++)
{
parameter = this.m_parameters[num7];
parameter.PreBindFree(this.m_connection, this.m_arrayBindCount);
}
this.FreeNonCachedOpoPrmCtx();
if (errCode != ErrRes.INT_ERR)
{
string str3;
if (this.m_commandType == System.Data.CommandType.StoredProcedure)
{
str3 = this.m_commandText;
}
else
{
str3 = string.Empty;
}
OracleException.HandleError(errCode, this.m_connection, str3, this.m_opsErrCtx, this.m_pOpoSqlValCtx, this, true);
}
}
}
if ((dep != null) && !this.m_connection.m_contextConnection)
{
dep.m_bIsEnabled = true;
if (!dep.m_regList.Contains(this.m_commandText))
{
dep.m_regList.Add(this.m_commandText);
}
if ((bQueryBasedNTFNRegistration == 1) && !dep.m_queryIDList.Contains(num4))
{
dep.m_queryIDList.Add(num4);
}
}
if (((this.m_pOpoSqlValCtx.CommandType == 4) || (this.m_pOpoSqlValCtx.CommandType == 2)) || (this.m_pOpoSqlValCtx.CommandType == 3))
{
this.m_rowsAffected = this.m_pOpoSqlValCtx.RowsAffected;
}
else
{
this.m_rowsAffected = -1;
}
for (num7 = 0; num7 < prmCnt; num7++)
{
parameter = this.m_parameters[num7];
if (parameter.m_bOracleDbTypeExSet)
{
parameter.m_enumType = PrmEnumType.DBTYPE;
}
if (parameter.m_oraDbType == OracleDbType.RefCursor)
{
parameter.m_commandText = this.m_commandText;
if (this.m_bindByName)
{
parameter.m_paramPosOrName = parameter.ParameterName;
}
else
{
parameter.m_paramPosOrName = num7.ToString();
}
}
parameter.m_pOpoPrmValCtx = (OpoPrmValCtx*) pOpoPrmValCtx[num7];
try
{
if (parameter.m_direction == ParameterDirection.Input)
{
OracleDbType oraDbType = parameter.m_oraDbType;
switch (oraDbType)
{
case OracleDbType.Varchar2:
parameter.FreeDataBuffer();
goto Label_0AA3;
case OracleDbType.Date:
parameter.m_saveValue = null;
goto Label_0AA3;
}
if (oraDbType != OracleDbType.Decimal)
{
parameter.PostBind(this.m_connection, this.m_pOpoSqlValCtx, this.m_arrayBindCount);
}
}
else
{
parameter.PostBind(this.m_connection, this.m_pOpoSqlValCtx, this.m_arrayBindCount);
}
}
catch (Exception)
{
for (num8 = num7 + 1; num8 < prmCnt; num8++)
{
parameter = this.m_parameters[num8];
parameter.PreBindFree(this.m_connection, this.m_arrayBindCount);
}
this.FreeNonCachedOpoPrmCtx();
throw;
}
Label_0AA3:
if (parameter.m_bOracleDbTypeExSet)
{
parameter.m_enumType = PrmEnumType.ORADBTYPE;
}
}
this.FreeNonCachedOpoPrmCtx();
if (OraTrace.m_TraceLevel != 0)
{
OraTrace.Trace(1, new string[] { " (EXIT) OracleCommand::ExecuteNonQuery()\n" });
}
return this.m_rowsAffected;
}
(2)由于从xml解析出来的数据结构字段不一样,有时是8个,有时是9个,所以采用包含9个字段的实体方式来序列化xml的结构,对于那个时有时无的字段就允许存空字符串处理,所以需要一个实体类Model;
info.cs(注:类名需要保证和xml解析出来的表结构根节点一样,不然会取不到数据):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace Model
{
public class info
{
private string _id; //主键
private string _title; //标题
private string _posttime; //时间
private string _institution; //公共机构
private string _author; //作者
private string _url; //文章域名地址
private string _webname; //文章域名标题
private string _infotype; //信息类型
private string _summary; //文章内容
private string _fl; //文章分类
private string _grabtime;//抓取时间
/// <summary>
/// 必须有默认的构造函数
/// </summary>
public info()
{
}
public info(string id, string title, string posttime, string institution, string author, string url,
string webname, string infotype, string summary, string fl,string grabtime)
{
this._id = id;
this._title = title;
this._posttime = posttime;
this._institution = institution;
this._author = author;
this._url = url;
this._webname = webname;
this._infotype = infotype;
this._summary = summary;
this._fl = fl;
this._grabtime = grabtime;
}
public String id
{
get { return _id; }
set { _id = value; }
}
public String title
{
get { return _title; }
set { _title = value; }
}
public String posttime
{
get { return _posttime; }
set { _posttime = value; }
}
public String institution
{
get { return _institution; }
set { _institution = value; }
}
public String author
{
get { return _author; }
set { _author = value; }
}
public String url
{
get { return _url; }
set { _url = value; }
}
public String webname
{
get { return _webname; }
set { _webname = value; }
}
public String infotype
{
get { return _infotype; }
set { _infotype = value; }
}
public String summary
{
get { return _summary; }
set { _summary = value; }
}
public String fl
{
get { return _fl; }
set { _fl = value; }
}
public String grabtime
{
get { return _grabtime; }
set { _grabtime = value; }
}
}
}
list.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace Model
{
public class list
{
List<info> infoList = new List<info>();
[XmlElement(ElementName = "info")]
public List<info> InfoList
{
get { return infoList; }
set { infoList = value; }
}
}
}
(3)还需要一个数据库访问类库DAL:
OracleDBHelper.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using DatabaseLib;
using DataBaseLink;
using Model;
using Oracle.DataAccess.Client;
namespace DAL
{
public static class OracleDBHelper
{
//public static string ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
//public static string ConnectionString = ReadingConfig.XmlValue("Config", "basic.config", "/Basic/defaultConnectionString", "");
//public static string ConnectionString = "Data Source=orcl;User ID=LZF;Password=easyman";
public static string ConnectionString =
"DATA SOURCE=172.18.1.153/ORCL;PERSIST SECURITY INFO=True;USER ID=WJ_BASE;PASSWORD=WJ_BASE;POOLING=TRUE;MIN POOL SIZE=10;";
#region 对于所有表 ExecuteNonQuery() 直接对数据进行更新操作
public static int ExecuteNonQuery(string sql)
{
return ExecuteNonQuery(sql, null, CommandType.Text);
}
public static int ExecuteNonQuery(string sql, OracleParameter[] para)
{
return ExecuteNonQuery(sql, para, CommandType.Text);
}
public static int ExecuteNonQuery(string sql, CommandType cmdType)
{
return ExecuteNonQuery(sql, null, cmdType);
}
public static int ExecuteNonQuery(string sql, OracleParameter[] para, CommandType cmdType)
{
int rows = -1;
using (OracleConnection conn = new OracleConnection(ConnectionString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
if (para != null)
{
cmd.Parameters.AddRange(para);
}
cmd.CommandType = cmdType;
conn.Open();
rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
conn.Close();
}
return rows;
}
#endregion
#region 对于所有表 ExecuteReader 返回结果集
public static OracleDataReader ExecuteReader(string sql)
{
return ExecuteReader(sql, null, CommandType.Text);
}
public static OracleDataReader ExecuteReader(string sql, OracleParameter[] para)
{
return ExecuteReader(sql, para, CommandType.Text);
}
public static OracleDataReader ExecuteReader(string sql, CommandType cmdType)
{
return ExecuteReader(sql, null, cmdType);
}
public static OracleDataReader ExecuteReader(string sql, OracleParameter[] para, CommandType cmdType)
{
OracleCommand cmd = null;
OracleConnection conn = new OracleConnection(ConnectionString);
;
cmd = new OracleCommand(sql, conn);
if (para != null)
{
cmd.Parameters.AddRange(para);
}
cmd.CommandType = cmdType;
conn.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
#endregion
#region 对于所有表 ExecuteDataTable 返回数据表
public static DataTable ExecuteDataTable(string sql)
{
return ExecuteDataTable(sql, null, CommandType.Text);
}
public static DataTable ExecuteDataTable(string sql, OracleParameter[] para)
{
return ExecuteDataTable(sql, para, CommandType.Text);
}
public static DataTable ExecuteDataTable(string sql, CommandType cmdType)
{
return ExecuteDataTable(sql, null, cmdType);
}
public static DataTable ExecuteDataTable(string sql, OracleParameter[] para, CommandType cmdType)
{
try
{
DataTable myTable = new DataTable();
using (OracleConnection conn = new OracleConnection(ConnectionString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
if (para != null)
{
cmd.Parameters.Add(para);
}
cmd.CommandType = cmdType;
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.Fill(myTable);
}
return myTable;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 插入数据
/// </summary>
/// <param name="ag"></param>
/// <returns></returns>
public static int Insert(info ag )
{
////读连接字符串
//string connectStr = ConnectionString;
//DbLink link = new DbLink(connectStr);
////将存储过程接口传入
//DbEntityOperate dbOpt = new DbEntityOperate(typeof(IDbStoreProcedureManager), link);
////保存这条记录,返回影响的行数
//return dbOpt.InsertItem(ag).Count;
//读连接字符串
string connectStr = ConnectionString;
DbLink link = new DbLink(connectStr);
//将存储过程接口传入
DbEntityOperate dbOpt = new DbEntityOperate(typeof(IDbStoreProcedureManager), link);
//创建一个用于查询的实体,数据库应该已经有一条记录并且字段C1的值为“abc”
info entity = new info();
//entity.ID = ag.ID;
////调用查询返回结果
//List<AeGISSMSInfo> items = dbOpt.GetDataByPageSelect<AeGISSMSInfo>(entity, null, null);
//将返回的实体记录中C2字段改值并存入数据库
entity.author = ag.author;
entity.fl = ag.fl;
entity.id = ag.id;
entity.infotype = ag.infotype;
entity.institution = ag.institution;
entity.posttime = ag.posttime;
entity.summary = ag.summary;
entity.title = ag.title;
entity.url = ag.url;
entity.webname = ag.webname;
entity.grabtime = ag.grabtime;
//保存这条记录
return dbOpt.ApplyItem<Model.info>(entity).Count;
}
#endregion
/*
#region 对于所有表 ExecuteScalar 返回数据表
public static object ExecuteScalar(string sql)
{
return ExecuteScalar(sql, null, CommandType.Text);
}
public static object ExecuteScalar(string sql, SqlParameter[] para)
{
return ExecuteScalar(sql, para, CommandType.Text);
}
public static object ExecuteScalar(string sql, CommandType cmdType)
{
return ExecuteScalar(sql, null, cmdType);
}
public static object ExecuteScalar(string sql, SqlParameter[] para, CommandType cmdType)
{
object res = null;
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
if (para != null)
{
cmd.Parameters.AddRange(para);
}
cmd.CommandType = cmdType;
conn.Open();
res = cmd.ExecuteScalar();
cmd.Parameters.Clear();
conn.Close();
}
return res;
}
#endregion
*/
}
}
ConnectionString 为数据库连接字符串,该DAL需要引用DataBaseLink和DatabaseLib类库;
(4)Bll层:
AeGISSMSInfoService.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Net.Configuration;
using System.Text;
using System.Transactions;
using Model;
using DAL;
using Oracle.DataAccess.Client;
namespace BLL
{
public class AeGISSMSInfoService
{
/// <summary>
/// 舆情数据插入
/// </summary>
/// <param name="infoList">抓取的xml数据</param>
/// <returns></returns>
public Boolean Insert(List<info> infoList)
{
int m = 0;
int n = 0;
bool IsSucess = false;
using (TransactionScope tsCope = new TransactionScope())
{
foreach (info info in infoList)
{
string sqlQuery = string.Format(" select ID from AEGISSMSINFO where ID='{0}'",
info.id);
DataTable dtCount = DAL.OracleDBHelper.ExecuteDataTable(sqlQuery);
int rows = null != dtCount ? dtCount.Rows.Count : 0;
//过滤重复数据
if (rows > 0)
continue;
n++;
string sqlInsert =
" insert into AEGISSMSINFO(ID,AUTHOR,FL,INFOTYPE,INSTITUTION,POSTTIME,SUMMARY,TITLE,URL,WEBNAME,GRABTIME)" +
" values(:ID,:AUTHOR,:FL,:INFOTYPE,:INSTITUTION,:POSTTIME,:SUMMARY,:TITLE,:URL,:WEBNAME,:GRABTIME)";
OracleParameter p1 = new OracleParameter("ID", OracleDbType.NVarchar2);
OracleParameter p2 = new OracleParameter("AUTHOR", OracleDbType.Varchar2);
OracleParameter p3 = new OracleParameter("FL", OracleDbType.Varchar2);
OracleParameter p4 = new OracleParameter("INFOTYPE", OracleDbType.Varchar2);
OracleParameter p5 = new OracleParameter("INSTITUTION", OracleDbType.Varchar2);
OracleParameter p6 = new OracleParameter("POSTTIME", OracleDbType.Varchar2);
OracleParameter p7 = new OracleParameter("SUMMARY", OracleDbType.Clob);
OracleParameter p8 = new OracleParameter("TITLE", OracleDbType.Varchar2);
OracleParameter p9 = new OracleParameter("URL", OracleDbType.Varchar2);
OracleParameter p10 = new OracleParameter("WEBNAME", OracleDbType.Varchar2);
OracleParameter p11 = new OracleParameter("GRABTIME", OracleDbType.Varchar2);
p1.Value = info.id;
p2.Value = info.author;
p3.Value = info.fl;
p4.Value = info.infotype;
p5.Value = info.institution;
p6.Value = info.posttime;
p7.Value = info.summary;
p8.Value = info.title;
p9.Value = info.url;
p10.Value = info.webname;
p11.Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
OracleParameter[] ops = new OracleParameter[11];
ops[0] = p1;
ops[1] = p2;
ops[2] = p3;
ops[3] = p4;
ops[4] = p5;
ops[5] = p6;
ops[6] = p7;
ops[7] = p8;
ops[8] = p9;
ops[9] = p10;
ops[10] = p11;
int agcount = DAL.OracleDBHelper.ExecuteNonQuery(sqlInsert, ops);
if (agcount > 0)
{
m++;
WriteLog(string.Format(
" \r\n" +
"=====================================→数据插入成功({0}),当前第 [{1}] 条←=====================================\r\n",
p11.Value, n));
WriteLog(string.Format("插入成功,sql为:'{0}'\r\n,参数值依次为:\r\n{1}\r\n",
sqlInsert,
p1.Value + ",\r\n" + p2.Value + ",\r\n" + p3.Value + ",\r\n" + p4.Value + ",\r\n" +
p5.Value + ",\r\n" + p6.Value + ",\r\n" + p7.Value + ",\r\n" + p8.Value + ",\r\n" +
p9.Value + ",\r\n" + p10.Value));
}
else
{
WriteLog(string.Format(
" \r\n" +
"=====================================→数据插入失败({0}),当前第 [{1}] 条←=====================================\r\n",
p11.Value, n));
WriteLog(string.Format("插入失败,sql为:'{0}'\r\n,参数值依次为:\r\n{1}\r\n",
sqlInsert,
p1.Value + ",\r\n" + p2.Value + ",\r\n" + p3.Value + ",\r\n" + p4.Value + ",\r\n" +
p5.Value + ",\r\n" + p6.Value + ",\r\n" + p7.Value + ",\r\n" + p8.Value + ",\r\n" +
p9.Value + ",\r\n" + p10.Value));
}
}
if (m == n)
{
tsCope.Complete();
WriteLog(string.Format(
" \r\n" +
"=====================================→数据抓取成功({0})←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
WriteLog(string.Format("数据抓取成功,共抓取:{0}条数据.\r\n", m));
Console.ReadLine();
IsSucess = true;
}
else
{
tsCope.Dispose();
WriteLog(string.Format(
" \r\n" +
"=====================================→数据抓取失败({0})←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
WriteLog(string.Format("数据抓取失败,共抓取:{0}条数据,成功{1}条,失败{2}条。\r\n", n, m, n - m));
}
}
return IsSucess;
}
/// <summary>
/// 写入日志
/// </summary>
/// <param name="logMsg"></param>
private void WriteLog(string logMsg)
{
string pathLogs = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
string path = string.Format(pathLogs + "\\AeGISSMSInfoLog{0}.txt", DateTime.Now.ToString("yyyy-MM-dd"));
if (!Directory.Exists(pathLogs))
Directory.CreateDirectory(pathLogs);
if (!File.Exists(path))
File.Create(path);
FileInfo finfo = new FileInfo(path);
if (finfo.Exists)
{
using (FileStream fs = finfo.OpenWrite())
{
//根据上面创建的文件流创建写数据流
StreamWriter w = new StreamWriter(fs);
//设置写数据流的起始位置为文件流的末尾
w.BaseStream.Seek(0, SeekOrigin.End);
w.Write(logMsg);
//清空缓冲区内容,并把缓冲区内容写入基础流
w.Flush();
//关闭写数据流
w.Close();
}
}
}
}
}
(5)建一个Windows服务类库项目:
Program.cs是服务程序入口,用于实例化服务对象并执行服务程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
namespace AeGISSMSInfo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
Service1.cs是Windows服务执行相关操作的核心类:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using Oracle.DataAccess.Client;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Policy;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Timers;
using System.Xml;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
using Model;
namespace AeGISSMSInfo
{
public partial class Service1 : ServiceBase
{
private System.Timers.Timer timer; //计时器
private string IsStart = "0"; //服务启动开关,默认为关;0:关;1:开;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
IsStart = "1";
// TODO: 在此处添加代码以启动服务。
timer = new System.Timers.Timer(); //间隔10秒
timer.AutoReset = true;
timer.Interval = 2*3600*1000; //10000; // //24*3600*1000; //设置计时器事件间隔执行时间为2小时
timer.Enabled = false; //执行一次
timer.Elapsed += new ElapsedEventHandler(GrabXMLData);
timer.Start();
WriteLog(string.Format(
"=====================================→启动舆情系统xml接口数据抓取服务({0})←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
}
protected override void OnStop()
{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
this.timer1.Enabled = false;
WriteLog(string.Format(
"=====================================→关闭舆情系统xml接口数据抓取服务({0})←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
}
protected override void OnPause()
{
//服务暂停执行代码
base.OnPause();
}
protected override void OnContinue()
{
//服务恢复执行代码
base.OnContinue();
}
protected override void OnShutdown()
{
//系统即将关闭执行代码
base.OnShutdown();
}
/// <summary>
/// 抓取xml数据按其格式写入数据库
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private void GrabXMLData(object source, System.Timers.ElapsedEventArgs e)
{
//每晚21点执行该服务,读取xml写入数据库
//if (DateTime.Now.Hour == 21 && DateTime.Now.Minute == 0 && DateTime.Now.Second== 0)
//{
try
{
string strXMLURL = "http://218.108.28.100/aegis/smsInfoXml/zjwjj/Infos.xml";
HttpWebResponse rsp = null;
HttpWebRequest req = null;
req = (HttpWebRequest) WebRequest.Create(new Uri(strXMLURL));
req.ContentType = "multipart/form-data";
req.Accept = "*/*";
req.Timeout = 30000; //30秒连接不成功就中断
req.Method = "GET";
rsp = (HttpWebResponse) req.GetResponse();
StreamReader sr = new StreamReader(rsp.GetResponseStream(), Encoding.Default);
String result = sr.ReadToEnd();
//过滤非法字符
StringBuilder infos = new StringBuilder();
foreach (char cc in result)
{
int ss = (int) cc;
if (((ss >= 0) && (ss <= 8)) || ((ss >= 11) && (ss <= 12)) || ((ss >= 14) && (ss <= 32)))
infos.AppendFormat(" ", ss); //&#x{0:X};
else infos.Append(cc);
}
using (
StringReader rdr =
new StringReader(@"<?xml version='1.0' encoding='utf-8'?>" + infos.ToString().Trim()))
{
//声明序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof (Model.list));
//反序列化,并将反序列化结果值赋给变量i
Model.list AeGISSMSInfo = (Model.list) serializer.Deserialize(rdr);
List<info> infoList = AeGISSMSInfo.InfoList;
//输出反序列化结果
bool IsInsert = new BLL.AeGISSMSInfoService().Insert(infoList);
IsStart = IsInsert ? "0" : "1";
sr.Close();
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
WriteLog(string.Format(
" \r\n" +
"=====================================→数据抓取失败({0})←=====================================\r\n" +
"异常信息:{1}\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
ex.Message
));
}
//}
}
/// <summary>
/// 写入日志
/// </summary>
/// <param name="logMsg"></param>
private void WriteLog(string logMsg)
{
string pathLogs = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
string path = string.Format(pathLogs + "\\AeGISSMSInfoLog{0}.txt", DateTime.Now.ToString("yyyy-MM-dd"));
if (!Directory.Exists(pathLogs))
Directory.CreateDirectory(pathLogs);
if (!File.Exists(path))
File.Create(path);
FileInfo finfo = new FileInfo(path);
if (finfo.Exists)
{
using (FileStream fs = finfo.OpenWrite())
{
//根据上面创建的文件流创建写数据流
StreamWriter w = new StreamWriter(fs);
//设置写数据流的起始位置为文件流的末尾
w.BaseStream.Seek(0, SeekOrigin.End);
w.Write(logMsg);
//清空缓冲区内容,并把缓冲区内容写入基础流
w.Flush();
//关闭写数据流
w.Close();
}
}
}
}
}
ProjectInstaller.cs的ProjectInstaller.Designer
namespace AeGISSMSInfo
{
partial class ProjectInstaller
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall);
//
// serviceInstaller1
//
this.serviceInstaller1.Description = "抓取xml数据,按其格式导入到数据库表,每隔2小时抓取一次记录抓取时间,若失败则重试3次,逾次则弃";
this.serviceInstaller1.ServiceName = "AeGISSMSInfoService";
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
this.serviceInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceInstaller1_AfterInstall);
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
#endregion
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
}
}
(6)建一个安装项目:
添加项目输出:
在项目库上右击,
点击“确定”,AeGISSMSInfoService的主输出的项目项被添加到安装项目中。
添加自定义操作:
双击“应用程序文件夹”,点击“添加文件”将项目打包后要安装的项目添加到该列表中,
设置用户界面:
设置文件系统,
注意:在这个“文件系统”中如果要添加卸载程序需要到C:/windows/system32中找到一个msiexec.exe,选择后加入,然后右击该文件,创建快捷方式:
单击该快捷方式,然后选择面板上的“属性”或右击该快捷方式→“属性”:
对于这里面的Arguments的设置方法,单击解决方案管理器中的安装项目,选择面板中的属性(注意:这里不是右击选择“属性”,右击选择属性会出现:
)找到ProductCode:
复制后在上面提到的Arguments中键入:/x (此处粘贴刚才复制的ProductCode)
例:/x {9FCDEEEB-F6FC-4B84-B95D-C1B113F7CB28}
这个设置主要用来触发卸载操作;
2.安装服务:
编译运行该安装项目后会在其bin目录下生成一个AeGISSMSInfo.exe文件,然后
“开始”→“运行”→键入“cmd”命令出现dos操作窗口:
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Users\ld>cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe
目录名称无效。
C:\Users\ld>cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
C:\Windows\Microsoft.NET\Framework\v4.0.30319>InstallUtil D:\gawking\projects\Ae
GISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMSInfo.exe
Microsoft (R) .NET Framework 安装实用工具版本 4.0.30319.18408
版权所有 (C) Microsoft Corporation。保留所有权利。
正在运行事务处理安装。
正在开始安装的“安装”阶段。
查看日志文件的内容以获得 D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug
\AeGISSMSInfo.exe 程序集的进度。
该文件位于 D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMSInfo.
InstallLog。
正在安装程序集“D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMS
Info.exe”。
受影响的参数是:
logtoconsole =
logfile = D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMSInf
o.InstallLog
assemblypath = D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISS
MSInfo.exe
正在安装服务 AeGISSMSInfoService...
已成功安装服务 AeGISSMSInfoService。
正在日志 Application 中创建 EventLog 源 AeGISSMSInfoService...
“安装”阶段已成功完成,正在开始“提交”阶段。
查看日志文件的内容以获得 D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug
\AeGISSMSInfo.exe 程序集的进度。
该文件位于 D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMSInfo.
InstallLog。
正在提交程序集“D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMS
Info.exe”。
受影响的参数是:
logtoconsole =
logfile = D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISSMSInf
o.InstallLog
assemblypath = D:\gawking\projects\AeGISSMSInfo\AeGISSMSInfo\bin\Debug\AeGISS
MSInfo.exe
“提交”阶段已成功完成。
已完成事务处理安装。
C:\Windows\Microsoft.NET\Framework\v4.0.30319>
3.可以建两个服务启动和中止的批处理文件用来启动和中止服务:
或者新建一个Winform程序在界面按钮操作中实现开启和关闭服务的功能:
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;
namespace AeGISSMSInfoForms
{
public partial class Form1 : Form
{
//建立服务对象
private ServiceController sc = new ServiceController("AeGISSMSInfoService");
public Form1()
{
InitializeComponent();
}
private void btnStartOrStop_Click(object sender, EventArgs e)
{
bool IsStart = false;
//服务运行则停止服务
if (sc.Status.Equals(ServiceControllerStatus.Running))
{
this.btnStart.Text = "启动服务";
sc.Stop();
WriteLog(string.Format(
" \r\n" +
"=====================================→停止服务成功 {0}←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
MessageBox.Show("服务停止成功!");
}
//服务停止则启动服务
if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) || (sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
this.btnStart.Text = "停止服务";
sc.Start();
WriteLog(string.Format(
" \r\n" +
"=====================================→启动服务成功 {0}←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
MessageBox.Show("服务启动成功!");
}
////服务停止则启动服务
//if (this.btnStart.Text == "启动服务")
//{
// this.btnStart.Text = "停止服务";
// sc.Start();
// WriteLog(string.Format(
// " \r\n" +
// "=====================================→启动服务成功 {0}←=====================================\r\n",
// DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
//}
////服务运行则停止服务
//else if (this.btnStart.Text == "停止服务")
//{
// this.btnStart.Text = "启动服务";
// sc.Stop();
// WriteLog(string.Format(
// " \r\n" +
// "=====================================→停止服务成功 {0}←=====================================\r\n",
// DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
//}
sc.Refresh();
}
private void btnUninstall_Click(object sender, EventArgs e)
{
//ProcessStartInfo a =
// new ProcessStartInfo(
// string.Format(@"{0}\\AeGISSMSInfo.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory)),
// "-remove");
//a.WindowStyle = ProcessWindowStyle.Hidden;
//a.UseShellExecute = false;
//WriteLog(string.Format(
// " \r\n" +
// "=====================================→卸载服务成功 {0}←=====================================\r\n",
// DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
////MessageBox.Show("服务卸载成功!");
////Process process = Process.Start(a);
////UnInstallService();
//string pathLogs = Path.Combine(AppDomain.CurrentDomain.BaseDirectory);
//System.Diagnostics.Process.Start(pathLogs + "\\卸载该服务程序.exe");
if (ServiceIsExisted(sc.ServiceName))
{
try
{
string CurrentDirectory = System.Environment.CurrentDirectory;
System.Environment.CurrentDirectory = CurrentDirectory + "\\Service";
ManagedInstallerClass.InstallHelper(new string[] { "/u", "AeGISSMSInfo.exe" });
System.Environment.CurrentDirectory = CurrentDirectory;
WriteLog(string.Format(
" \r\n" +
"=====================================→服务卸载成功 {0}←=====================================\r\n",
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
MessageBox.Show("服务卸载成功!");
}
catch (Exception ex)
{
MessageBox.Show("服务卸载出错:" + ex.Message);
}
}
else
{
MessageBox.Show("您要卸载的服务不存在!");
}
}
private bool ServiceIsExisted(string svcName)
{
ServiceController[] services = ServiceController.GetServices();
foreach (ServiceController s in services)
{
if (s.ServiceName == svcName)
{
return true;
}
}
return false;
}
/// <summary>
/// 写入日志
/// </summary>
/// <param name="logMsg"></param>
public void WriteLog(string logMsg)
{
string pathLogs = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
string path = string.Format(pathLogs + "\\AeGISSMSInfoLog{0}.txt", DateTime.Now.ToString("yyyy-MM-dd"));
if (!Directory.Exists(pathLogs))
Directory.CreateDirectory(pathLogs);
if (!File.Exists(path))
File.Create(path);
FileInfo finfo = new FileInfo(path);
if (finfo.Exists)
{
using (FileStream fs = finfo.OpenWrite())
{
//根据上面创建的文件流创建写数据流
StreamWriter w = new StreamWriter(fs);
//设置写数据流的起始位置为文件流的末尾
w.BaseStream.Seek(0, SeekOrigin.End);
w.Write(logMsg);
//清空缓冲区内容,并把缓冲区内容写入基础流
w.Flush();
//关闭写数据流
w.Close();
}
}
}
}
}
这只是个简单的操作,默认加载时判断服务如果是开启的,则按钮文字显示“停止服务”,反之显示“开启服务”,交替操作;
这样,一个解析xml抓取数据并插入数据库的Windows服务就写好了,每次电脑开启的时候就会自动启动该服务,每隔两小时就会抓取数据存入数据库。
记录的日志结果: