user1108948
user1108948

Reputation:

Could not stop the xxx Service on Local Computer

I have a Windows Service that works fine but When i try to stop it from the Services console, it raises this error:

---------------------------
Services
---------------------------
Windows could not stop the xxx service on Local Computer.
The service did not return an error. 
This could be an internal Windows error or an internal service error.
If the problem persists, contact your system administrator.

My code:

      protected override void OnStop()
      {
         // TODO: Add code here to perform any tear-down necessary to stop your service.
        IvrApplication.StopImmediate();
      }
     using System;
     using System.Collections.Generic;
     using System.Collections.Concurrent;
     using System.Text;
     using VoiceElements.Common;
     using VoiceElements.Client;
     using System.Threading;
     using System.IO;
     using System.Net.Sockets;
     using System.Configuration;

namespace VoiceApp
{
   public class IvrApplication
   {
       private static object s_SyncVar = new object();
      // private static ObjectPool<InboundLine> _linepool = new ObjectPool<InboundLine>(() => new InboundLine());
    //private static int _maxLineInstances = 0;
    public static object SyncVar
    {
        get { return IvrApplication.s_SyncVar; }
    }

    private static Log s_Log;
    public static Log Log
    {
        get { return s_Log; }
    }

    private static State s_State;

    public static State State
    {
        get { return s_State; }
    }

    private static Thread s_MainCodeThread;

    public static Thread MainCodeThread
    {
        get { return s_MainCodeThread; }
    }

    private static AutoResetEvent s_ThreadEvent = new AutoResetEvent(false);

    public static AutoResetEvent ThreadEvent
    {
        get { return s_ThreadEvent; }
    }

    private static string s_WorkingFolder = null;

    public static string WorkingFolder
    {
        get { return s_WorkingFolder; }
    }



    static IvrApplication()
    {
        // Constructor
        s_Log = new Log("IvrApplication.Log");
        Log.Write("IvrApplication Constructor Complete");
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.ExceptionObject is Exception)
        {
            Log.WriteException((Exception)e.ExceptionObject, "Domain Level Unhandled Exception");
        }
        else
        {
            Log.Write("Domain Level Unhandled Exception - No Exception Object");
        }
    }

    public static void Start()
    {
        lock (SyncVar)
        {
            if (State == State.Stopped)
            {
                s_State = State.Starting;
                ThreadStart ts = new ThreadStart(MainCode);
                s_MainCodeThread = new Thread(ts);
                s_MainCodeThread.Name = "IvrApplication";
                s_MainCodeThread.Start();
                Log.Write("IvrApplication Starting...");
            }
            else
            {
                Log.Write("IvrApplication is in the " + State.ToString() + " state.  Cannot start IvrApplication at this time.");
            }
        }
    }

    public static void StopImmediate()
    {
        lock (SyncVar)
        {
            if (State == State.Running || State == State.StoppingControlled)
            {
                s_State = State.StoppingImmediate;
                ThreadEvent.Set();
                Log.Write("IvrApplication StoppingImmediate.");
            }
            else
            {
                Log.Write("IvrApplication is in the " + State.ToString() + " state.  Cannot stop IvrApplication at this time.");
            }
        }
    }

    public static void StopControlled()
    {
        lock (SyncVar)
        {
            if (State == State.Running)
            {
                s_State = State.StoppingControlled;
                ThreadEvent.Set();
                Log.Write("IvrApplication StoppingControlled.");
            }
            else
            {
                Log.Write("IvrApplication is in the " + State.ToString() + " state.  Cannot stop IvrApplication at this time.");
            }
        }
    }

    public static TelephonyServer s_TelephonyServer = null;

