I have a simple TCP server written in C# with Visual Studio. Everything works fine unless ran as a Windows Service in which I get the 1053 error. I narrowed it down to the TCP listener parts because when I comment them out the service starts just fine. Here is the code I keep in Service1.cs:
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 System.Net.Sockets;
using System.IO;
using System.Text.RegularExpressions;
namespace Vegas_Remote_Render_Server
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
var defaultwaittime = "20";
int defaultport = 1302;
TcpListener listener = new TcpListener(System.Net.IPAddress.Any, defaultport);
listener.Start();
while (true)
{
Console.WriteLine("Waiting for a connection.");
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Client accepted.");
NetworkStream stream = client.GetStream();
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
try
{
byte[] buffer = new byte[1024];
stream.Read(buffer, 0, buffer.Length);
int recv = 0;
foreach (byte b in buffer)
{
if (b != 0)
{
recv++;
}
}
string request = Encoding.UTF8.GetString(buffer, 0, recv);
string formattedrequest = Regex.Replace(request, @"^\s*$\n|\r", string.Empty, RegexOptions.Multiline).TrimEnd();
Console.WriteLine(request);
Console.WriteLine("request received");
sw.WriteLine("request received");
string[] splitrequest = request.Split('|');
var projectpath = "";
var parameternumber = 0;
var waittime = defaultwaittime;
foreach (string value in splitrequest)
{
parameternumber = parameternumber + 1;
if (parameternumber == 1)
{
projectpath = value;
}
if (parameternumber == 2)
{
waittime = value;
}
}
if (formattedrequest != "killrender")
{
Console.WriteLine(projectpath);
Console.WriteLine(waittime);
System.Diagnostics.Process.Start(@"render.bat", $"\"{projectpath}\" \"{waittime}\"");
sw.Flush();
}
if (formattedrequest == "killrender")
{
Console.WriteLine("killing instances");
System.Diagnostics.Process.Start(@"kill.bat");
}
}
catch (Exception e)
{
Console.WriteLine("Something went wrong.");
sw.WriteLine(e.ToString());
}
}
}
protected override void OnStop()
{
}
}
}
To simplify the script, here is only the TCP listener parts:
static void Main(string[] args)
{
TcpListener listener = new TcpListener(System.Net.IPAddress.Any, defaultport);
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
}
}
I've also tried many solutions in other posts about this issue with the service. This includes exporting the .exe from visual studio as Release instead of Debug, commenting the console.WriteLine commands that I used while debugging, and removing the while(true). My Visual Studio Project also uses the project template "Windows Service C#"
I have heard that you can make registry edits to give the service more time, but I would rather not use that solution. The service works for the amount of time before it is deemed "unresponsive". I am stuck trying to find what part of the TCP listener is doing this.
Thanks in advance, I'm still kind of a Newbie with C#
1053 error states:
The service did not respond to the start or control request in a timely fashion.
This error message is the cause of a timeout that occurs after a request was initiated to start a service but it did not respond in the time window.
Response in your case is exiting OnStart()
method. You use while(true)
which is in many cases quite error prone. I suspect your service just enters the loop and ever exits because AcceptTcpClient is !blocking! operantion:
AcceptTcpClient is a blocking method that returns a TcpClient that you can use to send and receive data. Use the Pending method to determine if connection requests are available in the incoming connection queue if you want to avoid blocking.
You need to move your routine of handling clients out of the OnStart
method to do not block it, just move it to the separate thread.
Don't forget to Stop() TcpListener on service stop.