當前位置:首頁 » 編程語言 » java程序做成服務

java程序做成服務

發布時間: 2022-08-06 20:25:41

『壹』 java怎麼樣寫一個服務

把java程序注冊到windows系統服務,相關文檔和源碼

『貳』 如何注冊java程序為windows服務

這里介紹下如何利用javaService 軟體把java 程序注冊為windows 服務。
一、 利用javaService 注冊java 程序為windows 服務
[1] 下載javaService
訪問網址http://javaservice.objectweb.org/ 下載windows 版本的javaService 文件,我下載的是JavaService-2.0.10.rar ,目前最新的版本就是「2.0.10 」。
[2] 安裝javaService
解壓我們下載下來的javaServices 到一個目錄,我是解壓到目錄「D:/software/JavaService-2.0.10 」下(解壓到任何目錄都可以,最好別解壓到中文目錄,省的出現問題 )
[3] 編寫定時關機代碼,見第二章的定時關機代碼
1) 具體代碼參加第二章,類的名字為:
com.test.timer.TimerShutDownWindows
2) 把編寫後的java 文件導出為class 的形式,把導出的類放到目錄「D:/software/JavaService-2.0.10/classes/com/test/timer 」下。也就是把導出的com 包放到
「D:/software/JavaService-2.0.10/classes」 目錄下。
[4] 注冊java 程序為windows 服務
進入「D:/software/JavaService-2.0.10 「目錄,執行如下命令:
JavaService.exe -install MyShutDownService "%JAVA_HOME%"/jre/bin/server/jvm.dll -Djava.class.path="%JAVA_HOME%"/lib/tools.jar;D:/software/JavaService-2.0.10/classes -start com.test.timer.TimerShutDownWindows
其中「-install 「後面的參數為服務的名稱,「-start 」參數後邊是要啟動的類名,「Djava.class.path 」後面參數中的
「D:/software/JavaService-2.0.10/classe 」地址是我的「TimerShutDownWindows 」類存放的路徑,實際應用中修改為自己的classPath 即可。
這里需要注意幾點:
1) 「%JAVA_HOME% 」jdk 目錄,如果沒有配置jdk 目錄,則替換為jdk 的實際絕對地址。
2) -Djava.class.path 是必須的,因為服務啟動的時候無法訪問系統的CLASSPATH 變數,所以必須在這里聲明;如果jar 比較多,為避免寫的命令過長,我們可以使用「-Djava.ext.dirs=jars 所在目錄」參數。
3) 服務添加之後,可以在命令行中敲入「services.msc 」命令來查看所有服務,並可以對服務的啟動類型(自動啟動還是手動啟動等)進行修改。
[5] 測試
1) 啟動服務
當我們注冊完服務後,我們可以通過命令「net start MyShutDownService 」來啟動該服務,服務啟動後會在D 盤根目錄生成my_shutdown.log 日誌文件。
2) 關閉服務
如果我們要關閉服務,可以通過命令「net stop MyShutDownService 」來關閉該服務。
3) 刪除服務
當我們想刪除該服務時,可以使用命令「sc delete MyShutDownService 」來刪除該服務。
二、 定時關機代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

