C# 写一个简单的Windows服务

来源:互联网 发布:mac ruby sass 编辑:程序博客网 时间:2024/05/22 20:11

在VS中新建一个项目 Visual C#->Windows->经典桌面->Windows服务
大致功能:一个socket服务端,收到客户端的请求后,随机从txt读取一行发送到客户端

新建一个QuoteService的服务
用到的类
QuoteServer.cs

using System;using System.Collections.Generic;using System.Diagnostics;using System.Diagnostics.Contracts;using System.IO;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading.Tasks;namespace Wrox.ProCSharp.WinServices{  public class QuoteServer  {    private TcpListener listener;    private int port;    private string filename;    private List<string> quotes;    private Random random;    private Task listenerTask;    public QuoteServer()      : this("quotes.txt")    {    }    public QuoteServer(string filename)      : this(filename, 7890)    {    }    public QuoteServer(string filename, int port)    {      Contract.Requires<ArgumentNullException>(filename != null);      Contract.Requires<ArgumentException>(port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort);      this.filename = filename;      this.port = port;    }    protected void ReadQuotes()    {      try      {        quotes = File.ReadAllLines(filename).ToList();        if (quotes.Count == 0)          throw new QuoteException("quotes file is empty");        random = new Random();      }      catch (IOException ex)      {        throw new QuoteException("I/O error", ex);      }    }    protected string GetRandomQuoteOfTheDay()    {      int index = random.Next(0, quotes.Count);      return quotes[index];    }    public void Start()    {      ReadQuotes();      listenerTask = Task.Factory.StartNew(Listener, TaskCreationOptions.LongRunning);    }    protected void Listener()    {      try      {        IPAddress ipAddress = IPAddress.Any;        listener = new TcpListener(ipAddress, port);        listener.Start();        while (true)        {          Socket clientSocket = listener.AcceptSocket();          string message = GetRandomQuoteOfTheDay();          var encoder = new UnicodeEncoding();          byte[] buffer = encoder.GetBytes(message);          clientSocket.Send(buffer, buffer.Length, 0);          clientSocket.Close();        }      }      catch (SocketException ex)      {        Trace.TraceError(String.Format("QuoteServer {0}", ex.Message));        throw new QuoteException("socket error", ex);      }    }    public void Stop()    {      listener.Stop();    }    public void Suspend()    {      listener.Stop();    }    private void StopListener()    {    }    public void Resume()    {      Start();    }    public void RefreshQuotes()    {      ReadQuotes();    }  }}

QuoteService.cs

using System;using System.ServiceProcess;using System.IO;namespace Wrox.ProCSharp.WinServices{    public partial class QuoteService : ServiceBase    {        private QuoteServer quoteServer;        public QuoteService()        {            InitializeComponent();        }        protected override void OnStart(string[] args)        {            quoteServer = new QuoteServer(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "quotes.txt"), 5678);            quoteServer.Start();        }        protected override void OnStop()        {            quoteServer.Stop();        }        protected override void OnContinue()        {            base.OnContinue();        }        protected override void OnPause()        {            base.OnPause();        }        public const int commandRefresh = 128;        protected override void OnCustomCommand(int command)        {            switch (command)            {                case commandRefresh:                    quoteServer.RefreshQuotes();                    break;                default:                    break;            }        }    }}

项目中还需要添加ProjectInstaller

ProjectInstaller.Designer.cs

