【问题标题】:JavaExe and Java application as windows system service interactive to desktopJavaExe 和 Java 应用程序作为与桌面交互的 Windows 系统服务
【发布时间】:2023-11-25 07:58:01
【问题描述】:

请求:

这是我所在地区的 Java 开发人员面临的一个非常常见的问题。我真的被困了很多天。搜索并尝试了很多,阅读文档。阅读所有与 JavaExe 相关的 * 问题。请仅在您以前做过类似的事情并有全面答案的情况下回复。我会非常感谢社区!

塞纳里奥:

我正在使用 JavaExe 将应用程序作为 系统服务 在桌面 交互式 功能中运行。 确切地说,我有一个捕获桌面屏幕截图的应用程序。我希望它在任何用户登录时运行(以管理员身份),因此没有人可以阻止它。

我有一个 myapp.jar、settings.txt 和一个 lib 目录。

我搜索了很多,发现 JavaExe 有效(通过观看它的示例)

如果有人有更好的方法。请说明。

问题:

根据我的研究,

  1. 您必须创建一个名称类似于 .exe 的 .properties 文件,并在此文件中写入 "RunType = 1"

  2. 您在主类中定义了一个静态方法:serviceInit()

我需要放置任何类或引用/导入吗?怎么样?

编辑:

我在 works 下面的代码可以作为独立的 .jar 和 javaExe.exe 使用。

它现在提供系统服务并由SYSTEM用户运行。但它不能与桌面交互。即它没有显示任何 GUI。

package temp;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;


public class Temp {


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {


          serviceInit();

    }

    public static boolean serviceInit(){

        new Thread(){
            public void run(){
                Integer i = 0;
                while(i < 999999999){
                    JOptionPane.showMessageDialog(null,i);
                    i++;

                }
            }
        }.start();

        return true;
   }




}

而且我认为将 .jar、lib 目录和 settings.txt 捆绑到一个 .exe 中是不可能的?

【问题讨论】:

    标签: java windows-7 windows-services interactive java-service-wrapper


    【解决方案1】:

    你应该有:

    public class MyApp_ServiceManagement
    {
        static boolean isMsgToDisplay = false;
    
        /////////////////////////////
        public static boolean serviceInit()
        {
            (new Thread()
            {
                public void run()
                {
                    for(int i=0;i < 6;i++)
                    {
                         try { sleep(5*1000); }
                         catch(Exception ex) {}
    
                         isMsgToDisplay = true;
                    }
                }
            }).start();
    
            return true;
        }
    
        /// is Data ready to be send to the UI ?
        public static boolean serviceIsDataForUI()
        {
            return isMsgToDisplay;
        }
    
        /// Data to be send to the UI
        public static Serializable serviceDataForUI()
        {
            isMsgToDisplay = false;
            return "hello, I am an interactive Service";
        }
    }
    

    对于 UI 部分:

    public class MyApp_TaskbarManagement
    {
        /// To show (or not) the icon in tray
        public static boolean taskIsShow()
        {
            return false;
        }
    
        /// Receive the message from Service
        public static void taskDataFromService(Serializable data)
        {
            JOptionPane.showMessageDialog(null, data);
        }
    
        /// descr of UI
        public static String[] taskGetInfo()
        {
            return new String[]
                {
                    "UI part of Service"
                };
        }
    }
    

    【讨论】:

    • 而且我认为将.jar、lib 目录和settings.txt 捆绑到一个.exe 中是不可能的?
    • 请查看现在可以工作但不能与桌面交互的编辑代码。
    • 无法从服务调用 JOptionPane.showMessageDialog,只能从 TaskbarManagement 调用
    • 以及如何使用 Java 的 Robot.class 做事。鼠标和键盘以及屏幕事件和移动/捕获
    • @djangofan 很棒。我希望没有非管理员可以停止服务。
    【解决方案2】:

    main() 方法永远不会在服务模式下被调用(除了一种特殊情况),但是如果你想保留你的 main() 方法,你必须在 serviceInit() 中调用 main()。

    将 serviceInit() 放入您的主类或另一个名为 XXX_ServiceManagement 的类中,其中 XXX 是您的主类的名称。

    然后,serviceInit() 必须在 30 秒延迟之前返回。 不要放一个无限循环,...在里面。 将您的代码放入一个线程中,并从 serviceInit() (或 main)启动它

    你的问题的答案是什么?

    【讨论】:

    • 你能详细说明一下吗?除了 myapp,我还需要任何外部类吗? serviceinit() 就像我的问题的edit-1。什么是应用程序?它在哪里定义?
    • 我的意思是重新编辑您的答案,以便我和其他人学习和掌握方法。 (帮助整个社区)
    • JavaExe及其示例的文档中都有明确说明
    • 建议将服务类和UI类分开。仅从 XXX_TaskbarManagement 调用您的 UI 类或方法。
    • 这是一个示例变量,仅用于本示例。