How to compile a windows Service Program

Source: Internet
Author: User

 

In the past two days, I want to learn about how to write windows service programs, and I checked some information online. I read an article titled Five Steps for compiling Windows service programs in C language. However, due to the negligence of the translator, the author forgets to put the key code in this document, which may cause beginners to not understand it. So I checked the relevant information. I completed the sample program in "five steps for compiling Windows service programs in C language.

 

In this article, I hope to give some help to beginners and give a general introduction to the knowledge required to compile windows service programs.

 

First, Microsoft Windows Services (formerly known as NT Services) enable you to create executable applications that can run for a long time in their own Windows sessions. These services can be automatically started when the computer is started. They can be paused and restarted without displaying any user interface. This makes the service very suitable for use on the server, or any time, in order not to affect other users working on the same computer, it needs to be used for a long time to run the function. You can also run the service in a security context different from the logon user's specific user account or default computer account.

 

The service is stateful. When we use the Windows Service Manager SC .exe to view the service status, we can display the current status of the service, which is controlled by the program code. You 'd better set the service to SERVICE_START_PENDING during service initialization, and set it to SERVICE_RUNNING when the initialization is complete. These statuses are customized by the system. You can view other statuses through msdn. You can see this status information in SC .exe.

 

When writing a windows service program, you need to pay attention to the following functions:

 

1. The first is the main function. Because windows Services do not require an interface, most programs are win32 console applications, so the main function of the program is main rather than WinMain (). The main task of the main function is to initialize a SERVICE_TABLE_ENTRY dispatch table structure and then call StartServiceCtrlDispatcher (). This will convert the main thread of the calling process to the control dispatcher. This dispatcher starts a new thread and runs the ServiceMain () function corresponding to your service in the dispatch table. The ServiceMain () function will be mentioned below.

 

The sample code for this process is as follows:

 

SERVICE_TABLE_ENTRY entrytable [2];

 

Entrytable [0]. lpServiceName = "testservice ";

 

Entrytable [0]. lpServiceProc = (LPSERVICE_MAIN_FUNCTION) ServiceMain;

 

Entrytable [1]. lpServiceName = NULL;

 

Entrytable [1]. lpServiceProc = NULL;

 

StartServiceCtrlDispatcher (entrytable );

 

After that, the system will automatically create a thread to execute the content of the ServiceMain function. You should loop the task you want to execute in ServiceMain so that the service starts to run.

 

2. The ServiceMain function is a void WINAPI ServiceMain (int argc, char ** argv) function. The function name can be defined at will. It is used to put the tasks you need to execute in the function for loop execution. This is the working function of the service program. Before executing your task in ServiceMain, assign a value to the table structure body in SERVICE_TABLE_ENTRY. Note that because the service has not started executing your task, we set the service status to SERVICE_START_PENDING, initializing. Assign values as follows:

 

Servicestatus. dwServiceType = SERVICE_WIN32;

 

Servicestatus. dwCurrentState = SERVICE_START_PENDING;

 

Servicestatus. dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;

 

// In this example, only the system shutdown and stop the service are allowed.

 

Servicestatus. dwWin32ExitCode = 0;

 

Servicestatus. dwServiceSpecificExitCode = 0;

 

Servicestatus. dwCheckPoint = 0;

 

Servicestatus. dwWaitHint = 0;

 

Hstatus =: RegisterServiceCtrlHandler ("testservice", CtrlHandler );

 

CtrlHandler is a void WINAPI CtrlHandler (DWORD request) function. The function name can be set at will. As mentioned in the following section.

 

Hstatus is a global variable of the SERVICE_STATUS_HANDLE type. When you need to change the service status, the SetServiceStatus () function needs it as a parameter to identify a service.

 

3. void WINAPI CtrlHandler (DWORD requestler), the main function of which is to receive the control command of system transmission. If you disable the service through SC .exe, this function will receive the SERVICE_CONTROL_STOP message, and you can manage the service as necessary. In this example, only SERVICE_ACCEPT_SHUTDOWN and SERVICE_ACCEPT_STOP messages are received, which is set by assigning values to servicestatus.

 

Such a basic service program is complete.

 