namespace Wrox.ProCSharp.WinServices{    partial class ProjectInstaller    {        /// <summary>        /// Required designer variable.        /// </summary>        private System.ComponentModel.IContainer components = null;        /// <summary>         /// Clean up any resources being used.        /// </summary>        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>        protected override void Dispose(bool disposing)        {            if (disposing && (components != null))            {                components.Dispose();            }            base.Dispose(disposing);        }        #region Component Designer generated code        /// <summary>        /// Required method for Designer support - do not modify        /// the contents of this method with the code editor.        /// </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;      //       // serviceInstaller1      //       this.serviceInstaller1.Description = "Professional C# Sample Service";      this.serviceInstaller1.DisplayName = "Quote Service";      this.serviceInstaller1.ServiceName = "QuoteService";      //       // ProjectInstaller      //       this.Installers.AddRange(new System.Configuration.Install.Installer[] {            this.serviceProcessInstaller1,            this.serviceInstaller1});        }        #endregion        private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;        private System.ServiceProcess.ServiceInstaller serviceInstaller1;    }}

项目生成后安装服务
以管理员身份打开cmd命令窗口
1.进入installutil.exe所在的目录
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319

2.使用installutil.exe安装服务
InstallUtil e:\MyFirstService\bin\release\QuoteService.exe

3.卸载服务
InstallUtil /u e:\MyFirstService\bin\release\QuoteService.exe

安装服务后.在服务列表用手动,启动QuoteService服务

测试用客户端
QuoteClient(wpf程序)

MainWindow.xaml

<Window x:Class="Wrox.ProCSharp.WinServices.QuoteClientWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="Quote Of The Day" Height="200" Width="300">  <Grid>    <Grid.RowDefinitions>      <RowDefinition Height="*" MinHeight="30" />      <RowDefinition Height="3*" />    </Grid.RowDefinitions>    <Button Margin="3" VerticalAlignment="Stretch" Grid.Row="0" IsEnabled="{Binding EnableRequest}"  Click="OnGetQuote">Get Quote</Button>    <TextBlock Margin="6" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Quote}" />  </Grid></Window>

MainWindow.xaml.cs

using System;using System.Net.Sockets;using System.Text;using System.Windows;using System.Windows.Input;namespace Wrox.ProCSharp.WinServices{  /// <summary>  /// Interaction logic for Window1.xaml  /// </summary>  public partial class QuoteClientWindow : Window  {    private QuoteInformation quoteInfo = new QuoteInformation();    public QuoteClientWindow()    {      InitializeComponent();      this.DataContext = quoteInfo;    }    private async void OnGetQuote(object sender, RoutedEventArgs e)    {      const int bufferSize = 1024;      Cursor currentCursor = this.Cursor;      this.Cursor = Cursors.Wait;      quoteInfo.EnableRequest = false;      string serverName = Properties.Settings.Default.ServerName;      int port = Properties.Settings.Default.PortNumber;      var client = new TcpClient();      NetworkStream stream = null;      try      {        await client.ConnectAsync(serverName, port);        stream = client.GetStream();        byte[] buffer = new Byte[bufferSize];        int received = await stream.ReadAsync(buffer, 0, bufferSize);        if (received <= 0)        {          return;        }        quoteInfo.Quote = Encoding.Unicode.GetString(buffer).Trim('\0');      }      catch (SocketException ex)      {        MessageBox.Show(ex.Message, "Error Quote of the day",              MessageBoxButton.OK, MessageBoxImage.Error);      }      finally      {        if (stream != null)        {          stream.Close();        }        if (client.Connected)        {          client.Close();        }      }      this.Cursor = currentCursor;      quoteInfo.EnableRequest = true;    }  }}

Properties
ServerName string 用户 localhost
PortNumber int 用户 5678

QuoteInformation.cs

using System.Collections.Generic;using System.ComponentModel;using System.Runtime.CompilerServices;namespace Wrox.ProCSharp.WinServices{  public class QuoteInformation : INotifyPropertyChanged  {    public QuoteInformation()    {      EnableRequest = true;    }    private string quote;    public string Quote    {      get      {        return quote;      }      internal set      {        SetProperty(ref quote, value);      }    }    private bool enableRequest;    public bool EnableRequest    {      get      {        return enableRequest;      }      internal set      {        SetProperty(ref enableRequest, value);      }    }    private void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = "")    {      if (!EqualityComparer<T>.Default.Equals(field, value))      {        field = value;        var handler = PropertyChanged;        if (handler != null)        {          handler(this, new PropertyChangedEventArgs(propertyName));        }      }    }    public event PropertyChangedEventHandler PropertyChanged;  }}

在服务开启后.运行客户端点击按钮就可以看到效果了

quote.txt
“640K ought to be enough for everybody”, Bill Gates, 1981
“This ‘telephone’ has too many shortcomings to be seriously considered as a means of communication. The device is inherently of no value to us.”, Western Union internal memo, 1876
“Computer in the future may weigh no more than 1.5 tones.”, Popular Mechanics, forecasting the relentless march of science, 1949
“There is no reason anyone would want a computer in their home.”, Ken Olsen, Digital Equipment Corp., 1977
“I think there is a world market for maybe five computers”, T. Watson, Chairman of IBM, 1943
“But what is it good for?”, IBM commenting on the development of the Microchip.
“We will think about software more as a service than we have in the past.”, Bill Gates, Microsoft Chief Software Architect, 2000
“Landing and moving around on the moon offer so many serious problems for human beings that it may take science another 200 years to lick them” Lord Kelvin, (1824-1907)
“X-rays are a hoax”, Lord Kelvin (1824-1907)
“Radio has no future”, Lord Kelvin (1824-1907)
“Heavier than air flying machines are impossible” Lord Kelvin (1824-1907)
“In the decade ahead I can predict that we will provide over twice the productivity improvement that we provided in the ’90s.”, Bill Gates
“I don’t think there’s anything unique about human intellience. All the nuerons in the brain that make up perceptions and emotions operate in a binary fashion.”, Bill Gates
“I’m sorry that we have to have a Washington presence. We thrived during our first 16 years without any of this. I never made a political visit to Washington and we had no people here. It wasn’t on our radar screen. We were just making great software.”, Bill Gates
“The reason you see open source there at all is because we came in and said there should be a platform that’s identical with millions and millions of machines.”, Bill Gates

原创粉丝点击