#include <windows.h>
#include <stdio.h>
#include "hash.h"
#include "debug.h"
#include "stdio.h"
#include "mytime.h"
#define SERV_NAME "GPRSServer"
//DWORD WINAPI Run( LPVOID lpParam );
DWORD WINAPI Run(char *argv0,char *argv1,char *argv2 ); //做實際工作的函數,需三個參數
static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE hStatus;
static SC_HANDLE schSCManager;
static SC_HANDLE schService;
void WINAPI ControlHandler(DWORD request)
{
switch(request) {
case SERVICE_CONTROL_STOP:
Log("service stopped!");
ServiceStatus.dwCurrentState=SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode=0;
break;
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState=SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
if(SetServiceStatus(hStatus,&ServiceStatus)==0)
fprintf(stderr, "SetServiceStatus in ControlHandler out Switch Error !/n");
return;
}
static void getServicePath(char *path)
{
LPQUERY_SERVICE_CONFIG lpsc;
LPSERVICE_DESCRIPTION lpsd;
DWORD dwBytesNeeded, cbBufSize, dwError;
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)/n", GetLastError());
return;
}
// Get a handle to the service.
schService = OpenService(
schSCManager, // SCM database
SERV_NAME, // name of service
SERVICE_QUERY_CONFIG); // need query config access
if (schService == NULL)
{
printf("OpenService failed (%d)/n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
// Get the configuration information.
if( !QueryServiceConfig(
schService,
NULL,
0,
&dwBytesNeeded))
{
dwError = GetLastError();
if( ERROR_INSUFFICIENT_BUFFER == dwError )
{
cbBufSize = dwBytesNeeded;
lpsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize);
}
else
{
printf("QueryServiceConfig failed (%d)", dwError);
goto cleanup;
}
}
if( !QueryServiceConfig(
schService,
lpsc,
cbBufSize,
&dwBytesNeeded) )
{
printf("QueryServiceConfig failed (%d)", GetLastError());
goto cleanup;
}
if( !QueryServiceConfig2(
schService,
SERVICE_CONFIG_DESCRIPTION,
NULL,
0,
&dwBytesNeeded))
{
dwError = GetLastError();
if( ERROR_INSUFFICIENT_BUFFER == dwError )
{
cbBufSize = dwBytesNeeded;
lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize);
}
else
{
printf("QueryServiceConfig2 failed (%d)", dwError);
goto cleanup;
}
}
if (! QueryServiceConfig2(
schService,
SERVICE_CONFIG_DESCRIPTION,
(LPBYTE) lpsd,
cbBufSize,
&dwBytesNeeded) )
{
printf("QueryServiceConfig2 failed (%d)", GetLastError());
goto cleanup;
}
// Print the configuration information.
// Log(lpsc->lpBinaryPathName);
strcpy(path,lpsc->lpBinaryPathName);
LocalFree(lpsc);
LocalFree(lpsd);
cleanup:
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
static void WINAPI ServiceMain(int argc, char *argv[])
{
HANDLE hThread;
DWORD dwErrorCode = 0;
char path[256],args[4][128];
int j=0,k=0,i=0;
ServiceStatus.dwServiceType=SERVICE_WIN32;
ServiceStatus.dwCurrentState=SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwServiceSpecificExitCode=0;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwWin32ExitCode=0;
hStatus=RegisterServiceCtrlHandler(SERV_NAME,ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0) {
dwErrorCode = GetLastError();
if (dwErrorCode == ERROR_INVALID_NAME) {
}
else if (dwErrorCode == ERROR_SERVICE_DOES_NOT_EXIST) {
}
return;
}
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWaitHint=0;
SetServiceStatus(hStatus,&ServiceStatus);
getServicePath(path);
for(i=0;path[i]!='/0';i++)
{
if(path[i]==' ')
{
args[j][k]='/0';
j++;
k=0;
continue;
}
args[j][k]=path[i];
k++;
}
args[j][k-1]='/0';
Run(args[1],args[2],args[3]);
/*
hThread=CreateThread(NULL,0,Run,(LPVOID)&args[0],0,NULL);
if(hThread==NULL)
{
printf("create thread error!");
return;
}
CloseHandle(hThread);
*/
return;
}
static void InstallService(int argc, char *argv[])
{
DWORD dwErrorCode;
char szFilePath[64], szCmd[256];
GetModuleFileName(NULL,szFilePath,255);
sprintf(szCmd, "%s %s %s %s", szFilePath, argv[0], argv[1], argv[2]);
schSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schSCManager == NULL) {
fprintf(stderr, "open SCM database failed!/n");
return;
}
schService=CreateService(schSCManager,
SERV_NAME,
SERV_NAME,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS/* | SERVICE_INTERACTIVE_PROCESS*/,
SERVICE_AUTO_START,
SERVICE_ERROR_IGNORE,
szCmd,
NULL,
NULL,
NULL,
NULL,
NULL);
if (schService==NULL) {
dwErrorCode=GetLastError();
if (dwErrorCode != ERROR_SERVICE_EXISTS) {
fprintf(stderr, "create service failed!/n");
CloseServiceHandle(schSCManager);
}
else {
fprintf(stderr, "service already exists!/n");
CloseServiceHandle(schSCManager);
}
return;
}
else
fprintf(stderr, "install service successfully!/n");
schService = OpenService(schSCManager,SERV_NAME,SERVICE_ALL_ACCESS);
if(schService==NULL) {
fprintf(stderr, "open service failed!/n");
CloseServiceHandle(schSCManager);
return ;
}
if (StartService(schService,0,NULL)==0) {
dwErrorCode=GetLastError();
if(dwErrorCode==ERROR_SERVICE_ALREADY_RUNNING) {
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return;
}
}
while (QueryServiceStatus(schService,&ServiceStatus) != 0) {
if (ServiceStatus.dwCurrentState == SERVICE_START_PENDING)
Sleep(10);
else
break;
}
if(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
fprintf(stderr, "start service successfully!/n");
else
fprintf(stderr, "start service failed!/n");
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return;
}
void UninstallService()
{
SERVICE_STATUS UninstallServiceStatus;
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager==NULL) {
DEBUGP("open SCM database failed!/n");
return ;
}
schService=OpenService(schSCManager,SERV_NAME,SERVICE_ALL_ACCESS);
if (schService==NULL) {
DEBUGP("open service failed!/n");
CloseServiceHandle(schSCManager);
return ;
}
if(QueryServiceStatus(schService,&UninstallServiceStatus)!=0) {
if(UninstallServiceStatus.dwCurrentState != SERVICE_STOPPED) {
if(ControlService(schService,SERVICE_CONTROL_STOP,&UninstallServiceStatus)==0)
fprintf(stderr, "service stopped failed!/n");
Sleep(100);
if(UninstallServiceStatus.dwCurrentState==SERVICE_STOPPED)
fprintf(stderr, "service stopped successfully!/n");
else
fprintf(stderr, "service stopped failed!/n");
}
else
fprintf(stderr, "service already stopped !/n");
}
else {
fprintf(stderr, "service query failed!/n");
return;
}
if(DeleteService(schService)==0)
fprintf(stderr, "uninstall service failed!/n");
else
fprintf(stderr, "uninstall service successfully!/n");
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
return;
}
int main(int argc,char* argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[]= {
{SERV_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
if (argc == 2 && _stricmp(argv[1],"-uninstall")==0) {
UninstallService();
return 0;
}
if (argc == 5 && _stricmp(argv[1], "-install") == 0) {
InstallService(3, &argv[2]);
return 0;
}
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
用法:
service argv[0] argv[1] argv[2] -install
service -uninstall