使用Apache Common Daemon实现Windows服务

本文介绍使用Apcahe Common Daemon组件将java程序注册为Windows服务的方法,同样使用这个库来实现服务的有著名的Tomcat,甚至我认为这个项目就是从Tomcat里剥出来的,理由很简单,他们的ICON是一样的。

Apcahe Common Daemon组件包含一个jar文件,两个exe文件。其实这么说是不对的,其实Apcahe Common Daemon组件仅仅只包含一个jar文件,而配合在windows上启动jar的是另一个项目,叫prorun。它仅仅负责在windows上启动jar而在UNIX类OS上有别的工具来完成。

废话不多说,从Apache网站上下载commons-daemon-1.1.0.jar文件,当然你可以是使用maven。添加到项目后,像下面代码一样创建一个实现了Daemon接口的启动类,请忽略自动实现的destroy函数和init函数,在windows平台上,这两个函数不会被调用。而请重点关注startService和stopService两个函数,这是我们公开给外部调用工具prorun的静态接口,我们的程序会从这两个函数进出。

public class ServiceLauncher implements Daemon {
    private static ServiceLauncher launcher;
    private Service service;
    
    @Override
    public void destroy() {}

    @Override
    public void init(DaemonContext arg0) throws DaemonInitException, Exception {}

    @Override
    public void start() throws Exception {
        service = new Service();
        Thread t = new Thread(service);
        t.setDaemon(true);
        t.start();
        t.join();
    }

    @Override
    public void stop() throws Exception {
        service.finish();
    }

    public static void startService(String[] args) {
        launcher = new ServiceLauncher(args);
        launcher.start();
    }

    public static void stopService(String[] args) {      
        launcher.stop();
    }
}

这段代码启动了一个子线程,名字叫service,启动它以后会等待,直到它自己退出。因为外部的执行工具prorun会随时调用stopService来结束服务,所以实际上真正执行任务的service线程和当前的这个线程是被控制者和控制者的关系。也不要轻易的使用kill来杀死service线程,这会导致正在实行的任务中途退出,这不是一个优雅的设计。

至于service线程里的工作属于项目范畴,不做介绍。现在介绍如何使用外部工具来启动这个服务。

首先你得下载prcrun程序包,例如:commons-daemon-1.1.0-bin-windows.zip,解压它会得到两个可执行程序prunsrv.exe和prunmgr.exe,以及一个amd64版本的prunsrv.exe,它应该是64位版本的意思。请注意,如果你使用了32位版本的prunsrv.exe的话,那么你的jvm也必须是32位的,否则无法运行。

得到这两个程序后再将刚才我们写的java程序打包导出位一个可执行jar包,我们假设它叫program.jar,然后和刚才得到的两个程序放在同一个文件夹下。接下来请把prunsrv.exe改名为program.exe,把prunmgr.exe改名为proguramw.exe。你问我为啥要改名?因为我高兴。

 接下来我们需要注册这个jar到windows服务管理器里了,请写一个BAT文件:

@echo off

set EXEC_DIR=%~dp0
set INSTALL_PATH=%EXEC_DIR%program.exe
set JVM_PATH=%EXEC_DIR%\jre\bin\client\jvm.dll

%INSTALL_PATH% //IS//<Service Name> --DisplayName="XXX" --Description="XXX" ^
--Install=%INSTALL_PATH% --Startup=manual --Jvm=%JVM_PATH% ^
--StartMode=jvm --StopMode=jvm ^
--Classpath=%EXEC_DIR%\lib\*;%EXEC_DIR%\* ^
--StartClass=xx.ServiceLauncher --StartParams=%EXEC_DIR% --StartMethod=startService ^
--StopClass=xx.ServiceLauncher  --StopMethod=stopService ^
--LogPath=%EXEC_DIR%\logs --LogPrefix=Service --LogLevel=DEBUG --StdOutput=auto --StdError=auto

if "%errorlevel%" == "0" ( 
    echo Success
) else (
    echo Failed to install Windows Service
)
@echo on
 

在这个BAT里,我们使用program.exe来注册这个jar文件到windows服务管理器里,参数比较多,但是其实管用的主要有这几个:

//IS//<Service Name> 服务名

它会显示在Windows服务管理器中,这是操作服务的唯一的句柄,启动关闭都靠这个名字。

--Startup=manual 启动方式,这是手动,自动是auto

--Jvm=%JVM_PATH% JVM的路径,我们需要jvm.dll

--StartClass=xx.ServiceLauncher --StartParams=%EXEC_DIR% --StartMethod=startService  启动目标包和目标函数,以及传递给这个函数的参数。

--StopClass=xx.ServiceLauncher  --StopMethod=stopService 这是关闭时入口的设置

其他的就不重要了,自己理解吧。但是如何启动这个服务呢,可以到windows服务管理器里手动启动,也可以双击刚才改名的proguramw.exe,它会自动在windows里去找和自己名字一样的widnwos服务,然后弹出界面,你只需要操作界面就可以启动和关闭这个服务了。你也可以使用命令行来操作proguramw.exe启动这个服务,它可以让你把自己隐藏到托盘区域等等。

 

转载于:https://www.cnblogs.com/mubawa/p/9560520.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值