如果你玩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工程

这里我贴出我的代码示例出来,是工作的一个需求,大致看一些主要代码即可,我下面会提到的。

这里是工程结构:

代码:

  1. <span style="font-family:Microsoft YaHei;font-size:14px;">package com.ecservice;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.net.InetAddress;
  9. import java.net.NetworkInterface;
  10. import java.net.SocketException;
  11. import java.net.UnknownHostException;
  12. import java.text.SimpleDateFormat;
  13. import java.util.Date;
  14. public class ECService {
  15. private static Thread thread = null;
  16. private static Service service = null;
  17. /**
  18. * 退出服务方法(该方法必须有参数 String [] args)
  19. *
  20. * @param args
  21. */
  22. public static void StopService(String[] args) {
  23. System.out.println(service.getLocalTime()+"停止服务");
  24. service.setRunFlag(false);
  25. }
  26. /**
  27. * 启动服务方法(该方法必须有参数 String [] args)
  28. *
  29. * @param args
  30. */
  31. public static void StartService(String[] args) {
  32. // 产生服务线程
  33. service = new Service();
  34. thread = new Thread(service);
  35. System.out.println("\r\n"+service.getLocalTime()+"-----------启动服务-----------");
  36. try {
  37. // 将服务线程设定为用户线程,以避免StartService方法结束后线程退出
  38. thread.setDaemon(false);
  39. if (!thread.isDaemon()) {
  40. System.out.println(service.getLocalTime()+"成功设定线程为用户线程!");
  41. }
  42. // 启动服务线程
  43. thread.start();
  44. } catch (SecurityException se) {
  45. System.out.println(service.getLocalTime()+"线程类型设定失败!");
  46. }
  47. }
  48. public static void main(String[] args) {
  49. new Service().run();
  50. //      ECService.StartService(null);
  51. }
  52. }
  53. class Service implements Runnable {
  54. private boolean runFlag = true;
  55. /**
  56. * 设定服务线程运行标志值
  57. *
  58. * @param runFlag
  59. */
  60. public synchronized void setRunFlag(boolean runFlag) {
  61. this.runFlag = runFlag;
  62. }
  63. /**
  64. * 取得服务线程运行标志值
  65. *
  66. * @param void
  67. */
  68. @SuppressWarnings("unused")
  69. private synchronized boolean getRunFlag() {
  70. return runFlag;
  71. }
  72. @Override
  73. public void run() {
  74. System.out.println(getLocalTime()+"服务线程开始运行");
  75. // while (getRunFlag()) {
  76. // 获取当前计算机名和MAC
  77. String hostName = getHostName();
  78. if (hostName != null) {
  79. System.out.println(getLocalTime()+"计算机名获取成功!");
  80. // 获取本机mac地址
  81. String localMac = getMac();
  82. if (localMac != null) {
  83. System.out.println(getLocalTime()+"mac获取成功!");
  84. String mac = subMac(localMac);
  85. // 匹配本机计算机名与mac地址
  86. if (!hostName.equals(mac)) {
  87. System.out.println(getLocalTime()+"开始执行修改计算机名称。");
  88. // 执行修改计算机名
  89. // 生成一个bat批处理文件
  90. boolean isMakeBatSuccess = makeBat(mac);
  91. if(isMakeBatSuccess == true){
  92. System.out.println(getLocalTime()+"生成bat成功!");
  93. // 执行bat
  94. runCMD("C:\\ECService\\modify_hostname.bat");
  95. System.out.println(getLocalTime()+"执行bat完毕!");
  96. // 删除bat
  97. removeBat("C:\\ECService\\modify_hostname.bat");
  98. System.out.println(getLocalTime()+"执行删除bat完毕!");
  99. // 重启机器
  100. runCMD("shutdown -r -t 0");
  101. System.out.println(getLocalTime()+"执行修改计算机名操作完毕,系统正在重启。");
  102. }else{
  103. System.out.println(getLocalTime()+"生成bat失败!");
  104. }
  105. } else {
  106. System.out.println(getLocalTime()+"本机计算机名与mac地址一致,不需要修改计算机名。");
  107. }
  108. } else {
  109. System.out.println(getLocalTime()+"获取本机mac地址失败!");
  110. }
  111. } else {
  112. System.out.println(getLocalTime()+"获取本机计算机名失败!");
  113. }
  114. // }
  115. System.out.println(getLocalTime()+"服务线程结束运行");
  116. }
  117. /**
  118. * 获取计算机名称
  119. *
  120. * @return
  121. */
  122. public String getHostName() {
  123. try {
  124. InetAddress inetAddress = InetAddress.getLocalHost();
  125. String hostName = "";
  126. hostName = inetAddress.getHostName();
  127. return hostName;
  128. } catch (Exception e) {
  129. // TODO Auto-generated catch block
  130. e.printStackTrace();
  131. System.out.println(getLocalTime()+"获取计算机名称失败:" + e.getMessage());
  132. }
  133. return null;
  134. }
  135. /**
  136. * 获取MAC地址
  137. *
  138. * @return
  139. */
  140. public String getMac() {
  141. NetworkInterface byInetAddress;
  142. try {
  143. InetAddress localHost = InetAddress.getLocalHost();
  144. byInetAddress = NetworkInterface.getByInetAddress(localHost);
  145. byte[] hardwareAddress = byInetAddress.getHardwareAddress();
  146. return getMacFromBytes(hardwareAddress);
  147. } catch (SocketException e) {
  148. // TODO Auto-generated catch block
  149. e.printStackTrace();
  150. System.out.println(getLocalTime()+"获取mac地址失败:" + e.getMessage());
  151. } catch (UnknownHostException e) {
  152. // TODO Auto-generated catch block
  153. e.printStackTrace();
  154. System.out.println(getLocalTime()+"获取mac地址失败:" + e.getMessage());
  155. } catch (Exception e) {
  156. // TODO Auto-generated catch block
  157. e.printStackTrace();
  158. System.out.println(getLocalTime()+"获取mac地址失败:" + e.getMessage());
  159. }
  160. return null;
  161. }
  162. public String subMac(String mac) {
  163. String r = mac.substring(9, mac.length());
  164. return r;
  165. }
  166. public String getMacFromBytes(byte[] bytes) {
  167. StringBuffer mac = new StringBuffer();
  168. byte currentByte;
  169. boolean first = false;
  170. for (byte b : bytes) {
  171. if (first) {
  172. mac.append("-");
  173. }
  174. currentByte = (byte) ((b & 240) >> 4);
  175. mac.append(Integer.toHexString(currentByte));
  176. currentByte = (byte) (b & 15);
  177. mac.append(Integer.toHexString(currentByte));
  178. first = true;
  179. }
  180. return mac.toString().toLowerCase();
  181. }
  182. public boolean makeBat(String hostname) {
  183. boolean isSuccess = false;
  184. File file = new File("C:\\ECService\\modify_hostname.bat");
  185. try {
  186. file.createNewFile();
  187. StringBuilder sb = appendBat(hostname);
  188. String str = sb.toString();
  189. byte bt[] = new byte[1024];
  190. bt = str.getBytes();
  191. FileOutputStream in;
  192. in = new FileOutputStream(file);
  193. in.write(bt, 0, bt.length);
  194. in.close();
  195. isSuccess = true;
  196. } catch (FileNotFoundException e) {
  197. // TODO Auto-generated catch block
  198. e.printStackTrace();
  199. } catch (IOException e) {
  200. // TODO Auto-generated catch block
  201. e.printStackTrace();
  202. } catch (Exception e) {
  203. e.printStackTrace();
  204. }
  205. return isSuccess;
  206. }
  207. public StringBuilder appendBat(String hostname) {
  208. StringBuilder sb = new StringBuilder();
  209. sb.append("set cname=" + hostname);
  210. sb.append("\r\n");
  211. sb.append("echo REGEDIT4 >c:\\windows\\reg.reg");
  212. sb.append("\r\n");
  213. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName] >> c:\\windows\\reg.reg");
  214. sb.append("\r\n");
  215. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName] >> c:\\windows\\reg.reg");
  216. sb.append("\r\n");
  217. sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
  218. sb.append("\r\n");
  219. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName] >> c:\\windows\\reg.reg");
  220. sb.append("\r\n");
  221. sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
  222. sb.append("\r\n");
  223. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet002\\Control\\ComputerName\\ComputerName] >> c:\\windows\\reg.reg ");
  224. sb.append("\r\n");
  225. sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
  226. sb.append("\r\n");
  227. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters] >> c:\\windows\\reg.reg");
  228. sb.append("\r\n");
  229. sb.append("echo \"NV Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
  230. sb.append("\r\n");
  231. sb.append("echo \"Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
  232. sb.append("\r\n");
  233. sb.append("echo [HKEY_USERS\\S-1-5-18\\Software\\Microsoft\\Windows\\ShellNoRoam] >> c:\\windows\\reg.reg");
  234. sb.append("\r\n");
  235. sb.append("echo @=\"%cname%\" >> c:\\windows\\reg.reg");
  236. sb.append("\r\n");
  237. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\ComputerName\\ActiveComputerName] >> c:\\windows\\reg.reg");
  238. sb.append("\r\n");
  239. sb.append("echo \"ComputerName\"=\"%cname%\" >> c:\\windows\\reg.reg");
  240. sb.append("\r\n");
  241. sb.append("echo [HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters] >> c:\\windows\\reg.reg");
  242. sb.append("\r\n");
  243. sb.append("echo \"NV Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
  244. sb.append("\r\n");
  245. sb.append("echo \"Hostname\"=\"%cname%\" >> c:\\windows\\reg.reg");
  246. sb.append("\r\n");
  247. sb.append("echo [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon] >> c:\\windows\\reg.reg");
  248. sb.append("\r\n");
  249. sb.append("echo \"DefaultDomainName\"=\"%cname%\" >> c:\\windows\\reg.reg");
  250. sb.append("\r\n");
  251. sb.append("echo \"AltDefaultDomainName\"=\"%cname%\" >> c:\\windows\\reg.reg");
  252. sb.append("\r\n");
  253. sb.append("regedit /s c:\\windows\\reg.reg");
  254. sb.append("\r\n");
  255. sb.append("exit");
  256. return sb;
  257. }
  258. public String runCMD(String commands) {
  259. String result = "";
  260. try {
  261. Process process = Runtime.getRuntime().exec(commands);
  262. BufferedReader errorReader = new BufferedReader(
  263. new InputStreamReader(process.getInputStream()));
  264. String line = null;
  265. while ((line = errorReader.readLine()) != null) {
  266. result += line + "\n";
  267. }
  268. errorReader.close();
  269. } catch (Exception e) {
  270. e.printStackTrace();
  271. }
  272. return result;
  273. }
  274. public void removeBat(String path) {
  275. File file = new File(path);
  276. if (file.exists()) {
  277. boolean isflag = file.delete();
  278. if (isflag == true){
  279. System.out.println(getLocalTime()+"删除bat成功!");
  280. }
  281. else {
  282. System.out.println(getLocalTime()+"删除bat失败!");
  283. }
  284. } else {
  285. System.out.println(getLocalTime()+"删除bat失败,批处理文件不存在!");
  286. }
  287. }
  288. public String getLocalTime(){
  289. String time ="[";
  290. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  291. time += df.format(new Date()).toString();
  292. time+="]";
  293. return time;
  294. }
  295. }
  296. </span>

