1

I'm creating a Windows Service Application in Visual Studio 2010 Ultimate SP1.

I was following 'How to' from MSDN: http://msdn.microsoft.com/en-us/library/7a50syb3.aspx

I have encountered two problems:

  1. I cannot start a service via Server Explorer - my service is listed there, but in the context menu I have only two options available: Refresh and Properties. There is no "Start" though MSDN documentation says that there should be that option. Fortunately, I can avoid this hassle by using Services Control Manager.

  2. The next step is: "In Visual Studio, choose Processes from the Debug menu". That option doesn't exist in Debug menu. I have only "Attach to Process", but services aren't listed there.

Does somebody know what is wrong and how I am supposed to debug my application?

Thank you in advance.

movax
  • 27
  • 3
  • 8

2 Answers2

2

As a thought: I have built a lot of Windows services and for one of many reasons, I do not create the core code in the service itself. The service is essentially the "operational layer", if you will. Creating the core code in a dll permits debugging and testing of that particular code. You can create a console or desktop app that will run the core code which can be used during development and testing phases.

Personally, I created a service runner application which captures logging in conjunction with the start and stop functionality. My OnStart and OnStop code blocks are literally identical to that of the service.

Next, when you test the service, you should be able to start the service (e.g. myService.exe) and attach to process. However, another note is that you should pause/wait the service thread (for say 30 seconds) with a debug build so you have time to attach to the process and you don't miss your initialization code. Just remember, you have to install your service then start via the Windows service manager.

Here is some code you that might point you in the direction that I use. In the service program.cs file I use the below; then in the Service OnStart() method you call your dll and run. Also, you can stop your service, replace the dll with an updated version then restart. With C# you can replace the service exe as well, but these are only C# characteristics: in C++ you cannot.

static class Program
{
    public const string SERVICE_NAME = "myService";
    public const string SERVICE_DISPLAY_NAME = "My Service";

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(string[] args)
    {
        if (args != null && args.Length > 0)
        {
            foreach (string arg in args)
            {
                switch (arg.ToLower())
                {
                    case "-install":
                        ManageService(true);
                        return;

                    case "-remove":
                        ManageService(false);
                        return;
                }
            }


        }

        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
                { 
                    new Service() 
                };
        ServiceBase.Run(ServicesToRun);
    }

    private static void ManageService(bool bInstall)
    {
        string parms;

        if (bInstall == true)
        {
            parms = string.Format("Create {0} type= own start= demand binPath= \"{1}\" DisplayName= \"{2}\"", SERVICE_NAME,
                                  System.Reflection.Assembly.GetExecutingAssembly().Location, SERVICE_DISPLAY_NAME);
        }
        else // remove
        {
            parms = string.Format("Delete {0}", SERVICE_NAME);
        }

        try
        {
            string output = string.Empty;
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("sc.exe", parms);

            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            startInfo.CreateNoWindow = true;

            proc.StartInfo = startInfo;

            proc.Start();

            output = proc.StandardOutput.ReadToEnd();

            proc.WaitForExit(10000);

            if (proc.HasExited == true)
            {
                // NOTE: The project type has been changed from Windows Service to Console Application
                // so that Console.WriteLine will output to the console
                Console.WriteLine(output);
            }
            else
            {
                proc.Close();
                Console.WriteLine("Timed out waiting to install service");
            }
        }
        catch (System.ComponentModel.Win32Exception)
        {
            Console.WriteLine("Unable to locate sc.exe");
        }
    }
}
alex
  • 4,689
  • 8
  • 43
  • 83
Jeff Willener
  • 721
  • 4
  • 9
0
//From the main function a method from service class can be called like below code


//DebugApp method can be called from main and so the service can be debug:
//Service class    
public partial class CServices : ServiceBase
{
    public CServices()
    {
        InitializeComponent();
    }

    **public void DebugApp()
    {
        OnStart(new string[]{});
    }**
    protected override void OnStart(string[] args)
    {
        System.Console.WriteLine("Testing");
        System.Console.Read();
    }

    protected override void OnStop()
    {
    }
}


//Calling from main: 

   static void Main()
    {
        Services1.CServices uc = new CServices();
        uc.DebugApp();
    }