The following shows my sample code for reference only. This code is successfully debugged in vs2008. This article will end with how to install the service.

 

# Include <stdio. h>

 

# Include <Windows. h>

 

# Define SLEEP_TIME 5000 // Interval

 

# Define FILE_PATH "C: \ log.txt" // information output file

 

Bool brun = false;

 

SERVICE_STATUS servicestatus;

 

SERVICE_STATUS_HANDLE hstatus;

 

 

 

Int WriteToLog (char * str );

 

Void WINAPI ServiceMain (int argc, char ** argv );

 

Void WINAPI CtrlHandler (DWORD request );

 

Int InitService ();

 

 

 

Int WriteToLog (char * str)

 

{

 

FILE * pfile;

 

Fopen_s (& pfile, FILE_PATH, "a + ");

 

If (pfile = NULL)

 

{

 

Return-1;

 

}

 

Fprintf_s (pfile, "% s \ n", str );

 

Fclose (pfile );

 

Return 0;

 

}

 

 

 

Void WINAPI ServiceMain (int argc, char ** argv)

 

{

 

Servicestatus. dwServiceType = SERVICE_WIN32;

 

Servicestatus. dwCurrentState = SERVICE_START_PENDING;

 

Servicestatus. dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; // in this example, only the system shutdown and service shutdown commands are allowed.

 

Servicestatus. dwWin32ExitCode = 0;

 

Servicestatus. dwServiceSpecificExitCode = 0;

 

Servicestatus. dwCheckPoint = 0;

 

Servicestatus. dwWaitHint = 0;

 

Hstatus =: RegisterServiceCtrlHandler ("testservice", CtrlHandler );

 

If (hstatus = 0)

 

{

 

WriteToLog ("RegisterServiceCtrlHandler failed ");

 

Return;

 

}

 

WriteToLog ("RegisterServiceCtrlHandler success ");

 

// Report the running status to SCM

 

Servicestatus. dwCurrentState = SERVICE_RUNNING;

 

SetServiceStatus (hstatus, & servicestatus );

 

// The following starts the task loop. You can add the jobs you want the services to do.

 

Brun = true;

 

MEMORYSTATUS memstatus;

 

Char str [100];

 

Memset (str, '\ 0', 100 );

 

While (brun)

 

{

 

GlobalMemoryStatus (& memstatus );

 

Int availmb = memstatus. dwAvailPhys/1024/1024;

 

Sprintf_s (str, 100, "available memory is % dMB", availmb );

 

WriteToLog (str );

 

Sleep (SLEEP_TIME );

 

}

 

WriteToLog ("service stopped ");

 

}

 

 

 

Void WINAPI CtrlHandler (DWORD request)

 

{

 

Switch (request)

 

{

 

Case SERVICE_CONTROL_STOP:

 

Brun = false;

 

Servicestatus. dwCurrentState = SERVICE_STOPPED;

 

Break;

 

Case SERVICE_CONTROL_SHUTDOWN:

 

Brun = false;

 

Servicestatus. dwCurrentState = SERVICE_STOPPED;

 

Break;

 

Default:

 

Break;

 

}

 

SetServiceStatus (hstatus, & servicestatus );

 

 

 

}

 

Void main ()

 

{

 

SERVICE_TABLE_ENTRY entrytable [2];

 

Entrytable [0]. lpServiceName = "testservice ";

 

Entrytable [0]. lpServiceProc = (LPSERVICE_MAIN_FUNCTION) ServiceMain;

 

Entrytable [1]. lpServiceName = NULL;

 

Entrytable [1]. lpServiceProc = NULL;

 

StartServiceCtrlDispatcher (entrytable );

 

}

 

 

 

How to install the service:

 

Run the command line cmd.exe

 

Enter SC create testservicename binpath = D: \ test.exe

 

Enter SC start testservicename to start the service

 

Enter SC query to display the current status of your service at the bottom.

 

Enter SC stop testservicename to stop the service

 

Enter SC delete testservicename to delete the service. The service will be deleted after the next restart and cannot be registered with the same name before the restart.

 

Zhang Peng

 

HikVision

 

Zhangpeng_nj@163.com

 

2011/11/22

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.