windows服务需要3种程序 :服务程序、服务控制程序、服务配置程序。
1:服务程序,包括主函数、service-main函数、处理程序。
服务控制管理器SCM(Service Control Manager)用于注册服务,于服务进行通信,它是windows系统的一部分。服务程序的直接关系者。
主函数向SCM注册一个service-main函数,service-main则主要向SCM注册一个处理程序。处理程序响应来自SCM的消息。
2:服务控制程序,主要向SCM发送消息,SCM响应这些消息(有些是SCM响应的,有些是注册在SCM特定服务的处理程序响应的),所以可以自定义一些消息。
3:服务配置程序,主要是环境、依赖关系、服务运行参数的配置。它主要和注册表打交到。
试了一下,服务里面直接弹出windows消息框是不可以的。有待研究。
1:服务程序,包括主函数、service-main函数、处理程序。
服务控制管理器SCM(Service Control Manager)用于注册服务,于服务进行通信,它是windows系统的一部分。服务程序的直接关系者。
主函数向SCM注册一个service-main函数,service-main则主要向SCM注册一个处理程序。处理程序响应来自SCM的消息。
2:服务控制程序,主要向SCM发送消息,SCM响应这些消息(有些是SCM响应的,有些是注册在SCM特定服务的处理程序响应的),所以可以自定义一些消息。
3:服务配置程序,主要是环境、依赖关系、服务运行参数的配置。它主要和注册表打交到。
下面进入代码阶段:
如果进程中只有一个服务就可以删除数组。如果有多个服务运行在一个进程中,且需要初始化多个服务的某些共享状态时,则初始化必须在run()方法之前完成
static void Main()
{
//ServiceBase[] ServicesToRun;
//ServicesToRun = new ServiceBase[]
//{
// new QuoteService()
//};
//ServiceBase.Run(ServicesToRun);
ServiceBase.Run(new QuoteService());
}
class QuoteServer
{
private TcpListener listener;
private int port;
private string filename;
private List<string> quotes;
private Random random;
private Thread listenerThread;
#region 构造函数
public QuoteServer()
: this("quotes.txt")
{
}
public QuoteServer(string str)
: this(str, 7890)
{
}
public QuoteServer(string str, int port)
{
this.filename = str;
this.port = port;
}
#endregion
#region 工具函数
protected void ReadQuotes()
{
quotes = File.ReadAllLines(filename).ToList();
random = new Random();
}
protected string GetRandomQuoteOfTheDay()
{
int index = random.Next(0, quotes.Count);
return quotes[index];
}
protected void ListenerThread()
{
try
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
listener = new TcpListener(ipAddress, port);
listener.Start();
while (true)
{
Socket clientSocket = listener.AcceptSocket();
string message = GetRandomQuoteOfTheDay();
UnicodeEncoding encoder = new UnicodeEncoding();
byte[] buffer = encoder.GetBytes(message);
clientSocket.Send(buffer, buffer.Length, 0); //服务端口一直在发送随机消息
clientSocket.Close();
}
}
catch (Exception ex)
{
Trace.TraceError(string.Format("QuotServer {0}", ex.Message));
}
}
#endregion
public void Start()
{
ReadQuotes();
listenerThread = new Thread(ListenerThread);
listenerThread.IsBackground = true;
listenerThread.Name = "Listener";
listenerThread.Start();
}
public void Stop()
{
listener.Stop();
}
public void Suspend()
{
listener.Stop();
}
public void Resume()
{
Start();
}
public void RefreshQuote()
{
ReadQuotes();
}
}
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()
{
quoteServer.Resume();
}
protected override void OnShutdown()
{
quoteServer.Stop();
}
protected override void OnPause()
{
quoteServer.Suspend();
}
private const int commandRefresh = 128;
protected override void OnCustomCommand(int command)
{
switch (command)
{
case commandRefresh:
quoteServer.RefreshQuote();
break;
default:
break;
}
}
}
客户端打开本机端口通信就可以了
private void OnGetQuote(object sender, RoutedEventArgs e)
{
const int bufferSize = 1024;
Cursor currentCursor = this.Cursor;
this.Cursor = Cursors.Wait;
string serverName = Properties.Settings.Default.ServerName;
int port = Properties.Settings.Default.PortNumber;
TcpClient client = new TcpClient();
NetworkStream stream = null;
try
{
client.Connect(serverName, port);
stream = client.GetStream();
byte[] buffer = new Byte[bufferSize];
int received = stream.Read(buffer, 0, bufferSize);
if (received <= 0)
{
return;
}
textQuote.Text = 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;
}
试了一下,服务里面直接弹出windows消息框是不可以的。有待研究。
就先到这里吧,谢谢。