Windows service starting, but stopping immediately without errors after OnStart() - c#

I've recently converted a TCP-port listening application into a Windows Service, which installs and runs perfectly on my 32bit Vista laptop.
The problem was, after its installation, which works, I attempted to run the service(through Remote Dekstop) on a 64bit Win7 and it neatly handed me an error 1053, basically stating that the service timed out while starting up.
Now I've gotten it to start up without errors, but all it does is exit immediately without any errors or any eventLogging past OnStart.
I've tried replacing my Timer with Threading to see if that might have been the issue with the strange start, but no luck there... Here's the OnStart method of the service and the method that is meant to run continously.
protected override void OnStart(string[] args)
{
myServer.Start();
eventLog1.WriteEntry("Server started.");
mWorker = new Thread(StartUp);
eventLog1.WriteEntry("Starting up CykelScore service.");
mWorker.Start();//Start the service
//timer.Start(); // Start the timer
}
private void StartUp(object arg)
{
while (true)
{
eventLog1.WriteEntry("Running.");
if (mStop.WaitOne(10000)) return;
{
if (Monitor.dataCount > 0)
{
string tmp = "";
eventLog1.WriteEntry("Antal tags: " + Monitor.dataCount.ToString());
lockedUp.WaitOne();
try
{
tmp = Monitor.PopData();
}
catch (Exception ex)
{
eventLog1.WriteEntry("Fejl:" + ex.ToString());
}
eventLog1.WriteEntry("Recieved: " + tmp);
string buffer = tmp;
string antenna = (buffer.Split(',')[0]).Replace(" ", "");
string time = buffer.Split(',')[2];
string RFIDNR = (buffer.Split(',')[1]).Replace(" ", "");
string[] ART = new string[3];
ART[0] = antenna;
ART[1] = RFIDNR;
ART[2] = time;
if (lastreceivedtagID == RFIDNR)
{
eventLog1.WriteEntry("Same tag as last time. No need to check database");
}
else
{
if (!DataHandler.LoggedInCurrentTimespan(ART))
{
try
{
DataHandler.SaveToLocal(ART);
eventLog1.WriteEntry("Data saved to local database");
DataHandler.SendToRemote(tmp, Monitor.server, Monitor.database, Monitor.username, Monitor.password);
eventLog1.WriteEntry("Data sent to remote database");
}
catch (Exception ex)
{
eventLog1.WriteEntry("Fejl" + ex.ToString());
}
}
else
eventLog1.WriteEntry("Discarding data. Already in local database");
}
lastreceivedtagID = RFIDNR;
lockedUp.ReleaseMutex();
}
}
}
}
Does anyone have any idea what might be the issue?

Related

Closing a USB serial port leaves the port unavailable

