本文實例講述了java如何註冊成windows服務程式及一個簡單的java定時關機程式碼,分享給大家供大家參考。具體方法如下:
一、問題:
最近想找個軟體來控制電腦的關機時間,在網路上找了幾個,都是可視化介面的可以設定具體的關機時間的軟體。由於我想寫的關機程序是運行在別人機器上,只能讓機器在晚上17 點到23 點25 分才上網,到了23 點25 分就可以自動關機。為了讓別人感覺不到這個軟體的「存在」(免得使用者自己關閉定時關機軟體),所以我想把關機軟體註冊為服務的方式,運行在後台。這裡介紹下如何利用javaService 軟體把java 程式註冊為windows 服務。
二、實作方法:
1. 利用javaService 註冊java 程式為windows 服務
① 下載javaService
訪問網址http://javaservice.objectweb.org/ 下載windows 版本的javaService 文件,我下載的是JavaService-2.0.10.rar ,目前最新的版本就是「2.0.10 」。
② 安裝javaService
解壓縮我們下載下來的javaServices 到一個目錄,我是解壓縮到目錄“D:/software/JavaService-2.0.10 ”下(解壓縮到任何目錄都可以,最好別解壓到中文目錄,省的出現問題)
③ 編寫定時關機程式碼
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」目錄下。
④ 註冊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 」命令以查看所有服務,並且可以對服務的啟動類型(自動啟動還是手動啟動等)進行修改。
⑤ 測試
1) 啟動服務
當我們註冊完服務後,我們可以透過指令「net start MyShutDownService 」來啟動服務,服務啟動後會在D 盤根目錄產生my_shutdown.log 日誌檔。
2) 關閉服務
如果我們要關閉服務,可以透過指令「net stop MyShutDownService 」來關閉該服務。
3) 刪除服務
當我們想要刪除該服務時,可以使用指令「sc delete MyShutDownService 」來刪除該服務。
2. 定時關機代碼
複製程式碼如下: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 ,<BR>
* 否則回傳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程式設計有幫助。