这里看主要代码:

  1. public static void StartService(String[] args) {
  2. //启动服务的方法
  3. }</span>
  1. public static void StopService(String[] args) {
  2. //停止服务的方法
  3. }</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服务的更多相关文章

  1. 如何注册java程序为windows服务

    如何注册java 程序为windows 服务 最近想找个软件来控制电脑的关机时间,在网上找了几个,都是可视化界面的可以设置具体的关机时间的软件.由于我想编写的关机程序是运行在别人机器上,只能让该机器在 ...

  2. .NET Core部署Windows服务

    创建 首先你要确保你已经安装了.NET Core 3.0或以上版本. 老版本的Windows服务请看 这篇文章 使用命令行创建:  dotnet new worker 使用Visual Studio创 ...

  3. C#编写的windows服务安装后启动提示“服务启动后又停止了”

    使用C#编写的windows服务安装到服务器上行后进行启动时,总是提示“服务启动后又停止了”. 检查了服务逻辑是没问题,安装在开发本地也是正常,网上查了资料说是可能是服务没有注册,我检查了服务是正常注 ...

  4. netcore项目在Windows部署:使用NSSM部署Windows服务

    NSSM部署Windows服务 1 准备工作 在Windows平台部署Asp.net core应用程序一般采用IIS,但是如果我们的net core应用执行的是定时任务,需要开机自启,稳定运行的话,使 ...

  5. C#基于Quartz.NET实现任务调度并部署Windows服务

    一.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和asp ...

  6. 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务

    经常看到一些人在调试 Windows 服务时,很执著的在附加进程后调试!其实 .Net 编写的 Windows 应用程序,包括 Windows 服务都可以编译成 Console 程序!甚至于 ASP. ...

  7. Java Service Wrapper 发布Java程序为Windows服务

    下载Windows版本:https://www.krenger.ch/blog/java-service-wrapper-3-5-37-for-windows-x64/ 转自:F:\java\bhGe ...

  8. 编写C# Windows服务,用于杀死Zsd.exe进程

    最近经常在我的xp系统进程中出现Zsd.exe进程.刚开始他占用内存不是很大.但是过了一段时间就会变成几百M 机器就会变得很卡,网上说Zsd可能是病毒.所以我就想要不写一个Windows服务,让他每隔 ...

  9. 使用nssm部署windows服务启动应用

    swoole和workerman他们都可以实现即时通信的功能,这里我简单的就workman作为windows服务器启动为例说哈吧.直接进入正题: 下载这个聊天室项目 workerman聊天室 http ...

