当我从 eclipse 运行 中使用 Swing JDialog 但无法从 windows service(services.msc) 工作时,Swing JDialog 显示正常

Swing JDialog is showing fine when I run it from eclipse but not working from windows service(services.msc)

我有一个 java 应用程序,它在一定的时间间隔内 运行s 并显示一个弹出窗口(由 java swing 制作)。当我 运行 来自 eclipse 的应用程序时,它工作正常。在我使用 java -jar 命令创建了一个 jar 并 运行 它之后,它也工作正常。但是当我 运行 来自 windows service(services.msc) Popup window 的 jar 文件没有出现时,除了 popup 所有工作正常,例如记录数据获取等。 我没有找到任何解决方案,我已经应用了堆栈溢出中的所有解决方案,但问题仍然存在。

我把所有的信息都贴出来了

提前致谢

Java代码(该方法会间隔调用)

public static void showUserMsg(final int MsgId, String msgText) {
        logger.info("Entry in showUserMsg to show notification");
        logger.info("Message: " + msgText);

        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        final int screenWidth = (int) dim.getWidth();
        final int screenHeight = (int) dim.getHeight();
        try {
//          JDialog.setDefaultLookAndFeelDecorated(true);
            final JDialog dialog = new JDialog(new JFrame());
            dialog.setTitle("You have message");
            dialog.setAutoRequestFocus(false);
//          dialog.getLayeredPane().getComponent(1).setFont(new Font("Lucida",Font.PLAIN,18)); 
            dialog.setAlwaysOnTop(true);
            dialog.setVisible(true);
            dialog.setSize(600, 450);
            dialog.setLocation(screenWidth / 2 - 250 + 171, screenHeight / 2 - 250);
            dialog.setResizable(true);
            dialog.setModal(false);
            dialog.setModalityType(Dialog.ModalityType.MODELESS);
            dialog.requestFocus();
            final Image img = ImageIO.read(EcsApplication.class.getResource("icons/notify.png"));
            dialog.setIconImage(img);

            logger.info("Dialog location: " + dialog.getLocation());

            Container pane = dialog.getContentPane();
            JTextPane contentLabel = new JTextPane();
            contentLabel.setText("\n\n\n\n\n" + msgText);
            contentLabel.setEditable(false);
            contentLabel.setVisible(true);
            contentLabel.setFont(new Font("Verdana", Font.ROMAN_BASELINE, 18));
            contentLabel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
            contentLabel.setBounds(100, 100, 300, 200);
            JButton okButton = new JButton("Yes, I have read the message");

            okButton.setBounds(120, 330, 400, 50);
            okButton.setFont(new Font("Verdana", Font.ROMAN_BASELINE, 18));
            okButton.setBorder(BorderFactory.createLineBorder(new Color(68, 155, 221), 1));
            okButton.setBackground(new Color(144, 186, 227));
            okButton.setFocusable(true);
            okButton.setVisible(true);

            StyledDocument doc = contentLabel.getStyledDocument();
            SimpleAttributeSet center = new SimpleAttributeSet();
            StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
            doc.setParagraphAttributes(0, doc.getLength(), center, false);

            pane.add(okButton);
            pane.add(contentLabel);

            dialog.addWindowListener(new WindowListener() {

                @Override
                public void windowOpened(WindowEvent e) {
                }

                @Override
                public void windowClosing(WindowEvent e) {
                    logger.info("windowClosing event");
                    try {
                        statusByMsgId(MsgId);
                        JDialog warning = new JDialog();
                        warning.setTitle("Information");
                        warning.setAlwaysOnTop(true);
                        warning.setVisible(true);
                        warning.setSize(300, 150);
                        warning.setLocation(screenWidth / 2 - 150, screenHeight / 2 - 150);
                        warning.setResizable(false);
                        warning.setModal(true);
                        warning.requestFocus();
                        warning.setIconImage(img);

                        Container pane = warning.getContentPane();
                        pane.setBounds(100, 100, 100, 100);
                        JTextPane warningMsg = new JTextPane();
                        warningMsg.setText("You have read the message");
                        warningMsg.setEditable(false);
                        warningMsg.setVisible(true);
                        warningMsg.setBounds(100, 100, 300, 200);

                        warningMsg.setFont(new Font("Verdana", Font.ROMAN_BASELINE, 14));

                        StyledDocument doc1 = warningMsg.getStyledDocument();
                        SimpleAttributeSet center1 = new SimpleAttributeSet();
                        StyleConstants.setAlignment(center1, StyleConstants.ALIGN_CENTER);
                        doc1.setParagraphAttributes(0, doc1.getLength(), center1, false);

                        pane.add(warningMsg);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        logger.error(ex.getMessage(), ex);
                    }

                }

                @Override
                public void windowClosed(WindowEvent e) {
                }

                @Override
                public void windowIconified(WindowEvent e) {
                }

                @Override
                public void windowDeiconified(WindowEvent e) {
                }

                @Override
                public void windowActivated(WindowEvent e) {
                }

                @Override
                public void windowDeactivated(WindowEvent e) {
                }
            });

            okButton.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    logger.info("OK button clicked.");
                    try {
                        statusByMsgId(MsgId);
                    } catch (Exception ex) {
                        ex.printStackTrace();
//                      InfoLogger.printInfo(EcsService.class, "showUserMsg", "Dialog box not loaded.");
//                      InfoLogger.printExceptionLog("EcsService", "showUserMsg", ex);

                        logger.error(ex.getMessage(), ex);

                    }

                    dialog.setVisible(false);

                }

            });

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        logger.info("Exit in showUserMsg");
    }


