Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Aşağıdaki örnekteki SvcMain işlevi, örnek hizmetin ServiceMain işlevidir. SvcMain, bir konsol uygulamasının ana fonksiyonu gibi hizmetin komut satırı parametrelerine erişebilir. İlk parametre, ikinci parametrede hizmete geçirilen bağımsız değişkenlerin sayısını içerir. Her zaman en az bir tartışma olacaktır. İkinci parametre, dize işaretçileri dizisine yönelik bir işaretçidir. Dizideki ilk öğe her zaman hizmet adıdır.
SvcMain işlevi ilk olarak RegisterServiceCtrlHandler işlevini çağırarak SvcCtrlHandler işlevini hizmetin İşleyicisi işlevi olarak kaydeder ve başlatmaya başlar. RegisterServiceCtrlHandler, ServiceMain'deki ilk hata vermeyen işlev olmalıdır; böylece hizmet, bir hata oluşursa SERVICE_STOPPED durumunu belirten durumu SetServiceStatus çağırmak için bu işlev tarafından geri döndürülen durum tutamacını kullanabilir.
Ardından SvcMain işlevi, ilk durumunun SERVICE_START_PENDING olduğunu belirtmek için ReportSvcStatus işlevini çağırır. Hizmet bu durumdayken hiçbir denetim kabul edilmez. Hizmetin mantığını basitleştirmek için, hizmetin başlatmayı gerçekleştirirken herhangi bir denetimi kabul etmemesi önerilir.
Son olarak, SvcMain işlevi hizmete özgü başlatmayı gerçekleştirmek ve hizmet tarafından gerçekleştirilecek çalışmaya başlamak için SvcInit işlevini çağırır.
Örnek başlatma işlevi SvcInit, çok basit bir örnektir ve ek iş parçacıkları oluşturma gibi daha karmaşık başlatma görevlerini gerçekleştirmez. Hizmet denetim işleyicisinin hizmetin durdurulması gerektiğini belirtmek için sinyal gönderebileceği bir olay oluşturur, ardından hizmetin SERVICE_RUNNING durumuna girdiğini belirtmek için ReportSvcStatus'u çağırır. Bu noktada hizmet başlatma işlemini tamamlamış ve denetimleri kabul etmeye hazırdır. En iyi sistem performansı için uygulamanızın çalışma durumunu 25-100 milisaniye içinde girmesi gerekir.
Bu örnek hizmet gerçek görevleri tamamlamadığından, SvcInit yalnızca WaitForSingleObject işlevini çağırarak hizmet durdurma olayının işaretlenmesi için bekler, hizmetin SERVICE_STOPPED durumuna girdiğini belirtmek için ReportSvcStatus'u çağırır ve döndürür. (döndürmek bağımsız değişkenler için ayrılan belleğin temizlenmesine izin verdiğinden, işlevin ExitThread işlevini çağırmak yerine döndürülmesinin önemli olduğunu unutmayın.) WaitForSingleObjectyerine RegisterWaitForSingleObject işlevini kullanarak ek temizleme görevleri gerçekleştirebilirsiniz. ServiceMain işlevini çalıştıran iş parçacığı sonlandırılır, ancak hizmetin kendisi çalışmaya devam eder. Hizmet denetimi işleyicisi olayı işaret ettiğinde, iş parçacığı havuzundan bir iş parçacığı, durumu SERVICE_STOPPED olarak ayarlamak da dahil olmak üzere ek temizlemeyi gerçekleştirmek için geri çağırmanızı yürütür.
Bu örnekte, olay günlüğüne hata olayları yazmak için SvcReportEvent kullanıldığına dikkat edin. SvcReportEvent kaynak kodu için bkz. Svc.cpp. Örnek bir denetim işleyici işlevi için bkz. Denetim İşleyicisi İşlevi Yazma.
Bu örnekte aşağıdaki genel tanımlar kullanılır.
#define SVCNAME TEXT("SvcName")
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
HANDLE ghSvcStopEvent = NULL;
Aşağıdaki örnek parçası, tam hizmet örneğinden alınır.
//
// Purpose:
// Entry point for the service
//
// Parameters:
// dwArgc - Number of arguments in the lpszArgv array
// lpszArgv - Array of strings. The first string is the name of
// the service and subsequent strings are passed by the process
// that called the StartService function to start the service.
//
// Return value:
// None.
//
VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
// Register the handler function for the service
gSvcStatusHandle = RegisterServiceCtrlHandler(
SVCNAME,
SvcCtrlHandler);
if( !gSvcStatusHandle )
{
SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
return;
}
// These SERVICE_STATUS members remain as set here
gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gSvcStatus.dwServiceSpecificExitCode = 0;
// Report initial status to the SCM
ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 );
// Perform service-specific initialization and work.
SvcInit( dwArgc, lpszArgv );
}
//
// Purpose:
// The service code
//
// Parameters:
// dwArgc - Number of arguments in the lpszArgv array
// lpszArgv - Array of strings. The first string is the name of
// the service and subsequent strings are passed by the process
// that called the StartService function to start the service.
//
// Return value:
// None
//
VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv)
{
// TO_DO: Declare and set any required variables.
// Be sure to periodically call ReportSvcStatus() with
// SERVICE_START_PENDING. If initialization fails, call
// ReportSvcStatus with SERVICE_STOPPED.
// Create an event. The control handler function, SvcCtrlHandler,
// signals this event when it receives the stop control code.
ghSvcStopEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual reset event
FALSE, // not signaled
NULL); // no name
if ( ghSvcStopEvent == NULL)
{
ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
return;
}
// Report running status when initialization is complete.
ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 );
// TO_DO: Perform work until service stops.
while(1)
{
// Check whether to stop the service.
WaitForSingleObject(ghSvcStopEvent, INFINITE);
ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
return;
}
}
//
// Purpose:
// Sets the current service status and reports it to the SCM.
//
// Parameters:
// dwCurrentState - The current state (see SERVICE_STATUS)
// dwWin32ExitCode - The system error code
// dwWaitHint - Estimated time for pending operation,
// in milliseconds
//
// Return value:
// None
//
VOID ReportSvcStatus( DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
// Fill in the SERVICE_STATUS structure.
gSvcStatus.dwCurrentState = dwCurrentState;
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
gSvcStatus.dwWaitHint = dwWaitHint;
if (dwCurrentState == SERVICE_START_PENDING)
gSvcStatus.dwControlsAccepted = 0;
else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if ( (dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED) )
gSvcStatus.dwCheckPoint = 0;
else gSvcStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the SCM.
SetServiceStatus( gSvcStatusHandle, &gSvcStatus );
}
İlgili konular