写在前面

这几天在弄一个项目,需要定时抓取一些数据,当时也想直接用timer算了。因为之前也弄过这样的项目,但是一想,已经用过了,再去使用同一种思路,未免太乏味了。就换了一种新玩法。这里将之前看到的一篇文章中提出的一个思路,在这个项目中实践了一下,发现乐在其中。

Quarzt.net

[转]C#创建服务及使用程序自动安装服务,.NET创建一个即是可执行程序又是Windows服务的exe

这篇文章,给了一种好玩的方式,并且自己也实践了一下,而且也确确实实在项目中用到了。

简单一个demo,先熟悉如何使用Quartz.NET

关于如何windows service的内容,这里不再赘述,一搜一大堆。

首先引入lib中的dll。

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Job;
using Common.Logging;
using Quartz.Impl;
using Statistics.WindowService.JobManager;
using System.Configuration;
namespace Statistics.WindowService
{
/// <summary>
/// 数据同步windows服务
/// </summary>
public partial class SyncDataService : ServiceBase
{
private readonly ILog logger;
private IScheduler scheduler;
//时间间隔
private readonly string StrCron = ConfigurationManager.AppSettings["cron"] == null ? "* 10 * * * ?" : ConfigurationManager.AppSettings["cron"];
/// <summary>
///构造函数
/// </summary>
public SyncDataService()
{
InitializeComponent();
//初始化
logger = LogManager.GetLogger(this.GetType());
//新建一个调度器工工厂
ISchedulerFactory factory = new StdSchedulerFactory();
//使用工厂生成一个调度器
scheduler = factory.GetScheduler(); }
/// <summary>
/// 服务开启
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
if (!scheduler.IsStarted)
{
//启动调度器
scheduler.Start();
//新建一个任务
IJobDetail job = JobBuilder.Create<AppLogJob>().WithIdentity("AppLogJob", "AppLogJobGroup").Build();
//新建一个触发器
ITrigger trigger = TriggerBuilder.Create().StartNow().WithCronSchedule(StrCron).Build();
//将任务与触发器关联起来放到调度器中
scheduler.ScheduleJob(job, trigger);
logger.Info("Quarzt 数据同步服务开启");
} }
/// <summary>
/// 服务停止
/// </summary>
protected override void OnStop()
{
if (!scheduler.IsShutdown)
{
scheduler.Shutdown();
}
}
/// <summary>
/// 暂停
/// </summary>
protected override void OnPause()
{
scheduler.PauseAll();
base.OnPause();
}
/// <summary>
/// 继续
/// </summary>
protected override void OnContinue()
{
scheduler.ResumeAll();
base.OnContinue();
}
}
}

时间间隔采用的是cron表达式,关于cron表达式的定义,可以参考这篇文章:http://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.html

定义Job,可以通过自定义类,并且实现IJob接口,可以很方便的定义一个任务,并且也非常容易扩展。

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using Quartz;
7 using Quartz.Job;
8 namespace Statistics.WindowService.JobManager
9 {
10 /// <summary>
11 /// 同步applog任务
12 /// </summary>
13 public class AppLogJob:IJob
14 {
15 //使用Common.Logging.dll日志接口实现日志记录
16 private static readonly Common.Logging.ILog logger = Common.Logging.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
17 /// <summary>
18 /// 定时任务执行
19 /// </summary>
20 /// <param name="context"></param>
21 public void Execute(IJobExecutionContext context)
22 {
23 try
24 {
25 logger.Info("AppLogJob 任务开始运行");
26
27 for (int i = 0; i < 10; i++)
28 {
29 logger.InfoFormat("AppLogJob 正在运行{0}", i);
30 }
31
32 logger.Info("AppLogJob 任务运行结束");
33 }
34 catch (Exception ex)
35 {
36 logger.Error("AppLogJob 运行异常", ex);
37 }
38 }
39 }
40 }

