WIN8 Service program and external app call this service

Source: Internet
Author: User

A. Service

With the help of the Win7 Service on MSDN and the "Build Service Application with VC + +", Win8 experienced all kinds of tribulations and finally ran up its own modified service program.

The original API basically did not change, I am puzzled is Win7 on the direct operation are no problem, on the Win8 can not.

Error:

OpenSCManager failed W/err 0x00000005

Originally is Win8 on the issue of permissions, perhaps my own Win7 a start to have the admin authority.


The following directly into the topic, I integrated a bit of code, a total of three files: Main.c,service.h, Service.cpp. (The project is a console program.) )

MAIN.C is just the entry for the program, and the runtime accepts parameters.

#pragma region "includes" #include <stdio.h> #include <windows.h> #include "Service.h" #pragma endregionint wmain (int argc, wchar_t* argv[]) {if (argc > 1) && ((*argv[1] = = L '-' | | (*argv[1] = = L '/')))) {if (_wcsicmp (L "Install", Argv[1] + 1) = = 0) {Svcinstall ();} else if (_wcsicmp (L "Remove", argv[1] + 1) = = 0) {Svcuninstall ();}        else if (_wcsicmp (L "Query", Argv[1] + 1) = = 0) {svcqueryconfig ();}         else if (_wcsicmp (L "Start", Argv[1] + 1) = = 0) {Svcstart ();         } else if (_wcsicmp (L "Stop", argv[1] + 1) = = 0) {svcstopnow ();     }}else{_putws (L "Parameters:"); _putws (l "-install to install the service (Require admin permission)") _putws (L "-remove                To remove the service (Require admin permission), _putws (L "-query to query the configuration of the service");                _putws (L "-start to start the service"); _putws (L "-stop to stop the service"); Runservice ();} return 0;}

The code has been written clearly, my project name is Win8service, as long as the run Win8service.exe-install, the service will be installed.

Note: cmd must be started with admin. Win8: Win+q Key, open Search panel, enter cmd, right-click Command Prompt, select Run as Administrator.


Here's a look at the implementation of these functions:

Service.h

#pragma once//Internal name of the service#define service_name             L "Cppwin8service"//Displayed name of the Service#defi NE service_display_name     L "Cppwin8service Demo"//List of SERVICE dependencies-"dep1\0dep2\0\0" #define Service_ DEPENDENCIES     L ""//The name of the account under which the service should run#define Service_account          L "NT Authorit Y\\localservice "//The password to the service account Name#define Service_password         nullvoid runservice (); VOID Svcinstall (); VOID Svcuninstall (); VOID Svcqueryconfig (); BOOL Svcstart (); VOID Svcstopnow ();


Service.cpp