随机推荐

  1. 如何删除VS2015中的OpenCV的配置

    首先,在C盘--用户--AppData--Local--Microsoft--MSBuild--v4.0  路径下,找到  Microsoft.Cpp.Win32.user  文件,用记事本打开,如下 ...

  2. JS实现 类似图片3D效果

    其实这样的效果 目前很多网站上都有 其实以前也写过一个 只是当时代码只是为了实现而已,代码很乱,所以现在有业余时间研究了下,其实也并没有什么特殊地方 很类似于左右控制按钮切换图片的思路.效果如下: 可 ...

  3. 【转】系统去掉 Android 4.4.2 的StatusBar和NavigationBar

    系统Hide Status Bar frameworks/base/core/res/res/values/dimens.xml 把  <dimen name="status_bar_ ...

  4. scrollIntoView()的用法

    scrollIntoView是一个与页面(容器)滚动相关的API(官方解释),该API只有boolean类型的参数能得到良好的支持(firefox 36+都支持),所以在这里只讨论参数Boolean类 ...

  5. 清北学堂寒假集训DAY1

    第一天,上午讲了些基本的技巧和简单算法,主要就是适应这里. 中午跑到食堂吃了顿“饭”(我并没有挖苦233333),然后回宿舍休息休息 因为 迎接我们的是模拟啊啊啊啊啊阿 下午题一发下来,并没有想象中的 ...

  6. Android 将拼接好并加上边框的图片保存到内存卡中

    通过前两篇文章,问们学会了怎样拼接图片.给拼接好的图片加上边框样式,但这还不够,忙活了大半天 终于拼接好并给图片美化了,但是程序一旦推出,之前做的工作都白费了.这时我们会想,能不能把拼接好的图片保存起 ...

  7. 【hdu4405】AeroplaneChess

    题目大意:问从0到n所花费时间平均时间.每次有投骰子,投到几就走几步.原题还有坐飞机 #include<iostream> #include<cmath> #include&l ...

  8. (转)Centos7 修改硬件时间和系统时间

    查看硬件时间 [root@localhost ~]# hwclock --show Tue 13 Jun 2017 02:11:12 AM CST -0.848845 seconds 1 2 可以看出 ...

  9. Controller中添加一个异步的Action

    给一段示例代码: public Task<ActionResult> TbReport(string code) { return Task.Factory.StartNew(() =&g ...

  10. Android导入AS工程

     AS  导入工程 还得 新建工程贴代码