创建服务的文件夹结构:

在 classes 文件夹中 java class 文件存在 :

public class EcsClientService
{
    Process proc;
    private static EcsClientService serviceInstance;
    private boolean stopped;
    
    public EcsClientService() {
        this.stopped = false;
    }
    
    public static void windowsService(final String[] array) {
        String anObject = "start";
        if (array.length > 0) {
            anObject = array[0];
        }
        if ("start".equals(anObject)) {
            EcsClientService.serviceInstance.start();
        }
        else {
            EcsClientService.serviceInstance.stop();
        }
    }
    
    public void start() {
        this.stopped = false;
        try {
            System.out.println("currentDirectory>>> " + new File(EcsClientService.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile().getAbsolutePath().replace("%20", " "));
            this.proc = Runtime.getRuntime().exec("cmd.exe /c start ECSClientService.bat");
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        while (!this.stopped) {
            synchronized (this) {
                try {
                    this.wait(60000L);
                }
                catch (InterruptedException ex2) {}
            }
        }
    }
    
    public void stop() {
        this.stopped = true;
        synchronized (this) {
            this.notify();
        }
        try {
            Runtime.getRuntime().exec("wmic Path win32_process Where \"CommandLine Like '%ECSClientService.bat%' OR CommandLine Like '%-jar ECSClientService.jar%'\" Call Terminate");
        }
        catch (Exception ex) {}
    }
    
    static {
        EcsClientService.serviceInstance = new EcsClientService();
    }
}

InstallService.bat

for /f %%i in ("%20") do set curpath=%%~dpi

common\ecsClient.exe //DS//ECSClientService

common\ecsClient.exe //IS//ECSClientService --Install=%curpath%\common\ecsClient.exe --Description="Employee Communication Service" --Jvm=auto --Classpath=%curpath%\common\classes --StartMode=jvm --StartClass=EcsClientService --StartMethod=windowsService --StartParams=start --StopMode=jvm --StopClass=EcsClientService --StopMethod=windowsService --StopParams=stop --StopMode=jvm --Startup=auto --LogPath=common\logs --StdOutput=auto --StdError=auto


pause


StartService.bat

common\ecsClient.exe //ES//ECSClientService

StopService.bat

common\ecsClient.exe //SS//ECSClientService

UninstallService.bat

common\ecsClient.exe //DS//ECSClientService

ECSClientService.bat

@ECHO OFF
SET CampaignArg=%1
for /f %%i in ("%0") do set curpath=%%~dpi
cd /d %curpath%
java -jar ECSClientService.jar %CampaignArg%
pause

我相信你的问题不在Java。 AFAIK 服务 运行 在后台 - 无论用户是否登录。因此他们通常无法访问 GUI。

如果您的应用程序应 运行 在后台但在用户上下文中,也许您想将您的应用程序移动到自动启动程序文件夹,以便 Windows 将在用户登录时启动它。