package com.test.timer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class TimerShutDownWindows {
/* 檢測是否需要關機的時間間隔 */
private static long m_nDetectInterval = 5000;
/* 記錄上次檢測的時間,以毫秒為單位 */
private static long m_lLastMilliSeconds = 0;
/* 可以使用電腦的最小小時 */
private static int m_nUsePCMinHour = 17;
/* 可以使用電腦的最大小時 */
private static int m_nUseComputerMaxHour = 23;
/* 如果分鍾超過這個時間,則關機計算機 */
private static int m_nMinutes = 25;
/* 記錄日誌的文件的保存位置 */
private static String m_sLogFile = "D:" + File.separator
+ "my_shutdown.log";
/* 記錄當前系統是否已經啟動自動關閉程序 */
private static boolean bHasShutDownPC = false;
/**
* @param args
*/
public static void main(String[] args) {
// 1. 單獨開啟一個線程去檢測
Thread aThread = new Thread(new TimerDetector());
aThread.start();
}
/**
* 定義內部類
*
* @author Administrator
*
*/
static class TimerDetector implements Runnable {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
// 1. 獲取日誌文件
PrintWriter out = null;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
out = new PrintWriter(new FileWriter(m_sLogFile, true), true);
} catch (IOException e1) {
out = null;
e1.printStackTrace();
}
// 2. 記錄服務啟動時間
appendLog(out, " 服務啟動時間:" + df.format(new Date()));
while (true) {
// 1. 判斷當前系統時間是否被修改過
boolean bShoudShutDownPC = validateShoudShutDownPC(out);
if (bShoudShutDownPC) {
// 驗證沒通過,強制關機
exectueShutDown(out);
} else {
bHasShutDownPC = false;
}
// 2. 當前線程休眠下
try {
Thread.sleep(m_nDetectInterval);
} catch (InterruptedException e) {
appendLog(out, e.getMessage());
}
}
}
/**
* 驗證當前時間是否是需要關機的時間
*
* @return
*/
private boolean validateShoudShutDownPC(PrintWriter _out) {
// 1. 判斷是否修改了系統時間
boolean bHasModifySystemTime = detectModifySytemTime(_out);
appendLog(_out, "bHasModifySystemTime :" + bHasModifySystemTime);
if (bHasModifySystemTime) {
return bHasModifySystemTime;
}
// 2. 沒有修改系統時間,則判斷當前時間是否超過了指定的時間
boolean bShoudSleep = nowIsSleepTime();
appendLog(_out, "bShoudSleep :" + bShoudSleep);
if (bShoudSleep) {
return bShoudSleep;
}
return false;
}
/**
* 判斷當前時間是否應該休息的時間
*
* @return
*/
private boolean nowIsSleepTime() {
// 1. 獲取當前小時和分鍾
Calendar aCalendar = Calendar.getInstance();
int nHour = aCalendar.get(Calendar.HOUR_OF_DAY);
int nMinute = aCalendar.get(Calendar.MINUTE);
// 2. 判斷當前小時是否在可以使用PC 的時間內, 最大小時為23
if (nHour < m_nUsePCMinHour) {
return true;
}
// 23 點需要單獨判斷,超過23 點30 就應該休息
if ((nHour >= m_nUseComputerMaxHour) && (nMinute >= m_nMinutes)) {
return true;
}
// 3. 非休息時間
return false;
}
/**
* 判斷是否有人修改了系統時間,如果有人修改了系統時間返回true ,
* 否則返回false
*
* @return
*/
private boolean detectModifySytemTime(PrintWriter _out) {
// 1. 第一次檢測系統時間
if (m_lLastMilliSeconds == 0) {
m_lLastMilliSeconds = System.currentTimeMillis();
return false;
}
// 2. 檢測兩次時間的差值
long lInteral = System.currentTimeMillis() - m_lLastMilliSeconds;
lInteral = Math.abs(lInteral);
// 3. 判斷兩次的時間間隔, 兩次結果不一定完全等於 m_nDetectInterval ,允許誤差為1 分鍾
long lMaxInterval = m_nDetectInterval + 60 * 1000;
appendLog(_out, "lInteral :::" + lInteral);
appendLog(_out, "lMaxInterval :::" + lMaxInterval);
if (lInteral > lMaxInterval) {
// 有人修改了系統時間,強制關機
return true;
}
// 4. 只有沒人修改時間才記錄上次檢測時間
m_lLastMilliSeconds = System.currentTimeMillis();
return false;
}
/**
* 在指定的流中寫入日誌信息
*
* @param _outWriter
* @param _sAppendContent
*/
private void appendLog(PrintWriter _outWriter, String _sAppendContent) {
if (_outWriter == null) {
return;
}
_outWriter.println(_sAppendContent);
}
/**
* 執行關機命令
*/
private void exectueShutDown(PrintWriter _out) {
if (bHasShutDownPC) {
SimpleDateFormat df = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
appendLog(_out, " 系統即將關閉, 當前時間:" + df.format(new Date()));
return;
}
appendLog(_out, " 有人修改了系統時間,系統強制關機!");
// 關機
try {
Runtime.getRuntime().exec(
"shutdown -s -t 120 -c /" 很晚了,該睡覺了,2 分鍾後關閉計算機。/"");
} catch (IOException e) {
appendLog(_out, e.getMessage());
}
bHasShutDownPC = true;
}
}
}

