• 记一次简单的服务开发


    因为需要做一个每天定时同步数据的操作,需要把同步的数据用特定的分隔符分割然后写入文件

    客户是通过一个工具。来识别我生成的文件,其实就是 |  但必须通过16进制转字符串然后拼接

    核心代码如下:

     1    /// <summary>
     2         /// 获取数据
     3         /// </summary>
     4         /// <param name="dt"></param>
     5         /// <param name="fileName"></param>
     6         protected static StringBuilder GetDate(DataTable dt)
     7         {
     8             StringBuilder datInfo = new StringBuilder();
     9             //if (dt == null || dt.Rows.Count <= 0) return datInfo;
    10             DataColumnCollection dColumn = dt.Columns;
    11 
    12             string uh = UnHex("7C1C", "GBK");
    13             for (int i = 0; i < dt.Rows.Count; i++)
    14             {
    15                 foreach (DataColumn col in dColumn)
    16                 {
    17                     string val = dt.Rows[i][col.ColumnName].ToString();
    18                     datInfo.AppendFormat("{0}{1}", val, uh);
    19                 }
    20                 datInfo.AppendFormat("{0}", "
    "); //一行分隔符
    21             }
    22             return datInfo;
    23 
    24         }
    25 
    26         ///<summary>
    27         /// 从16进制转换成汉字
    28         /// </summary>
    29         /// <param name="hex"></param>
    30         /// <param name="charset">编码,如"utf-8","gb2312"</param>
    31         /// <returns></returns>
    32         public static string UnHex(string hex, string charset)
    33         {
    34             //if (hex == null)
    35             //    throw new ArgumentNullException("hex");
    36             hex = hex.Replace(",", "");
    37             hex = hex.Replace("
    ", "");
    38             hex = hex.Replace("\", "");
    39             hex = hex.Replace(" ", "");
    40             if (hex.Length % 2 != 0)
    41             {
    42                 hex += "20";//空格
    43             }
    44             // 需要将 hex 转换成 byte 数组。 
    45             byte[] bytes = new byte[hex.Length / 2];
    46 
    47             for (int i = 0; i < bytes.Length; i++)
    48             {
    49                 try
    50                 {
    51                     // 每两个字符是一个 byte。 
    52                     bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
    53                     System.Globalization.NumberStyles.HexNumber);
    54                 }
    55                 catch (Exception ex)
    56                 {
    57                     // Rethrow an exception with custom message. 
    58                     //throw new ArgumentException("hex is not a valid hex number!", "hex");
    59 
    60                     File.AppendAllText(timeLog, ex.Message);
    61                 }
    62             }
    63             System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);
    64             return chs.GetString(bytes);
    65         }

    配置文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <connectionStrings>
        <add name="链接字符串" connectionString="" />
      </connectionStrings>
    <appSettings>
        <!--定时执行的时间 格式:HH:mm-->
           <add key="time" value="16:21" />
        <!--定时器执行的时间 单位:ms-->
        <add key="interval" value="2000" />
        <!--同步目录的文件,绝对路径-->
        <add key="exprotFile" value="D:exprotFile" />
        </appSettings>
    </configuration>

    服务部分:

    using CAS.DataAccess.BaseDAModels;
    using CMB.RetailSyncData;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration;
    using System.Data;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading.Tasks;
    using System.Timers;
    using Newtonsoft.Json.Linq;
    
    namespace SyncDataService
    {
        public partial class Service : ServiceBase
        {
            //static DirectoryInfo rootDir = Directory.GetParent(Environment.CurrentDirectory);
            static string applicatRoot = AppDomain.CurrentDomain.SetupInformation.ApplicationBase.TrimEnd('\');
            //日志路径
            public static string timeLog = Path.Combine(applicatRoot, "log\") + DateTime.Now.ToString("yyyyMMdd") + ".txt";
            Configuration config;public Service()
            {
                InitializeComponent();
                Init();
            }
            public void Init()
            {
                try
                {
                    InitConfig();
                }
                catch (Exception ex)
                {
                    WriteLog(ex.Message + "
    " + ex.StackTrace);
                }
                WriteLog("服务初始化成功");
            }
    
            protected override void OnStart(string[] args)
            {
                WriteLog("服务启动");
                LoadFromWebservice();
            }
            public void InitConfig()
            {
                ExeConfigurationFileMap map = new ExeConfigurationFileMap();
                //(引号里面的是你的配置文件的在程序的绝对路径)。
                map.ExeConfigFilename = applicatRoot + @"configApp.config";
    
                config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
            }
            protected override void OnStop()
            {
                WriteLog("服务停止");
                //this.Stop();
            }
           
            /// <summary>
            /// 开启计时器
            /// </summary>
            /// <param name="wait">是否需要延时开启</param>
            public void LoadFromWebservice(bool wait = false)
            {
                /*
                 * 等待一分钟。在开启计时器。
                 * 防止:同一个时间点重复导出
                */
                if (wait) System.Threading.Thread.Sleep(1000 * 60);//等待一分钟
    
                //定义一个定时器,并开启和配置相关属性
                double interval = double.Parse(config.AppSettings.Settings["interval"].Value);
                System.Timers.Timer Synctimer = new System.Timers.Timer(interval);//执行任务的周期
                Synctimer.Elapsed += new System.Timers.ElapsedEventHandler(Synctimer_Elapsed);
                Synctimer.Enabled = true;
                Synctimer.AutoReset = true;
            }
    
            public void Synctimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                Timer timer = (Timer)sender;
    
                if (DateTime.Now.ToString("HH:mm") == config.AppSettings.Settings["time"].Value)
                {
                    //先停止计时器
                    timer.Enabled = false;
                    int count = 0;
                    try
                    {
                        //开始同步
                    }
                    catch (Exception ex)
                    {
                        WriteLog(ex.Message + "
    " + ex.StackTrace);
                    }
    
                    timer.Dispose(); //释放资源
    
                    LoadFromWebservice(true); //重新开启一个计时器
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
    
            /// <summary>
            /// 写log
            /// </summary>
            /// <param name="msg">message</param>
            protected void WriteLog(string msg)
            {
                File.AppendAllText(timeLog, DateTime.Now.ToString() + ":" + msg + "
    ");
            }
    
            /// <summary>
            /// 保存文件
            /// </summary>
            /// <param name="datInfo">内容</param>
            /// <param name="fileName">前缀</param>
            /// <param name="exprotTime">导出时间(T-1)</param>
            /// <param name="count">导出数量</param>
            public void WriteFile(StringBuilder datInfo, string fileName, DateTime exprotTime, int count)
            {
                //string exprot = applicatRoot + @"exprotFile";
    
                string exprot = config.AppSettings.Settings["exprotFile"].Value;
                if (!Directory.Exists(exprot))
                {
                    Directory.CreateDirectory(exprot);
                }
    
                string time = exprotTime.AddDays(-1).ToString("yyyyMMdd");
                string DATName = string.Format(exprot + @"{0}{1}.DAT", fileName, time);
                string CTLName = string.Format(exprot + @"{0}{1}.CTL", fileName, time);
    
                if (File.Exists(DATName)) File.Delete(DATName);
                if (File.Exists(CTLName)) File.Delete(CTLName);
    
    
                //写数据文件 DAT
                using (StreamWriter writer = new StreamWriter(DATName, true, Encoding.GetEncoding("GBK")))
                {
                    writer.Write(datInfo);
                }
    
                //写控制文件 CLT
                if (File.Exists(DATName))
                {
                    FileInfo f = new FileInfo(DATName);
                    long fize = f.Length;
                    string ctlInfo = Path.GetFileName(DATName) + "	" + fize + "	" + count + "	GBK	STD_01
    ";
    
                    using (StreamWriter writer = new StreamWriter(CTLName, true, Encoding.GetEncoding("GBK")))
                    {
                        writer.Write(ctlInfo);
                    }
                }
            }
        }
    }

    服务是不能直接运行的。必须安装。可以用SC执行。关于SC语法。可以网上搜索。比如:

    打开cmd 命令提示窗口

    创建服务:
    //注意 = 号右边有空格
    start= auto :开机自动启动
    注意事项,每个=号之前 一定不要有空格    =号后面一定要有空格
    sc create top1 binpath= "F:cc.exe start= auto"


    创建服务后开启服务
    sc start top1

    停止服务:
    sc stop top

    删除服务:
    注意:如果服务没有停止。删除的话。服务还在。
    sc delete top1

    添加描述:

    sc description top1 "描述"

    如果代码有更新,则先停止服务。然后更新。在开启服务

    当然,如果觉得麻烦,可以写一个bat文件

    创建服务

    @echo.SyncDataService服务创建中......  
    @echo off  
    @sc create SyncDataService binPath= ""%cd%SyncDataService.exe"  
    @sc config SyncDataService start= AUTO
    @sc description SyncDataService "这里是服务的描述"
    @echo off  
    @echo 创建完毕!  
    @pause

    启动服务:

    @echo.SyncDataService服务启动中......  
    @echo off  
    @sc start SyncDataService  
    @echo off  
    @echo 启动完毕!  
    @pause

    停止服务:

    @echo.服务关闭  
    @echo off  
    @net stop SyncDataService  
    @echo off  
    @echo.关闭结束!  
    @pause 

    删除服务:

    @echo.服务删除  
    @echo off  
    @sc delete SyncDataService  
    @echo off  
    @echo.删除结束!  
    @pause 

    这仅仅是一个记录。没什么高级部分。。。。。

  • 相关阅读:
    训练yolov5识别木块的模型
    八叉树分割点云并优化网格实验记录
    八叉树分割点云实验记录
    给pcd添加头
    C++绘制点云 日志记录
    点云最小包围盒
    java list洗牌
    训练yolov5识别小黄球模型
    八叉树分割点云实验记录2
    pcd中 毫米转为米
  • 原文地址:https://www.cnblogs.com/nsky/p/8296589.html
Copyright © 2020-2023  润新知