#pragma region "includes" #include <stdio.h> #include <windows.h> #include "Service.h" #pragma         Endregionservice_status G_sssvcstatus;  Current service Statusservice_status_handle G_sshsvcstatushandle; Current service status Handlehandle g_hsvcstopevent; VOID WINAPI Svcmain (DWORD dwargc, lpwstr* lpszargv); VOID WINAPI Svcctrlhandler (DWORD Dwctrl); VOID Svcinit (DWORD dwargc, lpwstr* lpszargv); VOID Svcstop (); VOID Svcreportstatus (DWORD dwcurrentstate, DWORD Dwwin32exitcode, DWORD Dwwaithint); VOID svcreportevent (LPWStr lpszfunction, DWORD dwerr = 0); VOID Runservice () {//can add any additional services for the process to this table. Service_table_entry dispatchtable[] = {{service_name, (lpservice_main_function) Svcmain}, {null, NULL}};//this call re Turns when the service had stopped.//the process should simply terminate when the call Returns.if (! StartServiceCtrlDispatcher (dispatchtable)) {svcreportevent (L "StartServiceCtrlDispatcher", GetLastError ());}}  VOID WINAPI Svcmain (DWORD dwargc, lpwstr* lpszargv) {svcreportevent (L "Enter svcmain");//Register the handler function for The Serviceg_sshsvcstatushandle = RegisterServiceCtrlHandler (service_name, Svcctrlhandler); if (!g_ Sshsvcstatushandle) {svcreportevent (L "RegisterServiceCtrlHandler", GetLastError ()); return;}//These SERVICE_STATUS Members remain as set hereg_sssvcstatus.dwservicetype = Service_win32_own_process; G_sssvcstatus.dwservicespecificexitcode = 0;//Report Initial status to the Scmsvcreportstatus (service_start_pending, No_error, +//Perform service-specific initialization and work. Svcinit (DWARGC, LPSZARGV);}  VOID WINAPI Svcctrlhandler (DWORD Dwctrl) {//Handle the requested control Code.switch (Dwctrl) {case Service_control_stop: Stop the service//service_stop_pending should be reported before setting the Stop//event-g_hsvcstopevent-in SVC Stop (). This avoids a race//condition which could result in a 1053-the Service do not//respond ... error.Svcreportstatus (service_stop_pending, no_error, 0); Svcstop (); Svcreportstatus (g_sssvcstatus.dwcurrentstate, no_error, 0); Return;case service_control_interrogate:break; Default:break;} }void Svcinit (DWORD dwargc, lpwstr* lpszargv) {svcreportevent (L "Enter svcinit");//////////////////////////////////// Service initialization.////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 a manual-reset event it's not signaled At first. The control/handler function, Svcctrlhandler, signals this event when it receives//the Stop control Code.g_hsvcstopev ent = CreateEvent (null, TRUE, FALSE, NULL), if (g_hsvcstopevent = = NULL) {svcreportstatus (service_stopped, no_error, 0); return;} Report running status when initialization are complete. Svcreportstatus (service_running, no_error, 0);///////////////////////////////Perform work until service stops.//and (TRUE) {//Perform work ...//Check Whether to stop the service. WaitForSingleObject (G_hsvcstopevent, INFINITE); Svcreportstatus (service_stopped, no_error, 0); return;}} VOID Svcstop () {svcreportevent (L "Enter svcstop");//Signal the service to Stop.if (g_hsvcstopevent) {SetEvent (g_ hsvcstopevent);}}  VOID Svcreportstatus (DWORD dwcurrentstate, DWORD Dwwin32exitcode, DWORD dwwaithint) {static DWORD Dwcheckpoint = 1;//Fill In the service_status structure.g_ssSvcStatus.dwCurrentState = Dwcurrentstate;g_sssvcstatus.dwwin32exitcode = Dwwin32exitcode;g_sssvcstatus.dwwaithint = dwwaithint;g_sssvcstatus.dwcontrolsaccepted = (DwCurrentState = = SERVICE_ start_pending)? 0:service_accept_stop;g_sssvcstatus.dwcheckpoint = ((dwcurrentstate = = service_running) | | (dwcurrentstate = = service_stopped)) ? 0:dwcheckpoint++;//the status of the service to the SCM. SetServiceStatus (G_sshsvcstatushandle, &g_sssvcstatus);} VOID svcreportevent (LPWStr lpszfunction, DWORD dwerr) {HANDLE heventsource; LPCWSTR lpszstrings[2];wchar_t szbuffer[80];heventsource = RegisterEventSource (null, service_name); if (null! = Heventsource) {WORD wtype;if (Dwerr = = 0) {swprintf_s (Szbuffer, ARRAYSIZE (szbuffer), lpszfunction); wtype = Eventlog_ Information_type;} else{swprintf_s (Szbuffer, ARRAYSIZE (szbuffer), L "%s failed W/err 0x%08lx", Lpszfunction, dwerr); wtype = Eventlog_error_ TYPE;} Lpszstrings[0] = service_name;lpszstrings[1] = szbuffer; ReportEvent (Heventsource,//Event log Handlewtype,//Event TYPE0,//Event category 0,//Event identifiernull,//No security identifier2,//Size O                 F lpszstrings array0,//No binary datalpszstrings,//Array of Stringsnull); No binary Dataderegistereventsource (Heventsource);}} VOID Svcinstall () {wchar_t szpath[max_path];if (GetModuleFileName (NULL, SzpatH, ARRAYSIZE (szpath)) = = 0) {wprintf (L "GetModuleFileName failed W/err 0x%08lx\n", GetLastError ()); return;} Open the local default service control Manager Databasesc_handle Schscmanager = OpenSCManager (null, NULL, SC_MANAGER_CO Nnect | Sc_manager_create_service), if (!schscmanager) {wprintf (L "OpenSCManager failed W/err 0x%08lx\n", GetLastError ()); return;}                   Install the service into SCM by calling Createservicesc_handle Schservice = CreateService (Schscmanager, Scmanager Databaseservice_name,//Name of Serviceservice_display_name,//name to DISPL           Ayservice_change_config,//desired accessservice_win32_own_process,//Service Typeservice_demand_start, Start Typeservice_error_normal,//ERROR control Typeszpath,//Service ' s bin Arynull,//No load ordering groupnull,//no tag Identifierservice_de Pendencies,//DependencieSservice_account,//Service running Accountservice_password); Password of the accountif (NULL! = Schservice) {wprintf (L "%s installed.\n", service_display_name); Closeservicehandle (Schservice);} else{wprintf (L "CreateService failed W/err 0x%08lx\n", GetLastError ());} Closeservicehandle (Schscmanager);}  VOID Svcuninstall () {//Open the local default service control Manager Databasesc_handle Schscmanager = OpenSCManager (NULL, NULL, Sc_manager_connect), if (!schscmanager) {wprintf (L "OpenSCManager failed W/err 0x%08lx\n", GetLastError ()); return ;} Open the service with delete, stop and query status Permissionssc_handle schservice = OpenService (Schscmanager, service _name, DELETE | Service_stop | Service_query_status); if (NULL! = Schservice) {//Try to stop the Serviceservice_status sssvcstatus;if (ControlService ( Schservice, Service_control_stop, &sssvcstatus)) {wprintf (L "stopping%s.", Service_display_name); Sleep (QueryServiceStatus) while (Schservice, &sssvcStatus) {if (sssvcstatus.dwcurrentstate = = service_stop_pending) {wprintf (L "); Sleep (1000);} else break;} if (sssvcstatus.dwcurrentstate = = service_stopped) {wprintf (L "\n%s stopped.\n", service_display_name);} else{wprintf (L "\n%s failed to stop.\n", Service_display_name);}} Now remove the service by calling Deleteserviceif (DeleteService (Schservice)) {wprintf (L "%s removed.\n", Service_ Display_name);} else{wprintf (L "DeleteService failed W/err 0x%08lx\n", GetLastError ());} Closeservicehandle (Schservice);} else{wprintf (L "OpenService failed W/err 0x%08lx\n", GetLastError ());} Closeservicehandle (Schscmanager);} VOID Svcqueryconfig () {//Open the local default service control Manager Databasesc_handle Schscmanager = OpenSCManager (NUL L, NULL, Sc_manager_connect), if (!schscmanager) {wprintf (l "OpenSCManager failed W/err 0x%08lx\n", GetLastError ()); return;} Try to open the service to query its status and Configsc_handle Schservice = OpenService (Schscmanager, service_name, SE Rvice_query_status | Service_Query_config); if (NULL! = Schservice) {wprintf (L "%s was installed.\n", service_display_name);D word cbbytesneeded;//// Query the status of the service//service_status_process ssp;if (Queryservicestatusex (Schservice, Sc_status_process_ INFO, (LPBYTE) &AMP;SSP, sizeof (SSP), &cbbytesneeded)) {wprintf (L "Service Status:"); switch (ssp.dwcurrentstate) { Case service_stopped: _putws (L "STOPPED"); Break;case service_running: _putws (L "RUNNING"); Break;case service_paused: _putws (L "PAUSED"); Break;case service_start_pending:case service_stop_pending:case service_continue_pending:case SERVICE_PAUSE_ PENDING: _putws (L "PENDING"); Break;}} else{wprintf (L "Queryservicestatusex failed W/err 0x%08lx\n", GetLastError ());} Closeservicehandle (Schservice);} Else{dword Dwerr = GetLastError (), if (Dwerr = = error_service_does_not_exist) {wprintf (L "%s is not installed.\n", SERVICE _display_name);} else{wprintf (L "OpenService failed W/err 0x%08lx\n", Dwerr);}} Closeservicehandle (Schscmanager);} BOOL Svcstart () {//Run ServIce with given namesc_handle Schscmanager = OpenSCManager (null, NULL, sc_manager_all_access); if (schscmanager==0) {Long nerror = GetLastError (); wprintf (L "OpenSCManager failed, error code =%d\n", nerror);} else{//Open the Servicesc_handle schservice = OpenService (Schscmanager, service_name, service_all_access); if ( schservice==0) {Long nerror = GetLastError (); wprintf (L "OpenService failed, error code =%d\n", nerror);} else{//call StartService to run the Serviceif (StartService (schservice, 0, (lpcwstr*) NULL)) {wprintf (L "%s s Tarted.\n ", service_display_name); Closeservicehandle (Schservice); Closeservicehandle (Schscmanager); return TRUE;} Else{long nerror = GetLastError () wprintf (L "StartService failed, error code =%d\n", nerror);} Closeservicehandle (Schservice); }closeservicehandle (Schscmanager); }return FALSE;} VOID Svcstopnow () {//Open the local default service control Manager Databasesc_handle Schscmanager = OpenSCManager (NULL, NULL, Sc_manager_connect); if (!schscmanager){wprintf (L "OpenSCManager failed W/err 0x%08lx\n", GetLastError ()); return;} Open the service with delete, stop and query status Permissionssc_handle schservice = OpenService (Schscmanager, service _name, DELETE | Service_stop | Service_query_status); if (NULL! = Schservice) {//Try to stop the Serviceservice_status sssvcstatus;if (ControlService ( Schservice, Service_control_stop, &sssvcstatus)) {wprintf (L "stopping%s.", Service_display_name); Sleep (QueryServiceStatus (Schservice, &sssvcstatus)) {if (sssvcstatus.dwcurrentstate = = Service_stop _pending) {wprintf (L "."); Sleep (1000);} else break;} if (sssvcstatus.dwcurrentstate = = service_stopped) {wprintf (L "\n%s stopped.\n", service_display_name);} else{wprintf (L "\n%s failed to stop.\n", Service_display_name);}} Closeservicehandle (Schservice);} else{wprintf (L "OpenService failed W/err 0x%08lx\n", GetLastError ());} Closeservicehandle (Schscmanager);}