『叄』 用什麼方法是java應用程序作為一個後台服務運行

在Windows中,無法直接用Java產生Service程序;但是可能通過編寫DCOM 或 MTS COM 或 COM+(Window2000) 組件 或 Corba 來模擬Service程序,可以實現透明遠程過程調用;
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 <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsvc.h>

#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) %s\n",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 %s\n",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=%d\n",dwArgc);
for(DWORD ii=0;ii<dwArgc;ii++)
{
WRITELOG("argv[%d] = %s\n",ii,lpszArgv[ii]);
}
WRITELOG("\n");

strcpy(ServiceName, lpszArgv[0]);
char param[2048];
param[0] = NULL;
for (DWORD i=1;i<dwArgc;i++)
{
if (i > 1)
strcat(param," ");
if (strchr(lpszArgv[i],' ') == NULL)
strcat(param,lpszArgv[i]);
else
{
strcat(param,"\"");
strcat(param,lpszArgv[i]);
strcat(param,"\"");
}
}
MainThreadId = ::GetCurrentThreadId();
ZeroMemory(&ServiceStatus,sizeof(ServiceStatus));
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
hServiceStatus = RegisterServiceCtrlHandler(ServiceName, ServiceHandler);
SetServiceStatus(SERVICE_START_PENDING);

if (!LoadServiceSetting(ServiceName,&Service))
LogEvent("Can't find Service Setting for '%s'\n",ServiceName);
else
{
hShutdownEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL);
DWORD ThreadId=0;
hThread = ::CreateThread(NULL,NULL,ThreadProc,param,NULL,&ThreadId);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
SetEvent(hShutdownEvent);
WaitForSingleObject(hThread,INFINITE);
::CloseHandle(hThread);
::CloseHandle(hShutdownEvent);
}
SetServiceStatus(SERVICE_STOPPED);
}
//----------------------------------------------------------------

SrvAny.cpp
// SrvAny.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <crtdbg.h>
#include "Service.h"

int RegisterService(const char* ServiceName,const char* DisplayName,const char* ExecutePath);
int UnregisterService(const char* ServiceName);
int outputerr(DWORD nErr)
{
if (nErr==0)
nErr = ::GetLastError();
_ASSERT(nErr != 0);
char temp[1024];
DWORD dwLen = ::FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,NULL,
nErr,NULL,temp,sizeof(temp),NULL);
printf("Win32 Error(%d)",nErr);
if (dwLen > 0)
printf("\t%s",temp);
printf("\n");
return -1;
}