    public static void MainCode()
    {

        try
        {
            s_WorkingFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

            Log.Write("IvrApplication::MainCode() Starting...");

            // Start Other Threads...
            try
            {
                // UPDATE YOUR SERVER ADDRESS HERE
                System.Net.IPAddress[] ips = System.Net.Dns.GetHostAddresses(ConfigurationManager.AppSettings["veserver"]);

                if (ips == null || ips.Length == 0) throw new Exception("Error: Could not resolve Telephony Server specified!");

                string sIpaddress = @"gtcp://" + ips[0].ToString() + ":54331";
                Log.Write("Connecting to: {0}", sIpaddress);

                // CHANGE YOUR USERNAME AND PASSWORD HERE
                s_TelephonyServer = new TelephonyServer(sIpaddress, "username", "password");

                //create object pool for line instance object that get used in the Newcall Event handler

                // CHANGE YOUR CACHE MODE HERE
                //
                // Client Session mode means that the server will stream and cache the files to/from your client machine.
                // Files are flushed after you disconnect.
                //
                // Server mode means that the files reside on the server and will use the full path name to find them there.
                // Server mode can only be used on your own dedicate VE server.

                //s_TelephonyServer.CacheMode = VoiceElements.Interface.CacheMode.ClientSession;
                s_TelephonyServer.CacheMode = VoiceElements.Interface.CacheMode.Server;


                // SUBSCRIBE to the new call event.
                s_TelephonyServer.NewCall += new VoiceElements.Client.NewCall(s_TelephonyServer_NewCall);
                s_TelephonyServer.RegisterDNIS();

                // Subscribe to the connection events to allow you to reconnect if something happens to the internet connection.
                // If you are running your own VE server, this is less likely to happen except when you restart your VE server.
                s_TelephonyServer.ConnectionLost += new ConnectionLost(s_TelephonyServer_ConnectionLost);
                s_TelephonyServer.ConnectionRestored += new ConnectionRestored(s_TelephonyServer_ConnectionRestored);


            }
            catch (Exception ex)
            {
                try
                {
                    if (s_TelephonyServer != null)
                    {
                        s_TelephonyServer.Dispose();
                    }
                }
                catch (Exception) { }

                Log.Write("IvrApplication::MainCode() Exception: " + ex.Message + "\r\n" + ex.StackTrace);
                throw ex;
            }

            Log.Write("VoiceElementsClient Version: {0}", s_TelephonyServer.GetClientVersion());
            Log.Write("VoiceElementsServer Version: {0}", s_TelephonyServer.GetServerVersion());

            lock (SyncVar)
            {
                s_State = State.Running;
            }

            Log.Write("IvrApplication::MainCode() Running...");

            while (true)
            {

                // Waits for some asyncronous event.
                ThreadEvent.WaitOne(10000, false);

                // At this point you are in control.  You can farm out calls from a database, 
                // or you could code the IvrInteractive Form and create a GUI for handling you calls.
                // Follow the example from the Sampler on how to make an outbound class for new calls.

                lock (SyncVar)
                {
                    if (State != State.Running) break;
                }
            }

            s_TelephonyServer.Dispose();
            s_TelephonyServer = null;

            // Must be shutting down...

            if (State == State.StoppingControlled)
            {
                Log.Write("IvrApplication::MainCode() StoppingControlled...");
            }

            if (State == State.StoppingImmediate)
            {
                Log.Write("IvrApplication::MainCode() StoppingImmediate...");
            }

            lock (SyncVar)
            {
                s_State = State.Stopped;
                Log.Write("IvrApplication::MainCode() Stopped.");
            }

        }
        catch (Exception ex)
        {
            Log.Write("IvrApplication::MainCode() Exception" + ex.Message + "\r\n" + ex.StackTrace);
            s_State = State.Stopped;
        }
        finally
        {
            s_MainCodeThread = null;
        }
    }

    static void s_TelephonyServer_ConnectionRestored(object sender, ConnectionRestoredEventArgs e)
    {

        // When the connection is restored you must reset your cache mode and re-register the DNIS.

        s_TelephonyServer.CacheMode = VoiceElements.Interface.CacheMode.ClientSession;
        //s_TelephonyServer.CacheMode = VoiceElements.Interface.CacheMode.Server;
        s_TelephonyServer.RegisterDNIS();

        Log.Write("The Connection to the server was successfully restored!");

    }

    static void s_TelephonyServer_ConnectionLost(object sender, ConnectionLostEventArgs e)
    {

        // You could also send an email to yourself to let you know that the server was down.
        Log.Write("The Connection to the server was lost.");
    }


    static void s_TelephonyServer_NewCall(object sender, VoiceElements.Client.NewCallEventArgs e)
    {
        // Handle The New Call Here

        //Object Pool ***************************************************
        //if (_linepool.PoolCount() > _maxLineInstances)
        //{
        //    _maxLineInstances++;
        //    Log.Write("");
        //    Log.Write("Max Object Pool Size:{0}", _linepool.PoolCount().ToString());
        //    Log.Write("");
        //}
        //InboundLine s_InboundLine = _linepool.GetObject();
        //********************************************************

        InboundLine s_InboundLine = new InboundLine(); 
        s_InboundLine.TServer = s_TelephonyServer;
        s_InboundLine.Channel_Resource = e.ChannelResource;
        s_InboundLine.log = Log;
        s_InboundLine.RunScript();


//      _linepool.PutObject(s_InboundLine); //Object Pool

        //Threads per object ************************************
            //ThreadStart its = new ThreadStart(s_InboundLine.RunScript);
            //Thread s_InboundLineThread = new Thread(its);
            //s_InboundLineThread.Name = "Port"+e.ChannelResource.PortIndexer.ToString();
            //s_InboundLineThread.Start();
        //*********************************************************
    }


}

}

