I am trying to get a Visual Basic service to run.
Installing and uninstalling the service works perfectly, however, when trying to start the service via the task manager, the following error message is displayed:
Unable to start service
The operation could not be completed.
The service did not respond to the start or control request in a timely fashion.
In the Event Viewer, the following error messages are logged in regard to this:
A timeout was reached (30000 milliseconds) while waiting for the ABC service to connect.
The ABC service failed to start due to the following error:
The service did not respond to the start or control request in a timely fashion.
Trying to start the service via cmd using the following command:
net start "ABC"
...results in the following error message:
The service is not responding to the control function.
More help is available by typing NET HELPMSG 2186.
And unhelpfully, typing "NET HELPMSG 2186" only repeats the first half of the error message:
The service is not responding to the control function.
I've had a look at the source code of the service, but I'm not quite familiar with its architecture. However, I could identify a few functions that I feel may be relevant for the service, namely:
OnStart(String())
OnStop()
New()
From what I've gathered out of related threads thus far, the error message could possibly mean that the service does not have the proper functions to be addressed by the service control functions. Could this be the case here?
If not, what approach would you suggest for debugging this?
Additional Info (21-Jul-2018):
Here's what the OnStart method looks like:
Protected Overrides Sub OnStart(ByVal args() As String)
Dim log As ILogger = CommonObjectFactory.instance.buildLogger(LogName.ABCDSys).open("OnStart")
Dim oCallback As Threading.TimerCallback = Nothing
Try
Dim numTimeDuration As Integer = 30000
Try
'numTimeDuration = Convert.ToInt32(ABCDA.ABCProperties.Instance.GetValue("DTimer", "DSys", "5000"))
Dim config As IDServiceConfiguration = CommonObjectFactory.instance.buildConfigurationFactory().buildDSConfiguration()
numTimeDuration = config.DTimer
Catch ex As Exception
log.error(ex)
End Try
log.info("Setting up a " & numTimeDuration / 1000 & " second timer")
oCallback = New Threading.TimerCallback(AddressOf TimerEvent)
_timer = New System.Threading.Timer(oCallback, Nothing, numTimeDuration, numTimeDuration)
Catch ex As Exception
log.error(ex)
End Try
log.close()
log = Nothing
End Sub
As far as I know, this service should check documents every 30 seconds, and from what I can see in the code that'S what should happen.
However, when trying to start the service, it crashes immediately. Not after 30 seconds, but right away, even though the error message in the Event Log says "A timeout was reached (30000 milliseconds)". In fact, I had problems with this service before where it crashed after 30 seconds, but in all these cases it wrote a helpful error message in one of the logs. Now, not even the logs are created.
I wonder if something is wrong with the logging. That would be this line, right?
Dim log As ILogger = CommonObjectFactory.instance.buildLogger(LogName.ABCDSys).open("OnStart")
What would be the best way for me to debug this? Due to the company workflow, I can't test this on my development machine but have to run the entire code through TeamCity first before testing it on another machine, so I'm not sure how to handle debugging. Given hat the service crashes immediately, I don't even have time to attach a debugger to it. Is there a way to start it attached to a debugger?
You need to share the code, particularly in the OnStart() method. My guess is that this code is blocking or long-running. You have only 30 seconds to start or stop a service before Windows thinks a problem happened. The typical approach is to start a thread in OnStart and do the real business logic there.
Related
I am new to vb.net and have a project that I have made my first windows service. Now I have a function that retrieves a count of transactions. I would like to call that function and put the results in a text file. I can hard code a stream to put into the text file, but whenever I call the function, the services just crashes. Not errors just dies. What am I doing wrong?
I have tried coding the function inside of the service-nope
I coded the function in a separate class-Nope! dies when I call it
Private Sub BrowserMailSender(obj As Object, e As EventArgs)
Try
FileIO.WriteToFile("service is started:" + Now + vbNewLine)
My_Count() 'service dies here
FileIO.WriteToFile("end" + vbNewLine)
Catch ex As Exception
MsgBox(ex)
End Try
the function works if I call from the main project but I would like the service to run and save the data behind the scenes.
The call to MsgBox is at the root of the problem. A Windows Service runs in a context where it does not have the ability to present a User Interface to the user. You'll have to find another way to communicate errors, such as the Event Log or a log file.
Prior to Vista, the line between services and the user was permeable, partly because the OS wasn't yet designed to keep them isolated, and partly because most users ran with full administrative privileges all the time. From Vista forward, you have to work "in the dark".
There are ways present a UI to the user, and one of the answers here briefly mentions one of them. However, I would caution you against trying to present a UI at all. The main principle of a service is that it sits in the background and does things without requiring the user to interact with it. Presenting a UI for events that the user is not aware are happening at that moment is an asymmetrical relationship. It could block your service indefinitely when a user isn't expecting to have to interact with it to allow it to continue.
I have a C# program that is launching TShark.exe which is the background equivalent of WireShark. I would like to close all instances that I start. It appears to start just fine, run in the background and log network traffic to a file as it should. However, when I try to close it, I get a "No process is associated with this object." exception.
Here is how I'm starting the processes:
ProcessStartInfo processStartInfo = new ProcessStartInfo
{
Arguments = $"-i {nic} -t ad -w {GenerateLogPath(nic)}",
FileName = "\"C:\\Program Files\\Wireshark\\tshark.exe\"",
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false
};
WireSharkProcesses.Add(System.Diagnostics.Process.Start(processStartInfo));
I've tried several methods to close/kill these processes. First, I kept a list of all processes that I had started in my app and called the following on them without success:
process.CloseWindow();
process.Close();
process.Kill();
I kept getting the "No process is associated with this object." exception.
So, I used:
var processes = System.Diagnostics.Process.GetProcesses();
And got a list of all processes on my machine and looped through them and attempted to close those who's process name was "tshark" or "dumpcap". I attempted this with .CloseWindow(), .Close(), and .Kill() all of which failed and threw the above exception.
I even went into TaskManager and attempted to END TASK on them. They appeared to be removed, but upon closing and re-opening TaskManager, they magically reappeared. There are also now several instances of "tshark" and "dumpcap" that show up when I call GetProcesses(), but are not in the list of processes that Task Manager shows.
What am I missing here?? Short of rebooting my machine, how do I get these processes to exit? Is this just a wireshark problem, or a general problem with killing processes?
Are you using WinPcap or Npcap? If you're using WinPcap, you could try switching to Npcap and using that instead. See Gerald Comb's comment #32 on the recently closed Wireshark Bug 14701.
By the way, in case you weren't aware, tshark is capable of capturing on more than one interface at a time, so in theory only a single instance is required. I understand that this can sometimes cause reassembly problems though, so if that's what you're trying to avoid or if you just want to keep packets separated by interface, then yes, you'll have to start multiple instances.
Second question on here...
Basically I am having a problem with a Stackoverflow exception that is thrown in my program, and I literally have no idea on how to locate the cause..
I have a program which has a plugin system, and it's a program that utilizes TCP in order to send and receive data; Server-> Client. I am making a remote console plugin, and the problem occurs when I do the command 'tree'; the filesystem entries listing command. For the first few seconds everything goes alright; the commands are being outputted (sent from Client to server). The receiving packets event isn't thread safe, so in the API I've provided an invocation function (to invoke methods on the UI thread). So therefore on output, it will do the following:
Public Sub ClientReadPacket(Sender As IClient, Pipename As String, Values As Object())
Select Case DirectCast(Values(1), ConsoleCommands)
Case ConsoleCommands.Output
ServerGUI.Send(Sub() ConsoleOutput.AppendText(Values(2) & Environment.NewLine))
End Select
End Sub
As you can see, the ServerGUI is an interface that I have provided for plugin development. And in the actual program - in the class that implements the GUI interface, I get a stackoverflow exception right here:
Private Sub ISend(del As System.Threading.SendOrPostCallback) Implements IGUI.Send
UIThread.Send(del, Nothing)
End Sub ' The break point is here; I assume that means that the exception ocurs in the line above.
The UIThread object is a synchronizationcontext of the main thread.
http://i.gyazo.com/870d9667f2272969b650cea836adca50.png
Update: So far I've narrowed it down to the following; it must be causing stackoverflow exception when calling SynchronizationContext.Send() too often, and the same happens when I rather use Invoke() in the plugin, it also gives a Stackoverflow exception.
I tried using asyncoperation, and this does not crash, but due to the fact that it's solely asynchronous is a problem, because my program becomes unresponsive when using Post(), because it continuously Posts (due to the fact that it will manage the next packet before the asyncoperation has posted.
I am using linq to sql in a Silverlight application and I keep getting this debug error..
http://www.freeimagehosting.net/uploads/bf4055b4ee.jpg
This code runs when the application is started up without problems. When I call it the second time, I only get a few of the results. When I add a breakpoint to the WCF service I get the following error...
Could someone please tell me whats going on here so i can make some changes?
TIA
ps. Might not be the most efficient coding but I will sort all that out later :P
If you add a breakpoint to the service code the caller will throw a Timeout Exception after the timeout time has passed. Raise the timeout of your service (on the server and client side), this will allow you to debug your service code without getting exceptions.
I am writing a windows service that needs to be running 24/7. It is a pretty simple service that monitors a directory where files are dropped into and processes those files. I need to restart the service if an unhandled exception is thrown.
Is there a way for a service to restart itself in the event of an unhandled exception?
The Services applet has many different recovery features:
It can take different actions on the first, second, and subsequent failures:
Restart the service, after a configurable delay
Run a Program (passing command line parameters, possibly including the failure count)
Restart the Computer (after a configurable delay, and with a particular message being sent)
The program that runs should be able to look in the event log and see the reason for failure (especially if you log it), and should therefore be able to disable the service if the exception is one that is not recoverable.
And, of course, in the meantime, the service should be logging what's going on, which should enable any management tool to notify Operations of what's going on.
I agree that you should probably not configure "third and subsequent" to be "restart service", or you could wind up in a loop.
Have you tried using the Recovery tab of the Service entry - you can set rules for failures, including "Restart the Service" - by default this is on "No Action"
This is able to be done programatically if you wanted, this code was not written by me. I am posting the link to the Authors CodeProject page that contains the source / binaries. Below the link I have explained how I implemented the authors code.
http://www.codeproject.com/KB/install/sercviceinstallerext.aspx
Add a reference to the DLL.
Open ProjectInstaller.Designer.vb in notepad
In the InitializeComponent Sub
CHANGE
Me.ServiceProcessInstaller1 = New System.ServiceProcess.ServiceProcessInstaller
Me.ServiceInstaller1 = New System.ServiceProcess.ServiceInstaller
TO
Me.ServiceProcessInstaller1 = New System.ServiceProcess.ServiceProcessInstaller
Me.ServiceInstaller1 = New Verifide.ServiceUtils.ServiceInstallerEx
With the Friend Declarations in the ProjectInstaller.Designer.vb
CHANGE
Friend WithEvents ServiceProcessInstaller1 As System.ServiceProcess.ServiceProcessInstaller
Friend WithEvents ServiceInstaller1 As System.ServiceProcess.ServiceInstaller
TO
Friend WithEvents ServiceProcessInstaller1 As System.ServiceProcess.ServiceProcessInstaller
Friend WithEvents ServiceInstaller1 As Verifide.ServiceUtils.ServiceInstallerEx
CHANGE
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceProcessInstaller1, Me.ServiceInstaller1})
TO
Me.Installers.AddRange(New System.Configuration.Install.Installer() {Me.ServiceInstaller1, Me.ServiceProcessInstaller1})
Import The Namespace On ProjectInstaller.vb
In ProjectInstaller.vb in the Public Sub New Function After Initialize component function has been called
ADD
'Set Reset Time Count - This Is 4 Days Before Count Is Reset
ServiceInstaller1.FailCountResetTime = 60 * 60 * 24 * 4
'ServiceInstaller1.FailRebootMsg = "Houston! We have a problem"
'Add Failure Actions
ServiceInstaller1.FailureActions.Add(New FailureAction(RecoverAction.Restart, 60000))
ServiceInstaller1.FailureActions.Add(New FailureAction(RecoverAction.Restart, 60000))
ServiceInstaller1.FailureActions.Add(New FailureAction(RecoverAction.None, 3000))
ServiceInstaller1.StartOnInstall = True
Build installer and install. Voila
Wrap your service code in a runner which can catch any errors and restart your service.
The best way is to wrap Try / Catch blocks around the methods in the service you can afford to let throw exceptions.
However, there may be serious exceptions thrown that should result in the service being stopped immediately. Don't ignore these! In these cases, handle the exception, log it, email it and then rethrow it. That way you will be informed that the exception has occurred and will know what went wrong. You can then fix the problem and re-start the service manually.
Just ignoring it could cause a major failure in your system which you would not know about. It could also be very expensive on CPU/RAM if the service stops then restarts then stops ad infinitum.
As suggested by "John Saunders" and "theGecko", you can monitor the service and restart it when it fails. The builtin Windows Service Recovery functionality will get you a long way, but if you find that you need some more advanced features (for example, CPU hogging and hang detection) then please check out Service Protector. It is designed to keep your important Windows Services operating 24x7.
Good luck!