当前位置:  技术问答>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

    
 
 

您可能感兴趣的文章:

  • 请问大侠: 2.4下应用程序(user space)传大量数据给内核模块(kernel space)的可选方法和最佳方法.
  • 把java源程序生成应用程序有哪些方法?
  • IIS7.5 http 1.1 新建应用程序失败的解决方法
  • 深入C#任务管理器中应用程序选项隐藏程序本身的方法详解
  • 如何 点击JAVA应用程序菜单里一选项,就打开一个HTML文件!有哪几种方法?
  • 各位大仙,推荐一下用什么环境或方法开发linux网络应用程序的客户端界面呢?
  • 使用C# Winform应用程序获取网页源文件的解决方法
  • iis6.0 应用程序不可用的解决方法
  • C#访问应用程序配置文件的方法
  • iis应用程序池监控方法实例
  • 如何用编程的方法知道一个应用程序是否在运行
  • C#实现只运行单个实例应用程序的方法(使用VB.Net的IsSingleInstance)
  • (毕业设计呀,好惨!)两个JBulider应用程序(未打包)之间互相传递信息(比如说用户名,用户密码,登陆日期等等),除了用Socket,还有其他方法吗?(
  • Android判断当前应用程序处于前台还是后台的两种方法
  • Android的Service应用程序组件基本编写方法
  • 有没有关于:JAVA应用程序内嵌图像资源的方法的文章
  • win2003应用程序日志-状态服务器已关闭超时的 TCP/IP 连接的解决方法
  • asp.net 由于无法创建应用程序域,因此未能执行请求错误的解决方法
  • Android 完全退出应用程序的解决方法
  • Android实现获取应用程序相关信息列表的方法
  • destoon后台网站设置空白怎么办?解决方法
  • destoon后台网站设置变成空白的解决方法
  • .net后台获取html控件值的2种方法
  • ASP.NET MVC后台向前台传递多个对象、表的方法
  • 在页面上用action传递参数到后台出现乱码的解决方法
  • c#中js调用后台的方法介绍
  • Asp.net后台调用js脚本的方法
  • 我现在在编写一个在LINUX下运行的命令解释器,对于后台运行的命令方法有些不懂,请高手指点一下
  • php后台经常提示无法连接mysql 刷新后又可以访问的解决方法
  • HTML文本框的值改变后触发后台代码的方法
  • Asp.net 后台添加CSS、JS、Meta标签的方法
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Windows和Linux下C++类成员方法作为线程函数方法介绍
  • 如何将TOMCAT作为WINNT的一个服务??(什么样的工具或方法比较好用)?
  • 请问:如何把一个方法作为另一个方法的参数?举个例子最好
  • oracle关键字作为字段名使用方法
  • 谁知道这个程序的display方法为什麽一定要用(ResultSet result)作为参数呢?!
  • 结构体类型数据作为函数参数(三种方法)
  • Nginx作为反向代理时传递客户端IP的设置方法
  • java命名空间java.awt.im类inputcontext的类成员方法: getinputmethodcontrolobject定义及介绍
  • 实现在同一方法中获取当前方法中新赋值的session值解决方法
  • java命名空间java.awt.im.spi接口inputmethod的类成员方法: getcontrolobject定义及介绍
  • 突然想到一个奇怪的问题:如果一个非abstract类中包含一个空方法体(及非Java代码写的方法体是空的)的native方法,编译会通过吗?
  • java命名空间java.lang类runtime的类成员方法: runfinalization定义及介绍
  • 构造方法到底怎么用,构造方法体中可以放些什么东西,它和一般方法有什么本质区别功能上
  • java命名空间java.awt.im.spi接口inputmethod的类成员方法: dispose定义及介绍
  • jquery中slideUp()方法与slideDown()方法
  • java命名空间javax.swing类rowsorter<m>的类成员方法: allrowschanged定义及介绍
  • jquery中fadeIn()方法与fadeOut()方法(示例)
  • java命名空间java.lang类securitymanager的类成员方法: getsecuritycontext定义及介绍
  • 这句话对不对 用final修饰的方法是不能被该类的子类所重载的方法 ?
  • java命名空间java.awt.im.spi接口inputmethod的类成员方法: hidewindows定义及介绍
  • finalize()方法与System.runFinalization()方法有什么区别
  • java命名空间java.beans类statement的类成员方法: execute定义及介绍
  • 关于“创建重载现存方法的方法”
  • java命名空间java.lang类stacktraceelement的类成员方法: getmethodname定义及介绍
  • 关于多线程的奇怪问题,run()方法只会被start()方法自动启动一次吗?
  • java命名空间java.awt.im.spi接口inputmethod的类成员方法: activate定义及介绍
  • append()方法在哪些类里有啊?分别有什么作用?老是看到这个方法
  • java命名空间javax.swing类jcomponent的类成员方法: processcomponentkeyevent定义及介绍
  • servlet的service()方法与doGet()、doPost()方法是什么关系?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3