服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

将java程序变成windows系统服务

  近买了一台机器做个source服务器和异地的几个朋友一起做点东西玩玩。但是由于用的是电信的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++。但是难道就没有办法把java程序变成windows系统服务吗?在java的世界里基本上是没有不可能的事,objectweb forge上有个项目叫javaservice就是用来把java程序注册成系统服务的。于是下来看了一下:

  一试--失败

  二试--不成功

  三试--...

  ...
  ...

  放弃!

  老子自己做了,其实有了上面的instsrv和srvany其实就差一个可执行文件了。于是我用jbuilder把我的jar包做成了一个假的exe文件。

  我的dns更新程序如下:
package org.mstar.dns;

import java.util.timertask;
import org.apache.commons.httpclient.httpclient;
import org.apache.commons.httpclient.methods.getmethod;
import org.apache.commons.httpclient.httpstatus;
import org.apache.commons.httpclient.httpexception;
import java.io.ioexception;
import java.util.*;
import org.apache.commons.logging.*;
import org.apache.commons.httpclient.credentials;
import org.apache.commons.httpclient.usernamepasswordcredentials;
import org.apache.commons.httpclient.auth.authscope;
import java.text.simpledateformat;

public class refresher {
 private static log log = logfactory.getlog(refresher.class);
 public refresher() {
  timer timer = new timer();
  timer.schedule(new refreshtask(), 0, 60000);
 }

 class refreshtask extends timertask {
  static final string url ="http://members.3322.org/dyndns/update?system=dyndns&hostname=zjumty.3322.org";

  public void run() {
   httpclient client = new httpclient();
   client.getparams().setauthenticationpreemptive(true);
   credentials defaultcreds = new usernamepasswordcredentials("username", "password");
   //此处我要保密
   client.getstate().setcredentials(new authscope("members.3322.org",
     80, authscope.any_realm), defaultcreds);
   getmethod method = new getmethod(url);
   try {
    int statuscode = client.executemethod(method);
    if (statuscode != httpstatus.sc_ok) {
     log.error("method failed: " + method.getstatusline());
    }
    date date = calendar.getinstance().gettime();
    simpledateformat fmt = new simpledateformat("yyyy/mm/dd hh:mm:ss");
    byte[] responsebody = method.getresponsebody();
    log.info(fmt.format(date) + " -- " + new string(responsebody));
   } catch (httpexception e) {
    log.error("fatal protocol violation: " + e.getmessage());
    e.printstacktrace();
   } catch (ioexception e) {
    log.error("fatal transport error: " + e.getmessage());
    e.printstacktrace();
   } finally {
    method.releaseconnection();
   }
  }
 }

 public static void main(string[] args) {
  refresher refresher = new refresher();
 }
}

  其实就是用jakarta的httpclient来请求一个url就可以了。

  于是我现在有了我的refresher.exe。当然你的系统上一定要有jvm才能运行(废话)。为了运行方便我是把运行时的jar包,如logger.jar,httpclient.jar等打在我的jar包里了。

  接下来就是把它搞成系统服务了。

  第一步:instsrv refrehser c:/program files/windows resource kits/tools/srvany.exe

  第二步:regedit打开注册表

  第三步:进入hkey_local_machine/system/currentcontrolset/services/refrehser

  第四步:右键-新建-项 填入 parameters

  第五步:打开parameters,右键-新建-字符串值 application

  第六步:双击application 填入 c:/refresher.exe

  弟七步:启动refresher服务。

  一切都ok了。

  在parameters里还可以添加很多键值:

  appdirectory 工作目录

  appparameters 你的应用程序的参数。(我可以把我上面程序做成可以接受参数的,就更通用了)

  appenvironment 运行环境变量。

  值现在作为java程序员的你也可以为自己系统添加一些动能了,赶快去做吧!

扫描关注微信公众号