My app uses USB based serial ports to connect to physical hardware devices. I can open any valid USB port and communicate with the external devices. However, when I close the connection, the USB port is left in some sort of indeterminate state for some time, and during that time further attempts to reconnect result in the "Access to port "COM--" is denied" error. However, after some few seconds, attempting to reconnect is successful. How can I determine WHEN the USB port will again support a new connection?
The code looks like this:
private void Setup(string Port)
{
bool ValidPort = false;
int CloseSleep = 10;
_PortName = Port;
_PortType = this;
string[] AvailablePorts = SerialPort.GetPortNames();
foreach(string aPort in AvailablePorts)
{
if (aPort == _PortName)
{
// The required port is listed in the list of available ports)
ValidPort = true;
break;
}
}
if (ValidPort)
{
try
{
if (_ThePort != null)
{
_ThePort.Close();
_ThePort.DataReceived -= ReceivedDataEventHandler;
while(CloseSleep-- > 0)
System.Threading.Thread.Sleep(100);
_ThePort.Dispose();
_ThePort = null;
}
}
catch (Exception ex)
{
EMS_Config_Tool.ModalDialog md = new EMS_Config_Tool.ModalDialog("Closing Port: " + ex.Message, "System Exception");
md.ShowDialog();
}
System.IO.Ports.SerialPort TheNewPort = new System.IO.Ports.SerialPort(Port, 38400);
// Setup the event handlers from Tx and Rx
Handler.DataOutEvent += CommsSender;
TheNewPort.DataReceived += ReceivedDataEventHandler;
TheNewPort.DataBits = 8;
TheNewPort.Parity = Parity.None;
TheNewPort.Handshake = System.IO.Ports.Handshake.None;
TheNewPort.StopBits = System.IO.Ports.StopBits.One;
// We will try 3 times to open the port, and report an error if we fail to open the port
try
{
TheNewPort.Open();
}
catch (Exception)
{
System.Threading.Thread.Sleep(1000);
try
{
TheNewPort.Open();
}
catch (Exception)
{
System.Threading.Thread.Sleep(1000);
try
{
TheNewPort.Open();
}
catch (Exception ex)
{
EMS_Config_Tool.ModalDialog md = new EMS_Config_Tool.ModalDialog("Opening Port: " + ex.Message, "System Exception");
return;
}
}
}
The final catch statement is where the error about Access being denied is issued. Note my attempt to retry opening the port 3 times doesn't really help. If I leave the port alone for about 5 to 10 seconds and retry calling the Setup method it succeeds immediately.
As #Neil said, there are many issues. The best thing to do, in my point of view, is to put the search in a loop, and as soon as the port can be opened, it will be.
I used to do like this :
public Task WaitingPort()
{
while (port is null)
{
port = CheckPort();
}
}
private SerialPort CheckPort()
{
string[] listPort = SerialPort.GetPortNames();
foreach(string namePort in listPort)
{
SerialPort port = new SerialPort(namePort, 9600);
if (!port.IsOpen)
{
try
{
port.Open();
port.ReadTimeout = 1500;
string data = port.Readline();
// I programmed my device to send an "A" until it receives
// "777" to be able to recognize it once opened
if (data.Substring(0, 1) == "A")
{
port.ReadTimeout = 200;
port.Write("777"); // to make it stop sending "A"
return port;
}
else
{
port.Close();
}
}
catch (Exception e1)
{
port.Close();
}
}
}
return null;
}
Of course, this is just some kind of a template which you have to reshape to your use
I have amended my code to use a constrained loop to give it a better chance to work, which it usually does. I was hoping that there was a better way to do it, as I tend to have pretty impatient users who will be posting defect reports if they have to wait 5 or 10 seconds to make a connection....
// We will try several times to open the port, upto 10 times over 5 seconds, and report an error if we finally fail to open the port
try
{
TheNewPort.Open();
}
catch (Exception ex)
{
RetryOpenTimer.Interval = 500;
RetryCount = 10;
RetryOpenTimer.Elapsed += new System.Timers.ElapsedEventHandler(RetryOpenTimer_Elapsed);
WaitForOpen = true;
RetryOpenTimer.Start();
while (WaitForOpen && RetryCount > 0)
{
System.Threading.Thread.Sleep(500);
}
if (WaitForOpen)
{
EMS_Config_Tool.ModalDialog md = new EMS_Config_Tool.ModalDialog("Opening Port: " + ex.Message, "System Exception");
return;
}
}
...
void RetryOpenTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
RetryOpenTimer.Stop();
RetryOpenTimer.Elapsed -= RetryOpenTimer_Elapsed;
try
{
if (RetryCount-- > 0)
{
TheNewPort.Open();
WaitForOpen = false;
}
else
return;
}
catch (Exception)
{
RetryOpenTimer.Start();
RetryOpenTimer.Elapsed += RetryOpenTimer_Elapsed;
}
}

C# - Signalr client connection is causing performance issue Windows Service

Signalr client code is causing performance issue is Windows Service. Windows service is acting as signalr client.
What we are trying to do:
Windows service is having one timer, which executes the method(ConnectToSignalRServer). If somehow the connection gets closed, there is one event (Connection.Closed += Connection_Closed), which will again try to establish the connection by calling the method(ConnectToSignalRServer). A while loop is being used in the event (Connection.Closed += Connection_Closed) to try reconnecting.
Please find the sample code below and let me know if any issues with the code.
private static HubConnection Connection = null;
//When the service starts, this method would be called.
public static bool ConnectToSignalRServer()
{
try
{
string Url = "http://www.samplesignalrserver.com";
Connection = new HubConnection(Url);
var myHub = Connection.CreateHubProxy("SignalHub");
Connection.Start().ContinueWith(task =>
{
if (task.IsFaulted)
{
}
else
{
Connection.Closed += Connection_Closed;
}
}).Wait();
//Method(RequestData) would be called upon receiveng message from server
myHub.On<string>("GetMessgeFromServer", type =>
{
Task.Run(() => RequestData(type));
});
//Method(GetHostName) would be called in server
myHub.Invoke<string>("GetHostName", BLConstants.strHostName);
return true;
}
catch (Exception ex)
{
//capturing Stacktrace and Message from ex object
}
return false;
}
//Establish the connection, if the the connection would be closed
private static void Connection_Closed()
{
try
{
while (true)
{
Thread.Sleep(10000);
bool connected = ConnectToSignalRServer();
if (connected)
{
break;
}
}
}
catch (Exception ex)
{
//capturing Stacktrace and Message from ex object
}
}

QueueClient.OnMessage throws StackOverflowException during Worker Role Start up

I am trying to deploy my first Azure worker role and I have been running into this error when Run() method is called during service start up.
An unhandled exception of type 'System.StackOverflowException' occurred in Unknown Module.
I've tried to remote debug my code and the error is thrown at this line. MyPublisher is similar to MyQueue but it wraps Topic instead of a Queue. Any idea why QueueClient.OnMessage would cause StackOverflow?
Client.OnMessage(messageHandler, options);
Here is the partial code. My Apology if it is not formatted correctly (will try to format) or anything is missing in code.
public class MyQueue
{
String QueueName;
public QueueClient Client { get; protected set; }
public MyQueue(String queueName)
{
Trace.WriteLine($"Creating service Queue with name : {queueName} ");
QueueName = queueName;
}
public void EstableshConnection(string connectionString = null)
{
Trace.WriteLine($"Establishing connection with service Queue : {QueueName} ");
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
connectionString = connectionString ?? CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
if (!namespaceManager.QueueExists(QueueName))
namespaceManager.CreateQueue(QueueName);
Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
}
public void Send(BrokeredMessage message)
{
Trace.WriteLine($"Sending brokered message to queue : {QueueName} ");
if (Client != null && !Client.IsClosed)
Client.Send(message);
}
public void OnMessage(Action<BrokeredMessage> messageHandler)
{
Trace.WriteLine($"OnMessage handler: Queue Name : {QueueName} ");
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = true; // Indicates if the message-pump should call complete on messages after the callback has completed processing.
options.MaxConcurrentCalls = 1; // Indicates the maximum number of concurrent calls to the callback the pump should initiate
options.ExceptionReceived += LogErrors; // Allows users to get notified of any errors encountered by the message pump
//=====================StackOverFlowException on Client.OnMessage======
if (Client != null && !Client.IsClosed)
Client.OnMessage(messageHandler, options); //This is where I get StackOverflowException Error.
}
private void LogErrors(object sender, ExceptionReceivedEventArgs e)
{
if (e.Exception != null)
Trace.WriteLine("Queue client processing error: " + e.Exception.Message);
}
public void Disconnect()
{
Trace.WriteLine($"closing queue {QueueName}");
Client.Close();
}
}
Here is my workerrole implementation.
public class MyWorkerRole : RoleEntryPoint
{
#region Variables
ManualResetEvent CompletedEvent = new ManualResetEvent(false);
MyQueue RequestQueue; //for Request
MyPublisher ResponseTopicClient; //ReponseTopic to notify Subscriber when processing is completed
Public MyWorkerRole()
{
RequestQueue = new MyQueue("JobRequestQueue");
ResponseTopicClient = new MyPublisher("JobCompletedTopic");
}
public override bool OnStart()
{
try
{
RequestQueue.EstableshConnection();
ResponseTopicClient.EstableshConnection();
}
catch (Exception ex)
{
Trace.TraceWarning($"Trace: starting service failed. Error {ex.Message} ");
}
return base.OnStart();
}
public override void OnStop()
{
try
{
RequestQueue.Disconnect();
ResponseTopicClient.Disconnect();
CompletedEvent.Set();
}
catch (Exception ex)
{
Trace.TraceWarning($"Trace: stopping service failed with error. {ex.Message} ");
}
base.OnStop();
}
public override void Run()
{
try
{
Trace.WriteLine("Trace: Starting Message Processing");
//var receivedMessage2 = RequestQueue.Client.Receive(new TimeSpan(hours: 0, minutes: 2, seconds: 0));
RequestQueue.OnMessage((receivedMessage) =>
{
try
{
Guid resultGuid = (Guid)receivedMessage.Properties["CorrelationGuid"];
Trace.TraceWarning($"Trace: processing message with GUID {resultGuid}");
var messageToSend = JobProcessor.ProcessRequest(receivedMessage);
if (messageToSend == null)
{
Trace.TraceError("Trace: > Broken message!");
receivedMessage.Abandon();
return;
}
ResponseTopicClient.Send(messageToSend);
receivedMessage.Complete();
}
catch (Exception ex)
{
Trace.TraceError("Trace: Processing exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
Logger.Error("Processing exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
}
});
CompletedEvent.WaitOne();
}
catch (Exception ex)
{
Trace.TraceError("Trace: Run exception: " + ex.Message + "\nStack Trace" + ex.StackTrace);
}
finally
{
CompletedEvent.Set();
}
}
}
When your worker starts, it calls the Run method and in your code, you have :
//var receivedMessage2 = RequestQueue.Client.Receive(new TimeSpan(hours: 0, minutes: 2, seconds: 0));
RequestQueue.OnMessage((receivedMessage) =>
So, The code doesn't wait for a new message because the first line is commented and it calls the OnMessage method which recursibly calls itself again and again till the StackOverflowException gets fired
In all cases, you need to change the implementation because StackOverflowException will happen anyway when a new message is received
Figured it out. So, the issue was not with the code. Following error was reported in WADWindowsEventLogsTable under my storage account.
Faulting application name: WaWorkerHost.exe, version: 2.7.1198.768, time stamp: 0x57159090
Faulting module name: Microsoft.IntelliTrace.Profiler.SC.dll, version: 15.0.27128.1, time stamp: 0x5a1e2eb9
Exception code: 0xc00000fd
Fault offset: 0x000000000008ae7b
Faulting process id: 0xcf4
Faulting application start time: 0x01d3b75ed89dc2f9
Faulting application path: F:\base\x64\WaWorkerHost.exe
Faulting module path: F:\plugins\IntelliTrace\Runtime\x64\Microsoft.IntelliTrace.Profiler.SC.dll
This gave me a hint about disabling the IntelliTrace and it worked just fine. Here is how you can disable while publishing a package through VS 2017.
1.) Right click on your worker role project and select publish from menu
2.) In Settings page->Advanced Settings, uncheck "Enable IntelliTrace" option.

How do I impersonate a server with Fiddler core?

I'm trying to debug an app without setting fiddler as its proxy.
To do this, I've setup fiddler.core based app that resides on an other computer in the network and added an entry to hosts file.
Here's the app's code:
private static Proxy googleEndpoint;
static void Main(string[] args)
{
List<Fiddler.Session> oAllSessions =new List<Session>();
Fiddler.FiddlerApplication.BeforeRequest += (i) => Console.WriteLine("Before request: "+i.fullUrl);
FiddlerApplication.AfterSessionComplete += (i) =>
{
Console.WriteLine("After request: "+i.fullUrl);
lock (oAllSessions)
{
oAllSessions.Add(i);
}
};
//https://www.google.com.ua/
googleEndpoint = FiddlerApplication.CreateProxyEndpoint(443, true, "www.google.com.ua");
if (null != googleEndpoint)
{
Console.WriteLine("google.com.ua endpoint mounted");
}
else
{
Console.WriteLine("failed to mount google.com.ua endpoint");
}
Console.ReadKey();
SaveSessionsToDesktop(oAllSessions);
}
private static void SaveSessionsToDesktop(List<Fiddler.Session> oAllSessions)
{
bool bSuccess = false;
string sFilename = DateTime.Now.ToString("hh-mm-ss") + ".saz";
try
{
try
{
Monitor.Enter(oAllSessions);
TranscoderTuple oExporter = FiddlerApplication.oTranscoders.GetExporter("SAZ");
if (null != oExporter)
{
Dictionary<string, object> dictOptions = new Dictionary<string, object>();
dictOptions.Add("Filename", sFilename);
// dictOptions.Add("Password", "pencil");
bSuccess = FiddlerApplication.DoExport("SAZ", oAllSessions.ToArray(), dictOptions, null);
}
else
{
Console.WriteLine("Save failed because the SAZ Format Exporter was not available.");
}
}
finally
{
Monitor.Exit(oAllSessions);
}
WriteCommandResponse(bSuccess ? ("Wrote: " + sFilename) : ("Failed to save: " + sFilename));
}
catch (Exception eX)
{
Console.WriteLine("Save failed: " + eX.Message);
}
}
public static void WriteCommandResponse(string s)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(s);
Console.ForegroundColor = oldColor;
}
but when I'm trying to access https://www.google.com.ua from the target machine, the requests now time out.
Fiddler app shows that it has recieved the request in the BeforeRequest event, but it never sends a reply (AfterSessionComplete never gets called).
Why does this happen and how can I fix it?
How do I do the same for port 80?
I trust you're keeping in mind the fact that, unless you reconfigure the client to trust the FiddlerServer's root certificate, it will not issue a HTTPS request to FiddlerCore. It will instead immediately close the connection upon getting the interception certificate.
What do you see if you attach a BeforeResponse event handler? Does it fire?

Belgium Identity Card feature crashes on IIS W3WP.exe

My registration tool has a feature which allows candidates to load their personal information (like name, address, ..) from an ID.
When I compile the application with the build-in webserver in VS2010, and press the button to load ID information into textboxes, there is no problem. When I publish it on the localhost (with IIS), it crashes when I press the button.
This is what I received in my event viewer:
0
APPCRASH
Not available
0
w3wp.exe
7.5.7601.17514
4ce7a5f8
KERNELBASE.dll
6.1.7601.17651
4e211319
e0434352
0000b9bc
0
7e796e20-f3e1-11e0-8ea3-60eb69b01829
0
I'm working on a 64-bit laptop, use the Belgium Identity Card SDK.
Here you can find my code for the button;
protected void Button1_Click(object sender, EventArgs e)
{
//READ eID
ClearTextBoxes();
try
{
BEID_ReaderSet ReaderSet;
ReaderSet = BEID_ReaderSet.instance();
BEID_ReaderContext Reader;
Reader = ReaderSet.getReader();
bool bCardPresent = Reader.isCardPresent();
if (Reader.isCardPresent())
{
if (Reader.getCardType() == BEID_CardType.BEID_CARDTYPE_EID
|| Reader.getCardType() == BEID_CardType.BEID_CARDTYPE_FOREIGNER
|| Reader.getCardType() == BEID_CardType.BEID_CARDTYPE_KIDS)
{
try
{
Load_eid(Reader);
}
catch (Exception ex)
{
labelEx.Text = ex.Message;
}
}
else
{
labelEx.Text = "No valid card, please insert a valid IDcard";
}
}
else
{
labelEx.Text = "No IDcard found, please insert your card";
}
BEID_ReaderSet.releaseSDK();
}
catch (BEID_Exception ex)
{
BEID_ReaderSet.releaseSDK();
labelEx.Text = "No valid cardreader found, please connect a valid reader";
}
catch (StackOverflowException ex)
{
BEID_ReaderSet.releaseSDK();
labelEx.Text = "Error: " + ex;
}
catch (OutOfMemoryException ex)
{
BEID_ReaderSet.releaseSDK();
labelEx.Text = "Error: " + ex;
}
}
private void Load_eid(BEID_ReaderContext Reader)
{
try {
BEID_EIDCard card;
card = Reader.getEIDCard();
if (card.isTestCard())
{
card.setAllowTestCard(true);
}
BEID_EId doc;
doc = card.getID();
txtFirstN.Text = doc.getFirstName();
txtLastN.Text = doc.getSurname();
txtDOB.Text = doc.getDateOfBirth();
//CUT GETSTREET IN STREET AND HOUSENO
string street= doc.getStreet();
string[] words = street.Split(' ');
txtStreet.Text = words[0];
txtHouseNo.Text = words[1];
txtPostalCode.Text = doc.getZipCode();
txtCity.Text = doc.getMunicipality();
//sText += "Country = " + doc.getCountry() + "\r\n";
}
catch (Exception ex)
{
BEID_ReaderSet.releaseSDK();
labelEx.Text = "Error: " + ex;
}
}
How can I solve this problem?
Most likely your Application Pool is running under a user which does not have a privilege to access the card reader. This would cause a driver fault which can crash the w3wp.exe process.
Change it to a dedicated user and assign appropriate privileges for this user, or for testing purposes, set it to run under localsys.
Move your code to Javascript (in the browser/html).
I don't think the IIS user has the permission to communicate with the ID reader API.

Categories

Resources