Как отлаживать приложения-службы Windows? - PullRequest
1 голос
/ 23 октября 2011

Я создаю приложение-службу Windows в Visual Studio 2010 Ultimate SP1.

Я следовал инструкциям из MSDN: http://msdn.microsoft.com/en-us/library/7a50syb3.aspx

Я столкнулся с двумя проблемами:

  1. Я не могу запустить службу через обозреватель сервера - там указан мой сервис, но в контекстном меню у меня есть только две опции: «Обновить» и «Свойства».«Пуск» отсутствует, хотя в документации MSDN сказано, что такая возможность должна быть.К счастью, я могу избежать этого, используя диспетчер управления службами.

  2. Следующий шаг: «В Visual Studio выберите« Процессы »в меню« Отладка ».Эта опция не существует в меню отладки.У меня есть только «Присоединить к процессу», но там нет служб.

Кто-нибудь знает, что не так и как я должен отлаживать свое приложение?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 23 октября 2011

В качестве мысли: я создал много служб Windows и по одной из многих причин я не создаю основной код в самой службе. Сервис по сути является «операционным уровнем», если хотите. Создание основного кода в DLL позволяет отлаживать и тестировать этот конкретный код. Вы можете создать консольное или настольное приложение, которое будет запускать основной код, который можно использовать на этапах разработки и тестирования.

Лично я создал приложение для запуска служб, которое регистрирует протоколирование вместе с функциями запуска и остановки. Мои блоки кода OnStart и OnStop буквально идентичны блокам службы.

Далее, когда вы тестируете сервис, вы должны иметь возможность запустить сервис (например, myService.exe) и подключиться к процессу. Однако, еще одно замечание: вы должны приостановить / подождать поток службы (скажем, на 30 секунд) с отладочной сборкой, чтобы у вас было время подключиться к процессу, и вы не пропустили свой код инициализации. Просто помните, что вам нужно установить службу и запустить ее через диспетчер служб Windows.

Вот код, который вы можете указать в том направлении, которое я использую. В служебном файле program.cs я использую ниже; затем в методе Service OnStart () вы вызываете dll и запускаете. Также вы можете остановить свою службу, заменить dll обновленной версией, а затем перезапустить. В C # вы также можете заменить exe службы, но это только характеристики C #: в C ++ вы не можете.

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");
        }
    }
}
0 голосов
/ 07 февраля 2013
//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();
    }
...