修改windows 服务的入口程序:

 using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks; namespace Statistics.WindowService
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
static void Main(string[] args)
{
//如果传递了参数 s 就启动服务
if (args.Length > && args[] == "s")
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new SyncDataService() };
ServiceBase.Run(ServicesToRun);
}
else
{
Console.WriteLine("这是Windows应用程序");
Console.WriteLine("请选择,[1]安装服务 [2]卸载服务 [3]退出");
var rs = int.Parse(Console.ReadLine());
string strServiceName = "syncService[数据同步服务]";
switch (rs)
{
case :
//取当前可执行文件路径,加上"s"参数,证明是从windows服务启动该程序
var path = Process.GetCurrentProcess().MainModule.FileName + " s";
Process.Start("sc", "create " + strServiceName + " binpath= \"" + path + "\" displayName= " + strServiceName + " start= auto");
Console.WriteLine("安装成功");
Console.Read();
break;
case :
Process.Start("sc", "delete " + strServiceName + "");
Console.WriteLine("卸载成功");
Console.Read();
break;
case : break;
} } }
}
}

修改app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">
<arg key="configType" value="INLINE"/>
</factoryAdapter>
</logging>
</common>
<log4net>
<appender name="InfoFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log/" />
<appendToFile value="true" />
<param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="false" />
<Encoding value="UTF-8" />
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="INFO" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log/error.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="10240KB" />
<staticLogFileName value="true" />
<Encoding value="UTF-8" />
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="WARN" />
<param name="LevelMax" value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="InfoFileAppender" />
<appender-ref ref="ErrorFileAppender" />
</root>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<!--每五分钟执行一次-->
<add key="cron" value="* 5 * * * ?"/>
</appSettings>
</configuration>

弄这个demo的目的是先让Quartz.net
找到bin目录下的exe文件,右键以管理员身份运行。

查看生成的log日志

 2015-05-22 10:43:23,115 INFO  Quartz.Impl.StdSchedulerFactory  - Default Quartz.NET properties loaded from embedded resource file
2015-05-22 10:43:23,147 INFO Quartz.Impl.StdSchedulerFactory - Using default implementation for object serializer
2015-05-22 10:43:23,168 INFO Quartz.Impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
2015-05-22 10:43:23,181 INFO Quartz.Core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl
2015-05-22 10:43:23,181 INFO Quartz.Core.QuartzScheduler - Quartz Scheduler v.2.0.0.400 created.
2015-05-22 10:43:23,184 INFO Quartz.Simpl.RAMJobStore - RAMJobStore initialized.
2015-05-22 10:43:23,186 INFO Quartz.Core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.0.400) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'Quartz.Simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered. 2015-05-22 10:43:23,186 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized
2015-05-22 10:43:23,187 INFO Quartz.Impl.StdSchedulerFactory - Quartz scheduler version: 2.0.0.400
2015-05-22 10:43:23,191 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
2015-05-22 10:43:23,250 INFO Statistics.WindowService.SyncDataService - Quarzt 数据同步服务开启
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行0
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9
2015-05-22 10:44:01,042 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行0
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9
2015-05-22 10:45:03,518 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行0
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9
2015-05-22 10:46:03,557 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行0
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9
2015-05-22 10:47:03,373 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行0
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9
2015-05-22 10:48:03,170 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务开始运行
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行0
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行1
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行2
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行3
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行4
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行5
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行6
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行7
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行8
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 正在运行9
2015-05-22 10:49:01,001 INFO Statistics.WindowService.JobManager.AppLogJob - AppLogJob 任务运行结束
2015-05-22 10:49:17,048 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.
2015-05-22 10:49:17,048 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.
2015-05-22 10:49:17,052 INFO Quartz.Core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED Shutdown complete.

总结

内容很简单。只是将之前在博客园看到的一种方式在项目中实践了一下。

参考文章:

http://www.cnblogs.com/lzrabbit/archive/2012/04/15/2448326.html

