JavaExe 和 Java 应用程序作为 Windows 系统服务与桌面交互

5

请求:

这是我当地Java开发人员经常面临的一个问题。我已经被卡住很多天了。我搜索了很多,阅读了文档,阅读了与JavaExe相关的所有stackoverflow问题。如果您以前做过类似的事情并且有全面的答案,请回复。我将非常感激社区!

场景:

我正在使用JavaExe作为系统服务运行应用程序,在桌面交互功能方面。确切的说,我有一个捕捉桌面截图的应用程序。我希望它在任何用户登录时(作为管理员)运行,所以没有人可以停止它。

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

我已经搜索了很多并发现JavaExe可以工作(通过观察其示例)

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

问题:

根据我的研究,

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

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

我需要放置任何类或引用/导入吗?如何做到?

编辑:

我的代码在.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文件是可能的。
2个回答

2

在您的情况下,您应该拥有:

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"
            };
    }
}

请查看现在可以工作但不与桌面交互的编辑代码。 - Masood Ahmad
JOptionPane.showMessageDialog 无法从服务中调用,只能从 TaskbarManagement 中调用。 - bb67
如何使用Java中的Robot.class进行操作,包括鼠标、键盘和屏幕事件以及移动/捕获。 - Masood Ahmad
嗯...好的。我已经阅读了你的许多答案bb67。JavaExe是所有选项中最简单和高效的吗?还有其他推荐吗?@djangofan - Masood Ahmad
@bb67 从桌面获取信息会类似吗?比如通过Java中的Robot.class捕获桌面屏幕?你已经讲得很全面了。它与向桌面显示输入不同,而是从桌面获取信息。这样做有什么不同吗?有代码吗?最后一个问题 :) - Masood Ahmad
显示剩余11条评论

1

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

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

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

这回答了您的问题吗?


我是指重新编辑你的答案,让我和其他人能够学习和掌握方法论。(帮助整个社区) - Masood Ahmad
所有内容都在JavaExe的文档和示例中清楚地解释了。 - bb67
建议将服务类和UI类分开。只从XXX_TaskbarManagement调用您的UI类或方法。 - bb67
这只是一个示例变量,仅用于此示例。 - bb67
你可以在serviceInit()中放置任何想要的内容,唯一的限制是该方法必须在30秒内返回(由Windows强制执行)。 - bb67
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接