Как отладить службу Windows - PullRequest
       53

Как отладить службу Windows

2 голосов
/ 21 февраля 2011

Я создал службу Windows, используя Код проекта Статья.Я могу установить сервис и удалить сервис, используя ключи -i и -d.

Я могу увидеть сервис в services.msc, но когда я запускаю сервис, он ничего не делает. Ниже я сделаю выводосновной код службы:

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
  DWORD status;
  DWORD specificError;
  m_ServiceStatus.dwServiceType = SERVICE_WIN32;
  m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  m_ServiceStatus.dwWin32ExitCode = 0;
  m_ServiceStatus.dwServiceSpecificExitCode = 0;
  m_ServiceStatus.dwCheckPoint = 0;
  m_ServiceStatus.dwWaitHint = 0;

  m_ServiceStatusHandle = RegisterServiceCtrlHandler("Service1", 
                                            ServiceCtrlHandler); 
  if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
  {
    return;
  }
  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  m_ServiceStatus.dwCheckPoint = 0;
  m_ServiceStatus.dwWaitHint = 0;
  if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus))
  {
  }

  bRunning=true;
  while(bRunning)
  {

    Sleep(150000);
    ShellExecute(NULL, "open", "C:\\", NULL, NULL, SW_SHOWNORMAL);

  }
  return;
}

Но пока я запускаю службу, она не спит и не запускает проводник.Я что-то упустил?

Ответы [ 7 ]

5 голосов
/ 13 апреля 2012

Предложение Ферруччо подключить отладчик к работающей службе является хорошим, также как и предложение включить опцию для запуска в качестве консольного приложения (хотя это не поможет в вашем случае).

Чтобы отладить код запуска, вы можете вызвать DebugBreak () в начале кода запуска.Это запустит отладчик и приостановит выполнение вашего сервиса в этот момент.Как только вы окажетесь в отладчике, установите все необходимые точки останова и продолжите выполнение.

3 голосов
/ 21 февраля 2011

Вы всегда можете построить сервис в режиме отладки и подключить отладчик к работающему сервису.Единственная проблема с этим методом заключается в том, что вы не можете отлаживать код запуска службы.По этой причине и из-за того, что постоянная регистрация / отмена регистрации / запуск / остановка службы для ее отладки может быть затруднительной, я всегда пишу службы, чтобы их также можно было запускать как программы командной строки.

Ваша служба может сказать, что она была запущена из командной строки, если StartServiceCtrlDispatcher() не удалось и GetLastError() возвращает ERROR_FAILED_SERVICE_CONTROLLER_CONNECT.

Конечно, когда вы запускаете службу из командной строки, она имеет доступна рабочий стол, что обычно не выполняется службой и выполняется в контексте текущего зарегистрированного пользователя, а не LocalSystem или указанной учетной записи, поэтому необходимо учитывать эти различия при отладке службы таким способом.

0 голосов
/ 28 июня 2019

Используйте приведенный ниже код для отладки вашего сервиса, поместите его в функцию запуска сервиса, он выдаст всплывающее окно и удержит выполнение до тех пор, пока вы не скажете ОК или до 60 секунд, установите точку останова в следующем операторе выполнения и вы сможете продолжитьотладка -

Включить этот заголовок -

#include <Wtsapi32.h>
#pragma comment( lib, "Wtsapi32.lib" )

Код -

wchar_t title[] = L"mrnservice in startup - 60 seconds to take action";
wchar_t message[] = L"To debug, first attach to the process with Visual "
                    L"Studio, then click OK. If you don't want to debug, "
                    L"just click OK without attaching";
DWORD consoleSession = ::WTSGetActiveConsoleSessionId();
DWORD response;
BOOL ret = ::WTSSendMessage( WTS_CURRENT_SERVER_HANDLE,
                            consoleSession,
                            title, sizeof(title),
                            message, sizeof(message),
                            MB_OK,
                            60,
                            &response,
                            TRUE );
0 голосов
/ 24 октября 2013

В качестве альтернативы OutputDebugString () можно поместить в приложение-службу, а распечатки можно увидеть в DbgView.Я сделал это для отладки приложения-службы.Надеюсь, это кому-нибудь поможет ..

0 голосов
/ 21 февраля 2011

У меня есть несколько общих советов по отладке служб Windows здесь , хотя на первый взгляд я думаю, что тот факт, что вы используете ShellExecute, требует взаимодействия с рабочим столом.Служба обычно работает с учетной записью LocalService, поэтому она не имеет связи с физическим рабочим столом.

0 голосов
/ 21 февраля 2011

Я бы порекомендовал написать небольшой Logger-Class, который записывает информацию в текстовый файл.Тогда вы можете, например, поставить что-то вроде:

if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
    Logger.LogError("Service handler is 0.");
    return;
}    

while(running) {

   Logger.LogInfo("I am running.");

   //...
}
0 голосов
/ 21 февраля 2011

Сервисы безголовы, поэтому попытка запустить что-либо, связанное с графическим интерфейсом, не даст видимого эффекта. ShellExecute запустит приложение в визуальном контексте службы, которое ваш рабочий стол не сможет увидеть.

Если вы хотите доказать, что ваш сервис что-то делает, вместо этого запишите что-нибудь в файловую систему (или поверьте, что он работает, если менеджер сервисов достаточно хорошо подготовлен, чтобы сообщить вам, если это не так).

...