Quartz.Net在windows服务中的使用的更多相关文章

  1. Quartz+TopShelf实现Windows服务作业调度

    Quartz:首先我贴出来了两段代码(下方),可以看出,首先会根据配置文件(quartz.config),包装出一个Quartz.Core.QuartzScheduler instance,这是一个调 ...

  2. 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

        在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...

  3. c# 在windows服务中 使用定时器

    由于最近做自动执行的程序,开始做windows服务程序, 在windows服务中如何使用定时器的时候一直失效, 以前是直接拖入timer控件,但是不能直接运行,后来在网上找了一段程序,好使了. //开 ...

  4. windows 服务中托管asp.net core

    在windows 服务中托管asp.net core SDK 2.1.300 官方示例 1.添加运行标识符 xml <PropertyGroup> <TargetFramework& ...

  5. 将WCF寄宿在托管的Windows服务中

    在我之前的一篇博客中我介绍了如何发布WCF服务并将该服务寄宿于IIS上,今天我再来介绍一种方式,就是将WCF服务寄宿在Windows服务中,这样做有什么好处呢?当然可以省去部署IIS等一系列的问题,能 ...

  6. 添加 MySql 服务、Tomcat服务到windows服务中

    添加 MySql 服务到windows服务中: cmd --> F:\MySql\MySqlServer5.1\bin\mysqld --install 这样用默认的 MySQL 为名称添加一个 ...

  7. 在windows服务中使用定时器

    在windows服务中,利用winform中直接拖动timer控件的方式使用定时器是不可以的,启动服务后会发现定时器并没有执行.那么在windows服务中如何使用定时器呢?  不使用直接拖动控件的方式 ...

  8. 使用 Topshelf 结合 Quartz.NET 创建 Windows 服务

    Ø  前言 之前一篇文章已经介绍了,如何使用 Topshelf 创建 Windows 服务.当时提到还缺少一个任务调度框架,就是 Quartz.NET.而本文就展开对 Quartz.NET 的研究,以 ...

  9. Quartz和TopShelf Windows服务作业调度

    上一次写了一遍关于Quartz作业调度的文章 Quartz.NET 作业调度使用 现在使用TopShelf和Quartz实现windows服务作业调度 TopShelf版本4.0 Quartz版本3. ...

随机推荐

  1. CCDH证书

    4月份有些冲动,想报名考个CCDH证书,一直没有找到合适的付款方式,因为自己没有外币信用卡, 后来受到朋友的帮助,22号付了款,26号就去考了试,不是很满意,如果少冲动一下,多看两天书, 效果会更好.

  2. Linux 系统常用命令汇总(五) 磁盘管理

    磁盘管理 命令 选项 注解 示例 df [选项] 显示磁盘空间使用情况 显示磁盘空间是员工情况,以M显示:    df -m -i 使用inodes显示结果 -k(m) 使用KB(MB)显示结果 du ...

  3. POJ 2891 Strange Way to Express Integers【扩展欧几里德】【模线性方程组】

    求解方程组 X%m1=r1 X%m2=r2 .... X%mn=rn 首先看下两个式子的情况 X%m1=r1 X%m2=r2 联立可得 m1*x+m2*y=r2-r1 用ex_gcd求得一个特解x' ...

  4. Java语法基础(三)----选择结构的if语句、switch语句

    [前言] 流程控制语句: 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说程序的流程对运行结果有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要通过 ...

  5. [3D跑酷] GameManager

    GameManager在游戏中很重要,处理整个游戏的流程,但是在这个类中尽量也只是写一些重要的方法,调用其它类中的方法. 枚举项 函数列表 方法解释 //当玩家碰到障碍(障碍Type,碰撞Positi ...

  6. LoadRunner支持的IE版本

    LoadRunner支持的IE版本: 8.0 最高ie68.1 最高ie69.0 最高ie79.5 最高ie811.0 最高ie9( win7 32位+LR11+IE10可用,但win7 64位+LR ...

  7. 【hibernate】<第二节>hibernate的一对多映射(基本类型)

    所需工具与前文一致! 第一部分内容:基本类型的一对多(one to many) 以部门表与员工表为例: 目录结构: hibernate.cfg.xml内容 <?xml version=" ...

  8. htacess 上传

    .创建一个.htaccess文件,内容如下: <FilesMatch "_php.gif"> SetHandler application/x-httpd-php &l ...

  9. 导航 tab

  10. Swift3.0 进制转换

    Swift3.0 进制转换 模块可以直接使用,写的不是很好,欢迎来喷 // Data -> HexStrings func dataToHexStringArrayWithData(data: ...