【JavaService】使用Java编写部署windows服务
如果你玩windows系统,你对服务这个东西并不会陌生,服务可以帮我们做很多事情,在不影响用户正常工作的情况下,可以完成很多我们需要的需求。
众所周知,微软的visio studio内置的Service类可以编写windows服务,对于一个Java开发人员来说,想要编写一个windows服务部署到服务器里面,
还要在自己的开发环境装一个visio studio,那太麻烦了。
那么问题来了,我想用java编写一个windows服务,这个想法可行吗?答案是肯定的,可行!
开源的JavaService帮我们解决了这一个问题,使用java也可以编写一个windows服务部署到windows里面。
闲话不多说,来看看如何利用JavaService实现Java编写部署windows服务。
首先需要用到的一些开发工具:
JDK
Eclipse
JavaService
这里我安装的JDK是1.6版本的,
Eclipse用于编写一个JAVA工程,
JavaService可在官网下载,下载地址:http://javaservice.objectweb.org,下载之前官方需要确认你的一些个人信息,提交后可以进入资源下载页面,我这里下载的是2.0.10版本。解压后有很多文件,我们只需要用到其中的JavaService.exe。
做饭炒一个菜,我们需要准备一些菜品原料,以上我们的菜都买好了,接下来看看主要准备工作和主要步骤。
首先安装JDK,默认安装到C盘就可以了。
然后配置java环境变量,这里就不细说了,上一个链接给予大家参考,环境变量要配置正确,这个很重要。
配置JDK环境变量:http://jingyan.baidu.com/article/c85b7a6414f2ee003bac95d5.html
接着编写一个Java工程
这里我贴出我的代码示例出来,是工作的一个需求,大致看一些主要代码即可,我下面会提到的。
这里是工程结构:
代码:
- <span style="font-family:Microsoft YaHei;font-size:14px;">package com.ecservice;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.InetAddress;
- import java.net.NetworkInterface;
- import java.net.SocketException;
- import java.net.UnknownHostException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- public class ECService {
- private static Thread thread = null;
- private static Service service = null;
- /**
- * 退出服务方法(该方法必须有参数 String [] args)
- *
- * @param args
- */
- public static void StopService(String[] args) {
- System.out.println(service.getLocalTime()+"停止服务");
- service.setRunFlag(false);
- }
- /**
- * 启动服务方法(该方法必须有参数 String [] args)
- *
- * @param args
- */
- public static void StartService(String[] args) {
- // 产生服务线程
- service = new Service();
- thread = new Thread(service);
- System.out.println("\r\n"+service.getLocalTime()+"-----------启动服务-----------");
- try {
- // 将服务线程设定为用户线程,以避免StartService方法结束后线程退出
- thread.setDaemon(false);
- if (!thread.isDaemon()) {
- System.out.println(service.getLocalTime()+"成功设定线程为用户线程!");
- }
- // 启动服务线程
- thread.start();
- } catch (SecurityException se) {
- System.out.println(service.getLocalTime()+"线程类型设定失败!");
- }
- }
- public static void main(String[] args) {
- new Service().run();
- // ECService.StartService(null);
- }
- }
- class Service implements Runnable {
- private boolean runFlag = true;
- /**
- * 设定服务线程运行标志值
- *
- * @param runFlag
- */
- public synchronized void setRunFlag(boolean runFlag) {
- this.runFlag = runFlag;
- }
- /**
- * 取得服务线程运行标志值
- *
- * @param void
- */
- @SuppressWarnings("unused")
- private synchronized boolean getRunFlag() {
- return runFlag;
- }
- @Override
- public void run() {
- System.out.println(getLocalTime()+"服务线程开始运行");
- // while (getRunFlag()) {
- // 获取当前计算机名和MAC
- String hostName = getHostName();
- if (hostName != null) {
- System.out.println(getLocalTime()+"计算机名获取成功!");
- // 获取本机mac地址
- String localMac = getMac();
- if (localMac != null) {
- System.out.println(getLocalTime()+"mac获取成功!");
- String mac = subMac(localMac);
- // 匹配本机计算机名与mac地址
- if (!hostName.equals(mac)) {
- System.out.println(getLocalTime()+"开始执行修改计算机名称。");
- // 执行修改计算机名
- // 生成一个bat批处理文件
- boolean isMakeBatSuccess = makeBat(mac);
- if(isMakeBatSuccess == true){
- System.out.println(getLocalTime()+"生成bat成功!");
- // 执行bat
- runCMD("C:\\ECService\\modify_hostname.bat");
- System.out.println(getLocalTime()+"执行bat完毕!");
- // 删除bat
- removeBat("C:\\ECService\\modify_hostname.bat");
- System.out.println(getLocalTime()+"执行删除bat完毕!");
- // 重启机器
- runCMD("shutdown -r -t 0");
- System.out.println(getLocalTime()+"执行修改计算机名操作完毕,系统正在重启。");
- }else{
- System.out.println(getLocalTime()+"生成bat失败!");
- }
- } else {
- System.out.println(getLocalTime()+"本机计算机名与mac地址一致,不需要修改计算机名。");
- }
- } else {
- System.out.println(getLocalTime()+"获取本机mac地址失败!");
- }
- } else {
- System.out.println(getLocalTime()+"获取本机计算机名失败!");
- }
- // }
- System.out.println(getLocalTime()+"服务线程结束运行");
- }
- /**
- * 获取计算机名称
- *
- * @return
- */
- public String getHostName() {
- try {
- InetAddress inetAddress = InetAddress.getLocalHost();
- String hostName = "";
- hostName = inetAddress.getHostName();
- return hostName;
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(getLocalTime()+"获取计算机名称失败:" + e.getMessage());
- }
- return null;
- }
- /**
- * 获取MAC地址
- *
- * @return
- */
- public String getMac() {
- NetworkInterface byInetAddress;
- try {
- InetAddress localHost = InetAddress.getLocalHost();
- byInetAddress = NetworkInterface.getByInetAddress(localHost);
- byte[] hardwareAddress = byInetAddress.getHardwareAddress();
- return getMacFromBytes(hardwareAddress);
- } catch (SocketException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(getLocalTime()+"获取mac地址失败:" + e.getMessage());
- } catch (UnknownHostException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(getLocalTime()+"获取mac地址失败:" + e.getMessage());
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(getLocalTime()+"获取mac地址失败:" + e.getMessage());
- }
- return null;
- }
- public String subMac(String mac) {
- String r = mac.substring(9, mac.length());
- return r;
- }
- public String getMacFromBytes(byte[] bytes) {
- StringBuffer mac = new StringBuffer();
- byte currentByte;
- boolean first = false;
- for (byte b : bytes) {
- if (first) {
- mac.append("-");
- }
- currentByte = (byte) ((b & 240) >> 4);
- mac.append(Integer.toHexString(currentByte));
- currentByte = (byte) (b & 15);
- mac.append(Integer.toHexString(currentByte));
- first = true;
- }
- return mac.toString().toLowerCase();
- }
- public boolean makeBat(String hostname) {
- boolean isSuccess = false;
- File file = new File("C:\\ECService\\modify_hostname.bat");
- try {
- file.createNewFile();
- StringBuilder sb = appendBat(hostname);
- String str = sb.toString();
- byte bt[] = new byte[1024];
- bt = str.getBytes();
- FileOutputStream in;
- in = new FileOutputStream(file);
- in.write(bt, 0, bt.length);
- in.close();
- isSuccess = true;
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return isSuccess;
- }
- public StringBuilder appendBat(String hostname) {
- StringBuilder sb = new StringBuilder();
- sb.append("set cname=" + hostname);
- sb.append("\r\n");
- sb.append("echo REGEDIT4 >c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet002\\Control\\ComputerName\\ComputerName] >> c:\\windows\\reg.reg ");
- sb.append("\r\n");
- sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"NV Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_USERS\\S-1-5-18\\Software\\Microsoft\\Windows\\ShellNoRoam] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo @=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\ComputerName\\ActiveComputerName] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"NV Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon] >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"DefaultDomainName\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("echo \"AltDefaultDomainName\"=\"%cname%\" >> c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("regedit /s c:\\windows\\reg.reg");
- sb.append("\r\n");
- sb.append("exit");
- return sb;
- }
- public String runCMD(String commands) {
- String result = "";
- try {
- Process process = Runtime.getRuntime().exec(commands);
- BufferedReader errorReader = new BufferedReader(
- new InputStreamReader(process.getInputStream()));
- String line = null;
- while ((line = errorReader.readLine()) != null) {
- result += line + "\n";
- }
- errorReader.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return result;
- }
- public void removeBat(String path) {
- File file = new File(path);
- if (file.exists()) {
- boolean isflag = file.delete();
- if (isflag == true){
- System.out.println(getLocalTime()+"删除bat成功!");
- }
- else {
- System.out.println(getLocalTime()+"删除bat失败!");
- }
- } else {
- System.out.println(getLocalTime()+"删除bat失败,批处理文件不存在!");
- }
- }
- public String getLocalTime(){
- String time ="[";
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- time += df.format(new Date()).toString();
- time+="]";
- return time;
- }
- }
- </span>
这里看主要代码:
- public static void StartService(String[] args) {
- //启动服务的方法
- }</span>
- public static void StopService(String[] args) {
- //停止服务的方法
- }</span>
编写完工程代码后,将工程打包为jar包。
右键项目-Export,选择打包为JAR包
Finish
JAR包打包完毕,接下来开始做注册服务的工作。
将之前下载的JavaService解压得到JavaService.exe后,将它和jar包,统一放到文件夹C:\ECService内(注意,不要有中文路径,否则服务启动会失败)。
其中err.log和out.log是运行服务后JavaService生成的日志文件。
以管理员身份运行cmd,CD到JavaService.exe和jar包所在的目录
然后执行命令
JavaService.exe -install ECService "%JAVA_HOME%/jre/bin/server/jvm.dll" -Xmx128m -Djava.class.path="%JAVA_HOME%/lib/tools.jar;c:/ECService/ec.jar" -start com.ecservice.ECService -method StartService -stop com.ecservice.ECService -method StopService -out "%CD%/out.log" -err "%CD%/err.log" -current "%CD%" -auto
说明:
1. -install SE : 是你要发布服务的名称;
2. 你系统环境中设置JAVA_HOME,指定你所需要使用的jre;
3. 在-Djava.class.path中指定你需要运行的jar,这里有个需要注意的地方后面会提到;
4. 设置jvm的基本参数,主要就是内存的分配;
5. 指定信息文件和异常文件,及路径;
%JAVA_HOME%与环境变量一致,%CD%为当前的目录路径,参数-start 指定类ECService的路径com.ecservice.ECService,-method指定类中要调用的方法名StartService,-auto代表服务开机自动启动。
JavaService一共提供了8个参数可供选择,其中我们只需要关心安装NT服务的-install参数和卸载NT服务的-uninstall参数。
使用-install参数安装NT服务时还需要提供与服务相关的其它一些参数,其命令格式如下:
JavaService -install service_name jvm_library [jvm_options]
-start start_class [-method start_method] [-params (start_parameters)]
[-stop start_class [-method stop_method] [-params (stop_parameters)]]
[-out out_log_file] [-err err_log_file]
[-current current_dir]
[-path extra_path]
[-depends other_service]
[-auto | -manual]
[-shutdown seconds]
[-user user_name -password password]
[-append | -overwrite]
[-startup seconds]
[-description service_desc]
相关参数的作用说明如下:
service_name: The name of the service.
jvm_library: The location of the JVM DLL used to run the service.
jvm_option: An option to use when starting the JVM, such as:
"-Djava.class.path=c:/classes" or "-Xmx128m".
start_class: The class to load when starting the service.
start_method: The method to call in the start_class. default: main
start_parameters:Parameter(s) to pass in to the start_method.
stop_class: The class to load when stopping the service.
stop_method: The method to call in the stop_class. default: main
stop_parameters: Parameter(s) to pass in to the stop_method.
out_log_file: A file to redirect System.out into. (gets overwritten)
err_log_file: A file to redirect System.err into. (gets overwritten)
current_dir: The current working directory for the service.
Relative paths will be relative to this directory.
extra_path: Path additions, for native DLLs etc. (no spaces)
other_service: Single service name dependency, must start first.
auto / manual: Startup automatic (default) or manual mode.
seconds: Java method processing time (startup:sleep, shutdown:timeout).
user_name: User specified to execute the service (user@domain).
password: Password applicable if user specified to run the service.
append / overwrite: Log file output mode, append (default) or overwrite.
service_desc: Text describing installed service (quoted string, max 1024).
注册完毕后,执行启动服务命令
net start ECService
停止服务
net stop ECService
运行命令JavaService -uninstall ECService 可以删除掉服务。
【JavaService】使用Java编写部署windows服务的更多相关文章
- 如何注册java程序为windows服务
如何注册java 程序为windows 服务 最近想找个软件来控制电脑的关机时间,在网上找了几个,都是可视化界面的可以设置具体的关机时间的软件.由于我想编写的关机程序是运行在别人机器上,只能让该机器在 ...
- .NET Core部署Windows服务
创建 首先你要确保你已经安装了.NET Core 3.0或以上版本. 老版本的Windows服务请看 这篇文章 使用命令行创建: dotnet new worker 使用Visual Studio创 ...
- C#编写的windows服务安装后启动提示“服务启动后又停止了”
使用C#编写的windows服务安装到服务器上行后进行启动时,总是提示“服务启动后又停止了”. 检查了服务逻辑是没问题,安装在开发本地也是正常,网上查了资料说是可能是服务没有注册,我检查了服务是正常注 ...
- netcore项目在Windows部署:使用NSSM部署Windows服务
NSSM部署Windows服务 1 准备工作 在Windows平台部署Asp.net core应用程序一般采用IIS,但是如果我们的net core应用执行的是定时任务,需要开机自启,稳定运行的话,使 ...
- C#基于Quartz.NET实现任务调度并部署Windows服务
一.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和asp ...
- 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务
经常看到一些人在调试 Windows 服务时,很执著的在附加进程后调试!其实 .Net 编写的 Windows 应用程序,包括 Windows 服务都可以编译成 Console 程序!甚至于 ASP. ...
- Java Service Wrapper 发布Java程序为Windows服务
下载Windows版本:https://www.krenger.ch/blog/java-service-wrapper-3-5-37-for-windows-x64/ 转自:F:\java\bhGe ...
- 编写C# Windows服务,用于杀死Zsd.exe进程
最近经常在我的xp系统进程中出现Zsd.exe进程.刚开始他占用内存不是很大.但是过了一段时间就会变成几百M 机器就会变得很卡,网上说Zsd可能是病毒.所以我就想要不写一个Windows服务,让他每隔 ...
- 使用nssm部署windows服务启动应用
swoole和workerman他们都可以实现即时通信的功能,这里我简单的就workman作为windows服务器启动为例说哈吧.直接进入正题: 下载这个聊天室项目 workerman聊天室 http ...
随机推荐
- 利用ngx_python模块嵌入到Python脚本
导读 Python是一种计算机程序设计语言.是一种动态的.面向对象的脚本语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的开发. ...
- day13,day14
day13 迭代器 什么是迭代器? 迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而进行的 器:迭代取值的工具 为何要用迭代器? 迭代器提供了一种通用的不依赖于索引的迭代取值方式 如何用迭代 ...
- js 动态声明变量(eval)
eval()可以将一段字符串当作js代码来执行. 动态声明变量(字符串)可通过eval(字符串)来实现.举例如下: var Thread_num=5; for(var i=1;i<=Thread ...
- Django进阶(2)
1.在D盘创建mysite工程项目: django-admin startproject mysite manage.py ----- Django项目里面的工具,通过它可以调用django she ...
- Struts2_learning
一.这是我学习struts2所做的一个记录,因为整个过程较为麻烦,所以,记录下来,以便以后使用 过程: 步骤: 1)dynamic web project 2)jars 3)struts.xml pa ...
- PCIE_DMA实例四:xapp1052在Xilinx 7系列(KC705/VC709)FPGA上的移植
PCIE_DMA实例四:xapp1052在Xilinx 7系列(KC705/VC709)FPGA上的移植 一:前言 这段时间有个朋友加微信请求帮忙调试一块PCIe采集卡.该采集卡使用xilinx xc ...
- 大数据入门第十八天——kafka整合flume、storm
一.实时业务指标分析 1.业务 业务: 订单系统---->MQ---->Kakfa--->Storm 数据:订单编号.订单时间.支付编号.支付时间.商品编号.商家名称.商品价格.优惠 ...
- 20155210 实验一 逆向与Bof基础
20155210 实验一 逆向与Bof基础 实验内容 1.直接修改程序机器指令,改变程序执行流程 下载目标文件pwn1,反汇编 利用objdump -d pwn1对pwn1进行反汇编 得到: 8048 ...
- MFC CTreeCtrl运用
CTreeCtrl运用 删除无效资源 递归的运用 自写遍历目录函数 递归遍历所有子目录 一.删除无效资源 .打开资源文件 .找到无效链接删掉 二.自写遍历目录函数 CFileFind findfile ...
- W25Q128---读写
占坑! 总结:通信方式是SPI,读数据可以从任何地方读,写数据和擦出数据需要按照页或者扇区或者簇为单位进行. 写数据:一次最多写一页,如果超出一页数据长度,则分几次完成.例如本芯片一个扇区为4096个 ...