C# Windows 服务安装并运行服务
来源:互联网 发布:淘宝可以用花呗吗 编辑:程序博客网 时间:2024/06/05 00:36
开发目的:C#开发windows服务,并制作安装包。安装过程中配置系统参数。
功能描述:服务监控一个文件目录和其子目录,如果里面有新增rar的文件,就记录其信息。待到设定的时间,使用FTP上传功能,上传到FTP服务器。
代码示例:
1、文件目录监控类:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading;namespace FTPUploadComponent{ /// <summary> /// 监控目录 FileSystemWatcher /// </summary> public class DirectoryWatcher : IDisposable { private FileSystemWatcher _fsw = null; private FTPConfigSection _ftpSection = null; private FTPWatcherItem _ftpWtchItem = null; private FTPLog _ftpLog = null; public DirectoryWatcher(FTPConfigSection ftpCfgSection) { if (_fsw == null) { _ftpSection = ftpCfgSection; _ftpWtchItem = _ftpSection.WatcherCollection[0]; _ftpLog = new FTPLog(_ftpSection.LogCollection); } } public void SetWatcherDir() { _fsw = new FileSystemWatcher(_ftpWtchItem.WatcherDir, _ftpWtchItem.WatcherFileType); _fsw.IncludeSubdirectories = _ftpWtchItem.WatcherSubDir; _fsw.EnableRaisingEvents = true; _fsw.Created += new FileSystemEventHandler(DirectoryWatcher_Created); while (true) { //一直运行,防止线程停止,对要监视的目录失效 Thread.Sleep(1000*60*24); } } protected void DirectoryWatcher_Created(object sender, FileSystemEventArgs e) { string fileName = e.Name.Substring(e.Name.LastIndexOf('\\')+1); try { Thread.Sleep(_ftpWtchItem.WatcherWaitIntival); //ftpUpload.FTPUpLoadFile(e.Name); //写记录日志 _ftpLog.LogOpeFlag = OpeFlag.Record; _ftpLog.LogContent = string.Format("{0}|{1}", e.FullPath, fileName); _ftpLog.WriteFtpLog(); } catch (Exception ex) { //写失败记录 _ftpLog.LogOpeFlag = OpeFlag.Error; _ftpLog.LogContent = string.Format("FTP upload file failed.Time is {0}.Rerson is {1}. FilePath:<#{2}#>", DateTime.Now.ToString("yyyy-MM-dd HH:mi:ss"), ex.Message, e.FullPath); _ftpLog.WriteFtpLog(); } } public void Dispose() { if (!_fsw.Equals(null)) { _fsw.Dispose(); } } }}
代码中只对监控目录的新增文件经行处理。如果有新增文件则由DirectoryWatcher_Created方法处理。
参数FTPConfigSection是自定的FTP配置文件对应的操作类。
2、FTP上传类:
using System;using System.Net;using System.IO;using System.Threading;namespace FTPUploadComponent{ public class AsynchronousFtpUpLoader:IDisposable { private FTPUploadItem _ftpUpItem = null; private string _ftpUri = ""; private FtpWebRequest _request = null; private ManualResetEvent _waitObject = null; private FTPLog _ftpLog = null; public FTPLog FtpLog { set { _ftpLog = value; } } public AsynchronousFtpUpLoader(FTPUploadItem ftpUpItem,string fileName) { _ftpUpItem = ftpUpItem; _ftpUri = string.Format(@"{0}:{1}/{2}", _ftpUpItem.FTPHost, _ftpUpItem.FTPPort,fileName); if (_request == null) { _request = CreateFtpWebRequest(); } } private FtpWebRequest CreateFtpWebRequest() { if (_request != null) return _request; Uri target = new Uri(_ftpUri); _request = (WebRequest.Create(target)) as FtpWebRequest; _request.Proxy = null; _request.UseBinary = true; _request.KeepAlive = false; _request.Method = WebRequestMethods.Ftp.UploadFile; _request.Credentials = new NetworkCredential(_ftpUpItem.FTPUserName, _ftpUpItem.FTPPwd); return _request; } public void BeginGetRequest(string ftpUploadFileName) { string fileName = ftpUploadFileName; FtpState state = new FtpState(); state.Request = _request; state.FileName = fileName; _waitObject = state.OperationComplete; _request.BeginGetRequestStream( new AsyncCallback(EndGetStreamCallback), state ); _waitObject.WaitOne(); if (state.OperationException != null) { //失败日志 _ftpLog.LogOpeFlag = OpeFlag.Error; _ftpLog.LogContent = string.Format("FTP upload file failed.Time is {0}.Rerson is {1}. FilePath:<#{2}#>", DateTime.Now.ToString("yyyy-MM-dd HH:mi:ss"), state.OperationException.Message, ftpUploadFileName); _ftpLog.WriteFtpLog(); } else { //成功日志 _ftpLog.LogOpeFlag = OpeFlag.Success; _ftpLog.LogContent = string.Format("FTP upload file Success.Time is {0}.FilePath:<#{1}#>", DateTime.Now.ToString("yyyy-MM-dd HH:mi:ss"), ftpUploadFileName); _ftpLog.WriteFtpLog(); } } private static void EndGetStreamCallback(IAsyncResult ar) { FtpState state = (FtpState)ar.AsyncState; Stream requestStream = null; // End the asynchronous call to get the request stream. try { requestStream = state.Request.EndGetRequestStream(ar); // Copy the file contents to the request stream. const int bufferLength = 2048; byte[] buffer = new byte[bufferLength]; int count = 0; int readBytes = 0; FileStream stream = File.OpenRead(state.FileName); do { readBytes = stream.Read(buffer, 0, bufferLength); requestStream.Write(buffer, 0, readBytes); count += readBytes; } while (readBytes != 0); // IMPORTANT: Close the request stream before sending the request. requestStream.Close(); stream.Close(); stream.Dispose(); // Asynchronously get the response to the upload request. state.Request.BeginGetResponse( new AsyncCallback(EndGetResponseCallback), state ); } // Return exceptions to the main application thread. catch (Exception e) { state.OperationException = e; state.OperationComplete.Set(); return; } } private static void EndGetResponseCallback(IAsyncResult ar) { FtpState state = (FtpState)ar.AsyncState; FtpWebResponse response = null; try { response = (FtpWebResponse)state.Request.EndGetResponse(ar); response.Close(); state.StatusDescription = response.StatusDescription; // Signal the main application thread that // the operation is complete. state.OperationComplete.Set(); } // Return exceptions to the main application thread. catch (Exception e) { state.OperationException = e; state.OperationComplete.Set(); } } public void Dispose() { if (_request != null) { _request.Abort(); _request = null; } if (_waitObject != null) { _waitObject.Close(); _waitObject.Dispose(); } } }}
采用异步上传。参考MSDN中FtpWebRequest类用法。
其中URI指定的时候,格式是:ftp://地址/文件。如果不是这个格式,在异步获取读取文件流是报指定格式不正确错误。
以上监控类和上传类完成,下面就开始做安装包。
制作安装包步骤:
1、在解决方案中新建安装项目FTPUploadServiceSetUp
2、在新建的安装项目FTPUploadServiceSetUp中添加项目输出
项目输出选择为主输出 。项目选择要运行的服务类。
3、为打包的安装程序添加需要的文件
在应用目录中添加程序运行需要的dll、exe和配置文件。上图FTPUploadComponent.dll文件是封装的类库,FTPUploadConfigs.config是FTP上传需要配置的参数设置,InstallUtil.exe是安装服务需要的组件,uninstall.bat是卸载服务需要的批处理文件。
4、添加用户界面
添加后就可以自定义安装过程中的自定义界面。
上图中Textboxes(B),是获取FTP配置数据。Textboxes(C) 是配饰要监控的目录文件和配置。
右键Textboxes(B)属性,如下图,就可以配置配置参数
5、添加自定安装类
新建类库SetUpLib,在类库中添加Installer Class类。
6、重复第二步,把新增的自定义类,在安装项目中添加为主输出。
7、配置自定义类参数
右键安装项目,在视图中添加自定义操作。之后,在安装项,右键添加自定操作,选择刚才项目主输出添加的内容。
右键自定义操作属性,可以看到CustomActionData属性。这个属性就是获取从自定义界面获取到的值。
CustomActionData是用空格隔开的键值对。
具体使用参见http://msdn.microsoft.com/zh-cn/library/2w2fhwzz(v=vs.80).aspx
8、自定安装类获取自定义界面输入的数据
查看,安装类代码,可以看到该类继承了 System.Configuration.Install.Installer类。此类中定义了安装前,安装后要实现的内容,此例中,我们只重写了OnAfterInstall类。在安装成功后,把从自定义界面输入的内容写到配置文件中。代码如下:
protected override void OnAfterInstall(IDictionary savedState) { base.OnAfterInstall(savedState); //host=[EDITB1] /port=[EDITB2] /username=[EDITB3] /pwd=[EDITB4] // /targetdir=[TARGETDIR] /DirPath=[DIRPATH] /SubDir =[SUBDIR] /ExeInt=[EXECUTEINTERVAL] //多值用空格隔开 采用/pwd=[EDITB4]这种新式作为一个键值对 List<string> values = new List<string>(); values.Add(Context.Parameters["host"].ToString()); values.Add(Context.Parameters["port"].ToString()); values.Add(Context.Parameters["username"].ToString()); values.Add(Context.Parameters["pwd"].ToString()); values.Add(Context.Parameters["TARGETDIR"].ToString().Replace(@"\\", @"\")); values.Add(Context.Parameters["DirPath"].ToString().Replace(@"\\", @"\")); values.Add(Context.Parameters["SubDir"].ToString()); values.Add(Context.Parameters["ExeInt"].ToString()); values.Add(Context.Parameters["WatFileType"].ToString()); //这里操作添加数据库,只要执行创建数据库的脚本就可以了。 //这个是测试在安装目录下添加接收到的用户填写的数据库信息 try { WriteConfig(values); ExecBat(values[4], "install.bat"); } catch(Exception ex) { File.AppendAllText(Path.Combine(values[4], "log.txt"),ex.Message); } }
代码中获取数据,参数名称对应的就是CustomActionData属性中配置的名称。WriteConfig就是把界面中的数据写入到配置文件中,ExecBat执行服务安装并启动服务。
生成安装项目。打包程序完成。
安装测试:
1、安装目录
改值可以通过/targetdir=[TARGETDIR]获取。
2、FTP参数配置
3、监控目录配置
服务安装包安装完成。
在很多项目中,我们需要在安装的过程中还原数据库,下一篇讨论如何在安装包中执行过程中还原sql Server数据库。
- C# Windows 服务安装并运行服务
- 使用C#代码安装 Windows 服务--直接运行安装服务
- C# 安装 Windows 服务
- C#编写Windows服务并安装与启动
- C#创建windows服务程序,并制作windows服务安装包。
- 安装C# Windows服务程序
- 安装C# Windows服务程序
- C# Windows服务程序安装
- C# Windows 服务开发并启动
- c#创建windows服务步骤并打包
- C#创建windows服务并定时执行
- C#创建windows服务并定时执行
- C#对Windows服务操作(注册安装服务,卸载服务,启动停止服务,判断服务存在)
- Zookeeper以Windows服务安装运行
- 实现Windows服务并安装,控制
- windows下安装并启动redis服务
- 安装openoffice,并配置windows服务
- windows下安装设置Nginx+python+flup+django,并设为服务运行!
- 命令行参数argv传递整数给函数的方法
- CSS HACK 解决兼容的写法
- Twitter Storm开篇之作
- Web开发必备的43款可视化工具
- ZBarSDK支持armv7s
- C# Windows 服务安装并运行服务
- 微博翻页功能
- igbinary 与 php serialize 与 json_encode比较
- libsvm使用中的参数问题(选择最优参数)
- Java synchronized详解
- 转载一篇ClickOnce的文章!
- Web搜索中的用户意图的自动识别
- github添加fork的别人的仓库
- Linux环境变量的修改(永久,暂时)