当前位置: 技术问答>java相关
用什么方法是java应用程序作为一个后台服务运行?NT & unix
来源: 互联网 发布时间:2014-12-27
本文导语: 就好像数据库那样! | 自己写个NT Service程序,通过JNI启动你的Java程序。 | StdAfx.h #if !defined(AFX_STDAFX_H__7CCCEEAD_83A0_11D4_B105_000021E19FBF__INCLUDED_) #define AFX_STDAFX_H__7CCCEEAD_83A0_11D4_B105_000021...
就好像数据库那样!
|
自己写个NT Service程序,通过JNI启动你的Java程序。
|
StdAfx.h
#if !defined(AFX_STDAFX_H__7CCCEEAD_83A0_11D4_B105_000021E19FBF__INCLUDED_)
#define AFX_STDAFX_H__7CCCEEAD_83A0_11D4_B105_000021E19FBF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include
#include
#include
#include
#endif
//----------------------------------------------------------------
service.h
// Service.h: interface for the CService class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SERVICE_H__7CCCEEB1_83A0_11D4_B105_000021E19FBF__INCLUDED_)
#define AFX_SERVICE_H__7CCCEEB1_83A0_11D4_B105_000021E19FBF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
typedef struct T_SERVICE
{
char ServiceName[128];
char DisplayName[128];
char ExecutePath[_MAX_PATH];
}T_SERVICE;
BOOL LoadServiceSetting(const char* ServiceName,T_SERVICE* pService);
BOOL SaveServiceSetting(T_SERVICE* pService);
void DeleteServiceSetting(const char* ServiceName);
int outputerr(DWORD nErr=0);
inline BOOL outputerr(long nErr)
{
outputerr((DWORD)nErr);
return FALSE;
}
#ifdef _DEBUGLOG
#define WRITELOG writelog
void writelog(const char* fmt,...);
#else
#define WRITELOG
#endif
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
#endif // !defined(AFX_SERVICE_H__7CCCEEB1_83A0_11D4_B105_000021E19FBF__INCLUDED_)
//----------------------------------------------------------------
StdAfx.cpp
#include "stdafx.h"
//----------------------------------------------------------------
Service.cpp
// Service.cpp: implementation of the CService class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Service.h"
const char REG_PATH[] = "Software\Free\ServiceAny";
const char REG_DISPLAYNAME[] = "DisplayName";
const char REG_SERVICENAME[] = "ServiceName";
const char REG_EXECUTEPATH[] = "ExecutePath";
void DeleteServiceSetting(const char* ServiceName)
{
char temp[1024];
sprintf(temp,"%s\%s",REG_PATH,ServiceName);
::RegDeleteKey(HKEY_LOCAL_MACHINE,temp);
}
BOOL LoadServiceSetting(const char* ServiceName,T_SERVICE* pService)
{
char temp[1024];
sprintf(temp,"%s\%s",REG_PATH,ServiceName);
HKEY hKey=NULL;
long r = ::RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
temp,NULL,KEY_READ,&hKey);
if (r != 0)
return outputerr(r);
DWORD Type=0;
DWORD cbtemp = sizeof(temp);
r = ::RegQueryValueEx(hKey,REG_SERVICENAME,NULL,&Type,(LPBYTE)temp,&cbtemp);
if (r != 0 || Type != REG_SZ)
{
::RegCloseKey(hKey);
return outputerr(r);
}
strcpy(pService->ServiceName,temp);
cbtemp = sizeof(temp);
r = ::RegQueryValueEx(hKey,REG_DISPLAYNAME,NULL,&Type,(LPBYTE)temp,&cbtemp);
if (r == 0 && Type == REG_SZ)
strcpy(pService->DisplayName,temp);
else
strcpy(pService->DisplayName,pService->ServiceName);
cbtemp = sizeof(temp);
r = ::RegQueryValueEx(hKey,REG_EXECUTEPATH,NULL,&Type,(LPBYTE)temp,&cbtemp);
if (r != 0 || Type != REG_SZ)
{
::RegCloseKey(hKey);
return outputerr(r);
}
strcpy(pService->ExecutePath,temp);
::RegCloseKey(hKey);
return TRUE;
}
static LONG SetRegValue(HKEY hKey,const char* Name,const char* Value)
{
return ::RegSetValueEx(hKey,Name,NULL,REG_SZ,(CONST BYTE*)Value,strlen(Value)+1);
}
BOOL SaveServiceSetting(T_SERVICE* pService)
{
char temp[1024];
sprintf(temp,"%s\%s",REG_PATH,pService->ServiceName);
HKEY hKey=NULL;
DWORD cbtemp=0;
long r = ::RegCreateKeyEx(
HKEY_LOCAL_MACHINE,temp,NULL,
"",NULL,KEY_WRITE,NULL,&hKey,&cbtemp);
if (r != 0)
return outputerr(r);
if (strlen(pService->DisplayName)==0)
{
strcpy(pService->DisplayName,pService->ServiceName);
}
r = SetRegValue(hKey,REG_SERVICENAME,pService->ServiceName);
if (r != 0)
{
::RegCloseKey(hKey);
return outputerr(r);
}
r = SetRegValue(hKey,REG_DISPLAYNAME,pService->DisplayName);
if (r != 0)
{
::RegCloseKey(hKey);
return outputerr(r);
}
r = SetRegValue(hKey,REG_EXECUTEPATH,pService->ExecutePath);
if (r != 0)
{
::RegCloseKey(hKey);
return outputerr(r);
}
::RegCloseKey(hKey);
return TRUE;
}
#ifdef _DEBUGLOG
void writelog(const char* fmt,...)
{
char msg[2048];
va_list arg;
va_start(arg, fmt);
vsprintf(msg, fmt, arg);
va_end(arg);
FILE* f = fopen("f:\SrvAny.log","at");
fprintf(f,"%s",msg);
fclose(f);
}
#endif
static char ServiceName[128];
BOOL bLogError = FALSE;
void LogEvent(const char* fmt,...)
{
char msg[2048];
HANDLE hEventSource;
LPTSTR lpszStrings[1];
va_list arg;
va_start(arg, fmt);
vsprintf(msg, fmt, arg);
va_end(arg);
lpszStrings[0] = msg;
hEventSource = RegisterEventSource(NULL, ServiceName);
if (hEventSource != NULL)
{
/* Write to event log. */
ReportEvent(hEventSource,
bLogError?EVENTLOG_ERROR_TYPE:EVENTLOG_INFORMATION_TYPE,
0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
DeregisterEventSource(hEventSource);
}
printf("%s",msg);
}
static SERVICE_STATUS_HANDLE hServiceStatus=NULL;
static SERVICE_STATUS ServiceStatus;
static T_SERVICE Service;
static HANDLE hShutdownEvent=NULL;
static HANDLE hThread=NULL;
DWORD MainThreadId=0;
void SetServiceStatus(DWORD status)
{
ServiceStatus.dwCurrentState = status;
::SetServiceStatus(hServiceStatus,&ServiceStatus);
}
void LogError(DWORD nErr=0)
{
if (nErr==0)
nErr = ::GetLastError();
char temp[1024];
DWORD dwLen = ::FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,NULL,
nErr,NULL,temp,sizeof(temp),NULL);
if (dwLen > 0)
temp[dwLen] = NULL;
else
temp[0] = NULL;
bLogError = TRUE;
LogEvent("Win32 Error(%d) %sn",nErr,temp);
ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
ServiceStatus.dwServiceSpecificExitCode = nErr;
}
static void WINAPI ServiceHandler(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
SetServiceStatus(SERVICE_STOP_PENDING);
PostThreadMessage(MainThreadId, WM_QUIT, 0, 0);
break;
case SERVICE_CONTROL_PAUSE:
case SERVICE_CONTROL_CONTINUE:
case SERVICE_CONTROL_INTERROGATE:
default:
break;
}
}
static DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
char CommandLine[2048];
strcpy(CommandLine,Service.ExecutePath);
if (lpParameter != NULL && strlen((const char*)lpParameter)>0)
{
strcat(CommandLine," ");
strcat(CommandLine,(const char*)lpParameter);
}
char exedir[_MAX_PATH];
strcpy(exedir,Service.ExecutePath);
int n = strlen(exedir);
for(int i=n-1;i>=0;i--)
{
char c = exedir[i];
exedir[i] = NULL;
if (c == '\')
break;
}
if (!::CreateProcess(
Service.ExecutePath,CommandLine,
NULL,NULL,TRUE,
NULL,NULL,exedir,&si,&pi))
{
LogError();
LogEvent("can't CreateProcess %sn",CommandLine);
::PostThreadMessage(MainThreadId, WM_QUIT, 0, 0);
return (DWORD)-1;
}
SetServiceStatus(SERVICE_RUNNING);
HANDLE events[2];
events[0] = pi.hProcess;
events[1] = hShutdownEvent;
DWORD r = ::WaitForMultipleObjects(2,events,FALSE,INFINITE);
if (r != WAIT_OBJECT_0)
{
::PostThreadMessage(pi.dwThreadId,WM_QUIT,0,0);
DWORD r1 = ::WaitForSingleObject(pi.hProcess,10000);
if (r1 == WAIT_TIMEOUT)
{
LogEvent("Can't stop %s normally.n",Service.ExecutePath);
::TerminateProcess(pi.hProcess,-1);
}
}
if (r != WAIT_OBJECT_0 + 1)
{
::PostThreadMessage(MainThreadId, WM_QUIT, 0, 0);
}
DWORD ec=-1;
::GetExitCodeProcess(pi.hProcess,&ec);
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
return ec;
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
WRITELOG("in ServiceMain,argc=%dn",dwArgc);
for(DWORD ii=0;ii 0)
printf("t%s",temp);
printf("n");
return -1;
}
int usage()
{
printf("SrvAny usagen");
printf("t/s ServiceName [DisplayName] ExecutePathtRegister Servicen");
printf("t/u ServiceName tUnregister Servicen");
printf("n");
return -1;
}
int main(int argc, char* argv[])
{
WRITELOG("in main,argc=%dn",argc);
for(int i=0;i
#if !defined(AFX_STDAFX_H__7CCCEEAD_83A0_11D4_B105_000021E19FBF__INCLUDED_)
#define AFX_STDAFX_H__7CCCEEAD_83A0_11D4_B105_000021E19FBF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include
#include
#include
#include
#endif
//----------------------------------------------------------------
service.h
// Service.h: interface for the CService class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SERVICE_H__7CCCEEB1_83A0_11D4_B105_000021E19FBF__INCLUDED_)
#define AFX_SERVICE_H__7CCCEEB1_83A0_11D4_B105_000021E19FBF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
typedef struct T_SERVICE
{
char ServiceName[128];
char DisplayName[128];
char ExecutePath[_MAX_PATH];
}T_SERVICE;
BOOL LoadServiceSetting(const char* ServiceName,T_SERVICE* pService);
BOOL SaveServiceSetting(T_SERVICE* pService);
void DeleteServiceSetting(const char* ServiceName);
int outputerr(DWORD nErr=0);
inline BOOL outputerr(long nErr)
{
outputerr((DWORD)nErr);
return FALSE;
}
#ifdef _DEBUGLOG
#define WRITELOG writelog
void writelog(const char* fmt,...);
#else
#define WRITELOG
#endif
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
#endif // !defined(AFX_SERVICE_H__7CCCEEB1_83A0_11D4_B105_000021E19FBF__INCLUDED_)
//----------------------------------------------------------------
StdAfx.cpp
#include "stdafx.h"
//----------------------------------------------------------------
Service.cpp
// Service.cpp: implementation of the CService class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Service.h"
const char REG_PATH[] = "Software\Free\ServiceAny";
const char REG_DISPLAYNAME[] = "DisplayName";
const char REG_SERVICENAME[] = "ServiceName";
const char REG_EXECUTEPATH[] = "ExecutePath";
void DeleteServiceSetting(const char* ServiceName)
{
char temp[1024];
sprintf(temp,"%s\%s",REG_PATH,ServiceName);
::RegDeleteKey(HKEY_LOCAL_MACHINE,temp);
}
BOOL LoadServiceSetting(const char* ServiceName,T_SERVICE* pService)
{
char temp[1024];
sprintf(temp,"%s\%s",REG_PATH,ServiceName);
HKEY hKey=NULL;
long r = ::RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
temp,NULL,KEY_READ,&hKey);
if (r != 0)
return outputerr(r);
DWORD Type=0;
DWORD cbtemp = sizeof(temp);
r = ::RegQueryValueEx(hKey,REG_SERVICENAME,NULL,&Type,(LPBYTE)temp,&cbtemp);
if (r != 0 || Type != REG_SZ)
{
::RegCloseKey(hKey);
return outputerr(r);
}
strcpy(pService->ServiceName,temp);
cbtemp = sizeof(temp);
r = ::RegQueryValueEx(hKey,REG_DISPLAYNAME,NULL,&Type,(LPBYTE)temp,&cbtemp);
if (r == 0 && Type == REG_SZ)
strcpy(pService->DisplayName,temp);
else
strcpy(pService->DisplayName,pService->ServiceName);
cbtemp = sizeof(temp);
r = ::RegQueryValueEx(hKey,REG_EXECUTEPATH,NULL,&Type,(LPBYTE)temp,&cbtemp);
if (r != 0 || Type != REG_SZ)
{
::RegCloseKey(hKey);
return outputerr(r);
}
strcpy(pService->ExecutePath,temp);
::RegCloseKey(hKey);
return TRUE;
}
static LONG SetRegValue(HKEY hKey,const char* Name,const char* Value)
{
return ::RegSetValueEx(hKey,Name,NULL,REG_SZ,(CONST BYTE*)Value,strlen(Value)+1);
}
BOOL SaveServiceSetting(T_SERVICE* pService)
{
char temp[1024];
sprintf(temp,"%s\%s",REG_PATH,pService->ServiceName);
HKEY hKey=NULL;
DWORD cbtemp=0;
long r = ::RegCreateKeyEx(
HKEY_LOCAL_MACHINE,temp,NULL,
"",NULL,KEY_WRITE,NULL,&hKey,&cbtemp);
if (r != 0)
return outputerr(r);
if (strlen(pService->DisplayName)==0)
{
strcpy(pService->DisplayName,pService->ServiceName);
}
r = SetRegValue(hKey,REG_SERVICENAME,pService->ServiceName);
if (r != 0)
{
::RegCloseKey(hKey);
return outputerr(r);
}
r = SetRegValue(hKey,REG_DISPLAYNAME,pService->DisplayName);
if (r != 0)
{
::RegCloseKey(hKey);
return outputerr(r);
}
r = SetRegValue(hKey,REG_EXECUTEPATH,pService->ExecutePath);
if (r != 0)
{
::RegCloseKey(hKey);
return outputerr(r);
}
::RegCloseKey(hKey);
return TRUE;
}
#ifdef _DEBUGLOG
void writelog(const char* fmt,...)
{
char msg[2048];
va_list arg;
va_start(arg, fmt);
vsprintf(msg, fmt, arg);
va_end(arg);
FILE* f = fopen("f:\SrvAny.log","at");
fprintf(f,"%s",msg);
fclose(f);
}
#endif
static char ServiceName[128];
BOOL bLogError = FALSE;
void LogEvent(const char* fmt,...)
{
char msg[2048];
HANDLE hEventSource;
LPTSTR lpszStrings[1];
va_list arg;
va_start(arg, fmt);
vsprintf(msg, fmt, arg);
va_end(arg);
lpszStrings[0] = msg;
hEventSource = RegisterEventSource(NULL, ServiceName);
if (hEventSource != NULL)
{
/* Write to event log. */
ReportEvent(hEventSource,
bLogError?EVENTLOG_ERROR_TYPE:EVENTLOG_INFORMATION_TYPE,
0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
DeregisterEventSource(hEventSource);
}
printf("%s",msg);
}
static SERVICE_STATUS_HANDLE hServiceStatus=NULL;
static SERVICE_STATUS ServiceStatus;
static T_SERVICE Service;
static HANDLE hShutdownEvent=NULL;
static HANDLE hThread=NULL;
DWORD MainThreadId=0;
void SetServiceStatus(DWORD status)
{
ServiceStatus.dwCurrentState = status;
::SetServiceStatus(hServiceStatus,&ServiceStatus);
}
void LogError(DWORD nErr=0)
{
if (nErr==0)
nErr = ::GetLastError();
char temp[1024];
DWORD dwLen = ::FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,NULL,
nErr,NULL,temp,sizeof(temp),NULL);
if (dwLen > 0)
temp[dwLen] = NULL;
else
temp[0] = NULL;
bLogError = TRUE;
LogEvent("Win32 Error(%d) %sn",nErr,temp);
ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
ServiceStatus.dwServiceSpecificExitCode = nErr;
}
static void WINAPI ServiceHandler(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
SetServiceStatus(SERVICE_STOP_PENDING);
PostThreadMessage(MainThreadId, WM_QUIT, 0, 0);
break;
case SERVICE_CONTROL_PAUSE:
case SERVICE_CONTROL_CONTINUE:
case SERVICE_CONTROL_INTERROGATE:
default:
break;
}
}
static DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
char CommandLine[2048];
strcpy(CommandLine,Service.ExecutePath);
if (lpParameter != NULL && strlen((const char*)lpParameter)>0)
{
strcat(CommandLine," ");
strcat(CommandLine,(const char*)lpParameter);
}
char exedir[_MAX_PATH];
strcpy(exedir,Service.ExecutePath);
int n = strlen(exedir);
for(int i=n-1;i>=0;i--)
{
char c = exedir[i];
exedir[i] = NULL;
if (c == '\')
break;
}
if (!::CreateProcess(
Service.ExecutePath,CommandLine,
NULL,NULL,TRUE,
NULL,NULL,exedir,&si,&pi))
{
LogError();
LogEvent("can't CreateProcess %sn",CommandLine);
::PostThreadMessage(MainThreadId, WM_QUIT, 0, 0);
return (DWORD)-1;
}
SetServiceStatus(SERVICE_RUNNING);
HANDLE events[2];
events[0] = pi.hProcess;
events[1] = hShutdownEvent;
DWORD r = ::WaitForMultipleObjects(2,events,FALSE,INFINITE);
if (r != WAIT_OBJECT_0)
{
::PostThreadMessage(pi.dwThreadId,WM_QUIT,0,0);
DWORD r1 = ::WaitForSingleObject(pi.hProcess,10000);
if (r1 == WAIT_TIMEOUT)
{
LogEvent("Can't stop %s normally.n",Service.ExecutePath);
::TerminateProcess(pi.hProcess,-1);
}
}
if (r != WAIT_OBJECT_0 + 1)
{
::PostThreadMessage(MainThreadId, WM_QUIT, 0, 0);
}
DWORD ec=-1;
::GetExitCodeProcess(pi.hProcess,&ec);
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
return ec;
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
WRITELOG("in ServiceMain,argc=%dn",dwArgc);
for(DWORD ii=0;ii 0)
printf("t%s",temp);
printf("n");
return -1;
}
int usage()
{
printf("SrvAny usagen");
printf("t/s ServiceName [DisplayName] ExecutePathtRegister Servicen");
printf("t/u ServiceName tUnregister Servicen");
printf("n");
return -1;
}
int main(int argc, char* argv[])
{
WRITELOG("in main,argc=%dn",argc);
for(int i=0;i