当我从 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 将在用户登录时启动它。
我有一个 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 将在用户登录时启动它。