Let's see how the results work.

Win+r, bring up run, enter services.msc to bring up service management. Here you will see Cppwin8service Demo, click on it and you will find that it is not running.

We continue to operate on the console just after the install:

D:\honeywell\workspace\win8service\debug>win8service.exe-installcppwin8service Demo installed. D:\honeywell\workspace\win8service\debug>win8service.exe-startcppwin8service Demo started.

Refresh the service and you'll see this and start.

Open Event Viewer (Run Eventvwr.msc), Cppwin8service infomation can be seen in Windows logs---application, for example:

Cppwin8serviceenter Svcinit

Second, external programs start and stop this service

The service is running, so how do we control it in an external program? In fact very simple, is to use the above Svcstart and Svcstopnow method to do it.

We create a new MFC dialog box program, add two button, one to start a stop. Copy the two functions and then include the header file.


Third, batch processing installation service Program

To put it bluntly, it is to use the SC command to install the start-up service program, with batch processing to wrap, pay attention to run batch processing also use Admin.

SC command see the SC command to create a startup service.

Service installation and startup of Bat:

@echo. Start service! @echo OFF@SC create Linctestserver binpath= "D:\XXX\Debug\NewService.exe" @sc start Linctestserver @sc Config linctestserver start= auto@sc config linctestserver displayname= "linc Service" @echo Off@echo. Start ok! @pause


Stopped bat:

@echo. Stop Service@echo off@sc stop linctestserver @echo off@echo.service stoped@pause


Uninstalled bat:

@echo. Delete Service@echo off@sc Delete linctestserver @echo off@echo.service deleted@pause







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.