I tried to catch the exception in OnStop. I found the detail in event view is:

   Log Name:      Application
   Source:        IvrService
   Date:          11/4/2013 11:57:23 AM
   Event ID:      0
   Task Category: None
   Level:         Error
   Keywords:      Classic
   User:          N/A
   Computer:      xxx.corporate.my.com
   Description:
   Failed to stop service. System.IO.FileNotFoundException: Could not load file or assembly  'VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
   File name: 'VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null'
   at VoiceApp.IvrService.OnStop()
   at System.ServiceProcess.ServiceBase.DeferredStop()

    Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
    Running under executable  C:\source\VoiceApp\obj\Debug\VoiceApp.exe
     --- A detailed error log follows. 

    === Pre-bind state information ===
    LOG: User = NT AUTHORITY\SYSTEM
    LOG: DisplayName = VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null
    (Fully-specified)
    LOG: Appbase = file:///C:/source/VoiceApp/obj/Debug/
    LOG: Initial PrivatePath = NULL
    Calling assembly : VoiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyTok...
    Event Xml:
    <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
      <System>
         <Provider Name="IvrService" />
           <EventID Qualifiers="0">0</EventID>
           <Level>2</Level>
           <Task>0</Task>
           <Keywords>0x80000000000000</Keywords>
           <TimeCreated SystemTime="2013-11-04T16:57:23.000000000Z" />
           <EventRecordID>45872</EventRecordID>
           <Channel>Application</Channel>
           <Computer>xxx-desk.corporate.my.com</Computer>
           <Security />
       </System>
      <EventData>
      <Data>Failed to stop service. System.IO.FileNotFoundException: Could not load file or  assembly  'VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null' or one of its  dependencies. The system cannot find the file specified.
File name: 'VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null'

at VoiceApp.IvrService.OnStop() at System.ServiceProcess.ServiceBase.DeferredStop()

   Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
   Running under executable  C:\source\VoiceApp\obj\Debug\VoiceApp.exe
  --- A detailed error log follows. 

  === Pre-bind state information ===
   LOG: User = NT AUTHORITY\SYSTEM
   LOG: DisplayName = VoiceElementsCommon, Version=8.3.12.111, Culture=neutral, PublicKeyToken=null
   (Fully-specified)
    LOG: Appbase = file:///C:/VoiceApp/obj/Debug/
   LOG: Initial PrivatePath = NULL
   Calling assembly : VoiceApp, Version=1.0.0.0, Culture=neutral, PublicKeyTok...</Data>
   </EventData>
   </Event>

Upvotes: 0

Views: 7406

Answers (3)

Rhuan Soares
Rhuan Soares

Reputation: 1

I was facing the same problem.

You need to add the method override:

protected override void OnShutdown()
{
    eventLog1.WriteEntry("On Shutdonw.");
    timer.Stop();
    //Add your code for release memory
}

Upvotes: 0

giammin
giammin

Reputation: 18958

You did not post all your code and it is difficult to understand the error.

The causes could be:

How you initialize your EventWaitHandle: AutoReset or ManualResetand what you do in your thread to attach to it. There you can find an example on how it should be done.

Your thread are doing time consuming stuffs and they need more time to shutdown properly.

protected override void OnStop()
{
   this.RequestAdditionalTime(10000);
   IvrApplication.StopImmediate();
}

----------UPDATE---------

after you put the error logged I can bet you did not put all dependency dll in the folder where you service is.

Upvotes: 1

Ovidiu
Ovidiu

Reputation: 1407

My guess is you've still got threads running after StopImmediate() is called.

EDIT:

From what I understand from you comments you are calling IvrApplication.Start() multiple times so ThreadStart ts = new ThreadStart(MainCode); is also called multiple times. This means you end up with a lot of threads all waiting for ThreadEvent to be signaled. But, when you call ThreadEvent.Set(); inside StopImmediate() what happens is that ThreadEvent is signaled but only one thread is released from the waiting event. The others still wait for the event.

What you need is a ManualResetEvent instead of an AutoResetEvent so that when you call Set() you release all waiting threads, not just the first one.

Instead of

private static AutoResetEvent s_ThreadEvent = new AutoResetEvent(false);

use

private static ManualResetEvent s_ThreadEvent = new ManualResetEvent(false);
public static ManualResetEvent ThreadEvent
{
   get { return s_ThreadEvent; }
}

Upvotes: 0

Related Questions