Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,支持cron-like表达式等等
以上介绍是从博客园张善友(http://www.VEVb.com/shanyou/archive/2007/08/25/quartznettutorial.html)的博客摘录,可登录他博客具体了解quartz.net。
我在这里只讲具体在项目中的实现:
通过Windows服务调用Quartz.net,然后Quartz.net 调用WinForm消息窗口,实现计划任务消息推送。
【Windows服务】-->【Quartz.net】 --> 【Winform .exe】 --> 【程序打包】
项目解决方案,如图所示:
1、打开vs2010--新建项目--选择"Windows服务",我这里命名为"QuartzService". 创建好后首先映入我们眼帘的是QuartzService.cs[设计]视图,右键点设计视图选择"添加安装程序",如下图:
注释:(创建一个Windows服务,仅用InstallUtil程序去安装这个服务是不够的。你必须还要把一个服务安装程序添加到你的Windows服务当中,这样便于InstallUtil或是任何别的安装程序知道应用你服务的是怎样的配置设置)
2、切换到刚被添加的PRojectInstaller的设计视图,设置serviceInstaller1组件的属性: StartType = Automatic;ServiceName =QuartzService;
设置serviceProcessInstaller1组件的属性Account = LocalSystem;如下图:
3、QuartzService中添加Quartz.dll ,log4net.dll引用,在QuartzService.cs文件中引用命名空间 Quartz;Quartz.Impl; log4net;
右键点击QuartzService项目,属性-目标框架 ,选择.net Framwork 4,如下图:
4、添加app.config配置文件,具体配置如下:
1 <?xml version="1.0"?> 2 <configuration> 3 <configSections> 4 <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/> 5 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 6 <sectionGroup name="common"> 7 <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/> 8 </sectionGroup> 9 </configSections>10 <common>11 <logging>12 <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">13 <arg key="configType" value="INLINE"/>14 </factoryAdapter>15 </logging>16 </common>17 <log4net>18 <appender name="InfoFileAppender" type="log4net.Appender.RollingFileAppender">19 <file value="log/" />20 <appendToFile value="true" />21 <param name="DatePattern" value="yyyyMMdd".txt"" />22 <rollingStyle value="Date" />23 <maxSizeRollBackups value="100" />24 <maximumFileSize value="1024KB" />25 <staticLogFileName value="false" />26 <Encoding value="UTF-8" />27 <filter type="log4net.Filter.LevelRangeFilter">28 <param name="LevelMin" value="INFO" />29 <param name="LevelMax" value="INFO" />30 </filter>31 <layout type="log4net.Layout.PatternLayout">32 <conversionPattern value="%date %-5level %logger - %message%newline" />33 </layout>34 </appender>35 <appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender">36 <file value="log/error.txt" />37 <appendToFile value="true" />38 <rollingStyle value="Size" />39 <maxSizeRollBackups value="100" />40 <maximumFileSize value="10240KB" />41 <staticLogFileName value="true" />42 <Encoding value="UTF-8" />43 <filter type="log4net.Filter.LevelRangeFilter">44 <param name="LevelMin" value="WARN" />45 <param name="LevelMax" value="FATAL" />46 </filter>47 <layout type="log4net.Layout.PatternLayout">48 <conversionPattern value="%date %-5level %logger - %message%newline" />49 </layout>50 </appender>51 <root>52 <level value="INFO" />53 <appender-ref ref="InfoFileAppender" />54 <appender-ref ref="ErrorFileAppender" />55 </root>56 </log4net>57 58 <!-- 59 We use quartz.config for this server, you can always use configuration section if you want to.60 Configuration section has precedence here. 61 -->62 <appSettings>63 <!-- YYC.WebService URL地址 -->64 <add key="URL" value="http://localhost:43093/WebService.asmx" />65 </appSettings>66 <!--67 <quartz >68 </quartz>69 -->70 <startup>71 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>72 </startup>73 </configuration>View Code
1、在解决方案中添加新项-选择"类库",我这里命名为Quartz.Net.JobLibrary,Quartz.Net.JobLibrary用来实现多个"作业"类。Quartz.Net.JobLibrary类库中添加Quartz.dll ,log4net.dll引用。
Quartz.Net.JobLibrary类库中添加一个类Interop.cs,这个类是为了解决在Win7中出现【交互式检测】弹窗,博客园李敬然(http://www.VEVb.com/gnielee/archive/2010/04/07/session0-isolation-part1.html)的博客详细谈到 穿透Session 0 隔离,具体代码如下:
1 using System; 2 using System.Runtime.InteropServices; 3 4 namespace Quartz.Net.JobLibrary 5 { 6 public class Interop 7 { 8 public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero; 9 public static void ShowMessageBox(string message, string title) 10 { 11 int resp = 0; 12 WTSSendMessage( 13 WTS_CURRENT_SERVER_HANDLE, 14 WTSGetActiveConsoleSessionId(), 15 title, title.Length, 16 message, message.Length, 17 0, 0, out resp, false); 18 } 19 [DllImport("kernel32.dll", SetLastError = true)] 20 public static extern int WTSGetActiveConsoleSessionId(); 21 [DllImport("wtsapi32.dll", SetLastError = true)] 22 public static extern bool WTSSendMessage( 23 IntPtr hServer, 24 int SessionId, 25 String pTitle, 26 int TitleLength, 27 String pMessage, 28 int MessageLength, 29 int Style, 30 int Timeout, 31 out int pResponse, 32 bool bWait); 33 34 public static void CreateProcess(string app, string path) 35 { 36 IntPtr hToken; 37 IntPtr hDupedToken = IntPtr.Zero; 38 39 PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 40 SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 41 sa.Length = Marshal.SizeOf(sa); 42 43 STARTUPINFO si = new STARTUPINFO(); 44 si.cb = Marshal.SizeOf(si); 45 46 int dwSessionID = WTSGetActiveConsoleSessionId(); 47 bool result = WTSQueryUserToken(dwSessionID, out hToken); 48 49 if (!result) 50 { 51 ShowMessageBox("WTSQueryUserToken failed", "AlertService Message"); 52 } 53 54 result = DuplicateTokenEx( 55 hToken, 56 GENERIC_ALL_access, 57 ref sa, 58 (int)SECURITY
新闻热点
疑难解答