我正在编写一个基本上在系统托盘中运行的桌面Java应用程序。此应用程序可以接受命令行参数。如果有一个应用程序实例正在运行,而另一个实例是使用命令行参数调用的,则它只是将其传递给系统托盘中的正在运行的进程。
我很遗憾如何实现这个?我见过一些应用程序,但我不记得名字了。我要传递的只是字符串参数然后退出。
答案 0 :(得分:2)
实施此解决方案有两个部分:
1和2都可以使用套接字同时完成。
您可以做的是让您的程序在程序启动时收听端口。当您启动该程序的另一个实例时,它将尝试侦听同一个端口,如果该端口被占用,您可以假设已经有一个程序实例正在运行。当然,您应该选择任何应用程序通常不使用的端口。
然后,如果程序的实例已经启动,只需使用套接字传递String参数。
答案 1 :(得分:2)
换句话说,您希望您的应用程序成为单身人士。当用户尝试运行另一个应用程序实例时,它应该向已有的应用程序发送某种命令。
您可以按照以下方式执行此操作。
应用程序启动时应打开服务器套接字到您选择的端口。 如果成功,就应该开始。这是您的应用程序的第一个实例。 如果失败则意味着端口已经忙,所以应用程序的其他实例正在监听它。在这种情况下,连接到此套接字,发送命令并终止。
选择端口号时要小心。它应该足够高(> 10000)并且不应该被任何其他流行的应用程序使用。选择一些号码,然后尝试google它。
答案 2 :(得分:1)
基本上,我们的想法是在启动时绑定本地端口,如果失败连接到它并发送参数。
public class StartOnce {
public static void main(String args[]) throws IOException {
SocketAddress addr = new InetSocketAddress("127.0.0.1", 9999);
try {
ServerSocket ss = new ServerSocket();
// tries to bind to localhost:9999
ss.bind(addr);
// Ok, I'm the first instance, listen for other instances for update.
while(true) {
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
s.close();
}
} catch (BindException e) {
// BindException, tries to send message to the first instance.
System.out.println("Another instance is running. Say hi.");
Socket s = new Socket();
s.connect(addr);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println("Hello.");
for (String arg : args) {
pw.println(arg);
}
pw.close();
s.close();
}
}
}
答案 3 :(得分:0)
有多种方法可以实现这一目标。在Java中,您可以使用JMS来做这样的事情。如果您使用的是Spring,那么就有模板。 这是关于如何开始使用JMS的tutorial。
或者您可以使用套接字,甚至RMI来在多个进程中交换数据。
答案 4 :(得分:0)
您需要执行某种进程间通信。有许多技术可用于实现这一目标,包括:
(写入文件对于IPC来说是一个不好的选择,除非你使用像POSIX命名管道而不是普通文件这样的东西。)
答案 5 :(得分:0)
Another option is to use cache that runs in a separate process.