zoukankan      html  css  js  c++  java
  • 如何注册java程序为windows服务

    最近想找个软件来控制电脑的关机时间,在网上找了几个,都是可视化界面的可以设置具体的关机时间的软件。由于我想编写的关机程序是运行在别人机器上,只能让该机器在晚上17 点到23 点25 分才上网,到了23 点25 分就可以自动关机。为了让别人感觉不到这个软件的“存在”(免得使用者自己关闭定时关机软件),所以我想把关机软件注册为服务的方式,运行在后台。这里介绍下如何利用javaService 软件把java 程序注册为windows 服务。
    一、  利用javaService 注册java 程序为windows 服务
    [1] 下载javaService
    访问网址http://javaservice.objectweb.org/ 下载windows 版本的javaService 文件,我下载的是JavaService-2.0.10.rar ,目前最新的版本就是“2.0.10 ”。
    [2] 安装javaService
    解压我们下载下来的javaServices 到一个目录,我是解压到目录“D:/software/JavaService-2.0.10 ”下(解压到任何目录都可以,最好别解压到中文目录,省的出现问题 )
    [3] 编写定时关机代码,见第二章的定时关机代码
    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” 目录下。
    [4] 注册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 ”命令来查看所有服务,并可以对服务的启动类型(自动启动还是手动启动等)进行修改。
    [5] 测试
    1)  启动服务
    当我们注册完服务后,我们可以通过命令“net start MyShutDownService ”来启动该服务,服务启动后会在D 盘根目录生成my_shutdown.log 日志文件。
    2)  关闭服务
    如果我们要关闭服务,可以通过命令“net stop MyShutDownService ”来关闭该服务。
    3)  删除服务
    当我们想删除该服务时,可以使用命令“sc delete MyShutDownService ”来删除该服务。
    二、  定时关机代码
    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;
           }
        }
    }
  • 相关阅读:
    卷积神经网路计算公式
    Jupyter Notebook
    vim batch copy -- copy between row1 and row2 to row3
    Intellij 快速复制单行快捷键
    Exception in thread "main" java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
    Mac 下查看隐藏文件
    Mac 连接 mysql
    CC++JavaPython 求字符串长度
    LeetCode-1309 Decrypt String from Alphabet to Integer Mapping
    ❀LeetCode❀-1374. Generate a String With Characters That Have Odd Counts
  • 原文地址:https://www.cnblogs.com/top5/p/2521496.html
Copyright © 2011-2022 走看看