int usage()
{
printf("SrvAny usage\n");
printf("\t/s ServiceName [DisplayName] ExecutePath\tRegister Service\n");
printf("\t/u ServiceName \tUnregister Service\n");
printf("\n");
return -1;
}
int main(int argc, char* argv[])
{
WRITELOG("in main,argc=%d\n",argc);
for(int i=0;i<argc;i++)
{
WRITELOG("argv[%d] = %s\n",i,argv[i]);
}
WRITELOG("\n");
if (argc == 1)
{
SERVICE_TABLE_ENTRY st[] =
{
{ "", ServiceMain },
{ NULL, NULL }
};

if (!::StartServiceCtrlDispatcher(st))
return usage();
else
return 0;
}
if (strcmp(argv[1],"/?")==0)
return usage();
if (strcmp(argv[1],"/s")==0)
{
if (argc == 4)
return RegisterService(argv[2],argv[2],argv[3]);
if (argc == 5)
return RegisterService(argv[2],argv[3],argv[4]);
return usage();
}
if (strcmp(argv[1],"/u")==0)
{
if (argc != 3)
return usage();
else

『肆』 如何將java程序轉換成windows服務程序

使用JNI調用操作系統的函數,載入注冊成為系統服務。
先你必須用C或C++定義本地方法,再編譯成DLL組件,放到System32目錄中。
再將你的Java程序裝載DLL庫,再調用C/C++中定義的方法,完成注冊服務功能。
java無法直接操作底層OS的函數。
只有JNI可以實現。 總之,注冊系統服務的功能,必須依賴C/C++實現。
如果java可以做的到,那麼就不能跨平台了。

『伍』 如何將java控制台程序做成windows服務

下面簡單介紹一下具體的使用步驟:
1. 將下載的Java Service Wrapper包解壓到本地,目錄為{WRAPPER_HOME};
2. 服務應用程序名為MyServApp,在目錄d:\MyServApp下建立bin、conf、logs、lib目錄;並把你的已有應用程序如NioBlockingServer.class拷貝到該目錄下;
3. 將{WRAPPER_HOME}\src\bin\下的遺以下文件拷貝到MyServApp目錄下,並重命名。
{WRAPPER_HOME}\bin\Wrapper.exe  C:\ MyServApp \bin\Wrapper.exe
{WRAPPER_HOME}\src\bin\App.bat.in  C:\ MyServApp\bin\MyApp.bat
{WRAPPER_HOME}\src\bin\InstallApp-NT.bat.in  C:\ MyServApp\bin\InstallMyApp-NT.bat
{WRAPPER_HOME}\src\bin\UninstallApp-NT.bat.in  C:\ MyServApp\bin\UninstallMyApp-NT.bat
4. 將{WRAPPER_HOME}\lib下的以下文件拷貝到C:\ MyServApp \lib目錄下
{WRAPPER_HOME}\lib\Wrapper.DLL
{WRAPPER_HOME}\lib\wrapper.jar
5. 將{WRAPPER_HOME}\src\conf\wrapper.conf.in拷貝到C:\ MyServApp \conf目錄下並命名為wrapper.conf;並修改wrapper.conf文件,在其中配置您的應用服務。
主要修改以下幾項即可:
#你的JVM位置:
wrapper.java.command=D:\Sun\j2sdk1.4.0_03\bin\java
#運行參數:如:
wrapper.java.additional.1=-Dprogram.name=run.bat
#classpath:
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=../bin/.
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=../lib
#MAIN CLASS 此處決定了使用Java Service Wrapper的方式
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
#你的Java應用類
wrapper.app.parameter.1= NonBlockingServer
# 服務名
wrapper.ntservice.name=NB

# Display name of the service
wrapper.ntservice.displayname=Nio Nonblocking Server
# 服務描述
wrapper.ntservice.description=Nio Nonblocking Server
其他的配置根據你的需要改變即可
6. 對以上配置的MyApp.bat進行測試,運行MyApp.bat,就像在Console窗口下運行Tomcat一樣;
7. 對以上配置的服務進行測試,運行C:\ MyServApp\bin\InstallMyApp-NT.bat將把你的應用(此處為NioBlockingServer)安裝到Win32系統服務中了。
8. 打開控制面板-管理程序-服務,看到Nio Nonblocking Server已經在系統服務中了,其他用法就與我們熟悉的Windows服務一樣了。

Tomcat使用的是Java Service Wrapper模式二,這種方式需要對已有的程序進行小的改動,但可以通過Socket埠的方式控制服務程序核心的啟動,更加靈活。

『陸』 如何把JAVA程序做成Windows服務,並開機運行

兩種方式:
一是直接放到開機運行中,在任務欄中找到啟動項將程序考進去;
二是做成exe文件格式,寫一個start開機啟動腳本,非常簡單。

『柒』 將java程序注冊成windows服務

我猜你是要將tomcat中的java程序做成服務吧?如果是的話用下面的方法
1.打開你tomcat中的bin文件夾.(不同計算機上tomcat路徑可能不一樣,具體視情況而定),用文本打開(不是雙擊打開)service.bat.在其文本裡面搜索--JvmMs 128 --JvmMx 256,(我個人比較偷懶,直接搜索 256,哈哈,一樣的結果)在後面添加 --Startup=auto(注意:前面要有空格),點擊保存就OK了。
2.運行---輸入cmd---dos窗口,進行tomcat中bin文件夾下. 直接輸入:service.bat,出現Usage: service.bat install/remove [service_name] 說明你第一步工作已經正確完成了.

3.在打開的dos窗口輸入: service.bat install?tomcat5(安裝服務)
4.?很多人第三步完成之後,就直接windows服務裡面啟動就可以了,但是我發現還有少部分人啟動的時候,windows服務那邊提示「Apache Tomcat 服務因 0 (0x0) 服務性錯誤而停止」解決這個問題很簡單:把 JRE \BIN目錄下的 msvcr71.dll 文件拷貝到 C:\windows\system32 下面

『捌』 如何將Java程序變成Windows系統服務 (1)

但是由於用的是電信的ADSL,所以地址是動態的,每天機器自動重起的時候就會變化。於是我就用3322的域名綁定,但是3322提供的windows更新dns的客戶端運行時不是作為系統服務運行的,所以沒有用戶登錄時它是沒有運行的,所以還是沒有解決問題。 後來下了一個Windows Resource Kit Tools(這個工具windows server默認是沒有的,需要到微軟的網站上下載,具體地址我沒有記住,google一下肯定能找到),裡面有一些工具可以把普通的win32程序變成系統服務。 instsrv: 這個工具是把win32程序變成系統服務,但是並不是所有程序都適合做系統服務的,如CN99的客戶端,注冊成系統服務後就是無法啟動的。 基本用法:instsrv 「服務名」 「應用程序絕對路徑」 srvany: 這個工具就是用來解決上面的工具中的問題,你注冊的時候把它當作你要的服務,在用它來啟動你的應用程序。instsrv 「服務名」 「srvany的絕對路徑」 注冊成功後,到服務管理器中把剛才注冊的服務打開,在啟動參數中填上你的應用程序絕對路徑,啟動服務就可以了。 這種方式可以解決更新域名地址的問題了。 但是心裡不爽,作為一個程序員如此受制於人總是不爽的,其實CN99的動態域名更新協議很簡單,編個簡單的程序就實現的。無奈只會Java,對於C或C++程序員來說,做一個系統服務實在是小Case啊,後悔當初沒有好好學C和C++。

熱點內容
視頻太長怎麼壓縮發微信 發布:2024-04-20 10:00:14 瀏覽:384
顯卡怎麼保存配置 發布:2024-04-20 09:28:52 瀏覽:596
校園交易網站源碼 發布:2024-04-20 09:18:54 瀏覽:701
江蘇北斗授時伺服器ip雲空間 發布:2024-04-20 08:53:50 瀏覽:931
dedecms批量上傳圖片 發布:2024-04-20 08:42:11 瀏覽:966
酷q如何編譯 發布:2024-04-20 08:41:27 瀏覽:79
安卓手機數字人民幣怎麼下載 發布:2024-04-20 08:38:21 瀏覽:114
access如何配置資料庫 發布:2024-04-20 08:37:35 瀏覽:504
手寫輸入演算法 發布:2024-04-20 08:29:31 瀏覽:258
朝夕源碼 發布:2024-04-20 08:24:15 瀏覽:276