我也来学着写写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;
        }
OracleCommand.cs中的ExecuteNonQuery

 

(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();
                }
            }
        }
    }
}
AeGISSMSInfoService.cs

(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();
                }
            }
        }
    }
}
Service1.cs

 

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();
                }
            }
        }
    }
}
Form1.cs

这只是个简单的操作,默认加载时判断服务如果是开启的,则按钮文字显示“停止服务”,反之显示“开启服务”,交替操作;

 

这样,一个解析xml抓取数据并插入数据库的Windows服务就写好了,每次电脑开启的时候就会自动启动该服务,每隔两小时就会抓取数据存入数据库。

 

记录的日志结果:

 

 

posted @ 2015-05-25 11:58  以便以谢  阅读(1820)  评论(1编辑  收藏  举报