2011-12-25 2 views
3

Я хотел бы ограничить мое приложение Eclipse-RCP одним экземпляром. Под этим я подразумеваю, что, как только пользователь впервые откроет приложение, он прослушивает порт и для второго доступа он должен открыть предыдущий экземпляр вместо того, чтобы показывать предупреждающее сообщение, такое как «уже экземпляр запущен»Как ограничить приложение Eclipse-RCP одним экземпляром?

Мой код RCP Применение:

ApplicationInstanceListener.java код интерфейса

public interface ApplicationInstanceListener 
{ 
    public void newInstanceCreated(); 
} 

ApplicationInstanceManager.java код

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.UnknownHostException; 


public class ApplicationInstanceManager { 
     private static ApplicationInstanceListener subListener; 

    /** Randomly chosen, but static, high socket number */ 
    public static final int SINGLE_INSTANCE_NETWORK_SOCKET = 2020; 

    /** Must end with newline */ 
    public static final String SINGLE_INSTANCE_SHARED_KEY = "$$NewInstance$$\n"; 

    /** 
    * Registers this instance of the application. 
    * 
    * @return true if first instance, false if not. 
    */ 
    public static boolean registerInstance() { 
     // returnValueonerror should be true if lenient (allows app to run on network error) or false if strict. 
     boolean returnValueonerror = true; 
     // try to open network socket 
     // if success, listen to socket for new instance message, return true 
     // if unable to open, connect to existing and send new instance message, return false 
     try { 
      final ServerSocket socket = new ServerSocket(SINGLE_INSTANCE_NETWORK_SOCKET, 10, InetAddress 
        .getLocalHost()); 
      System.out.println("Listening for application instances on socket " + SINGLE_INSTANCE_NETWORK_SOCKET); 
      Thread instanceListenerThread = new Thread(new Runnable() { 
       public void run() { 
        boolean socketClosed = false; 
        while (!socketClosed) { 
         if (socket.isClosed()) { 
          socketClosed = true; 
         } else { 
          try { 
           Socket client = socket.accept(); 
           BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
           String message = in.readLine(); 
           if (SINGLE_INSTANCE_SHARED_KEY.trim().equals(message.trim())) { 
             System.out.println("Shared key matched - new application instance found"); 
            fireNewInstance(); 
           } 
           in.close(); 
           client.close(); 
          } catch (IOException e) { 
           socketClosed = true; 
          } 
         } 
        } 
       } 
      }); 
      instanceListenerThread.start(); 
      // listen 
     } catch (UnknownHostException e) { 
       System.out.println(e.getMessage()); 
      return returnValueonerror; 
     } catch (IOException e) { 
       System.out.println("Port is already taken. Notifying first instance."); 
      try { 
       Socket clientSocket = new Socket(InetAddress.getLocalHost(), SINGLE_INSTANCE_NETWORK_SOCKET); 
       OutputStream out = clientSocket.getOutputStream(); 
       out.write(SINGLE_INSTANCE_SHARED_KEY.getBytes()); 
       out.close(); 
       clientSocket.close(); 
       System.out.println("Successfully notified first instance."); 
       return false; 
      } catch (UnknownHostException e1) { 
       System.out.println(e.getMessage()); 
       return returnValueonerror; 
      } catch (IOException e1) { 
       System.out.println("Error connecting to local port for single instance notification"); 
       System.out.println(e1.getMessage()); 
       return returnValueonerror; 
      } 

     } 
     return true; 
    } 

    public static void setApplicationInstanceListener(ApplicationInstanceListener listener) { 
     subListener = listener; 
    } 

    private static void fireNewInstance() { 
     if (subListener != null) { 
     subListener.newInstanceCreated(); 
     } 
    } 
} 

Application.java код

import org.eclipse.equinox.app.IApplication; 
import org.eclipse.equinox.app.IApplicationContext; 
import org.eclipse.jface.dialogs.MessageDialog; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.ui.IWorkbench; 
import org.eclipse.ui.PlatformUI; 

/** 
* This class controls all aspects of the application's execution 
*/ 
public class Application implements IApplication { 

     /* 
     * (non-Javadoc) 
     * 
     * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app. 
     * IApplicationContext) 
     */ 
     public Object start(IApplicationContext context) throws Exception { 
       if (!ApplicationInstanceManager.registerInstance()) { 
         // instance already running. 
         System.out 
             .println("Another instance of this application is already running. Exiting."); 
         MessageDialog 
             .openInformation(new Shell(), "Information", 
                 "Another instance of this application is already running. Exiting."); 
         System.exit(0); 
       } 
       Display display = PlatformUI.createDisplay(); 
       try { 
         int returnCode = PlatformUI.createAndRunWorkbench(display, 
             new ApplicationWorkbenchAdvisor()); 
         if (returnCode == PlatformUI.RETURN_RESTART) 
           return IApplication.EXIT_RESTART; 
         else 
           return IApplication.EXIT_OK; 
       } finally { 
         display.dispose(); 
       } 

     } 

     /* 
     * (non-Javadoc) 
     * 
     * @see org.eclipse.equinox.app.IApplication#stop() 
     */ 
     public void stop() { 
       if (!PlatformUI.isWorkbenchRunning()) 
         return; 
       final IWorkbench workbench = PlatformUI.getWorkbench(); 
       final Display display = workbench.getDisplay(); 
       display.syncExec(new Runnable() { 
         public void run() { 
           if (!display.isDisposed()) 
             workbench.close(); 
         } 
       }); 
     } 
} 

Я взял простой RCP приложение с точки зрения в качестве шаблона. Приведенный выше код работает отлично, но не открывает предыдущий экземпляр как скайп или проигрыватель Windows Media Player несмотря на это показывает предупреждение, как показано ниже enter image description here

Как я могу показать или открыть предыдущий экземпляр на втором запуске приложения?

ответ

0

Посмотрите на эту статью: Single instance of RCP application. Автор описывает тот же шаблон использования серверного сокета, о котором вы спрашиваете.

+0

Тип советника в сообщении не может быть разрешен – srk

+0

@raghav: Вы правы, просто создайте его в начале метода 'start()': 'WorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor();' – Kai

0

Я думаю, вы должны просто чередовать уже запущенный экземпляр.
я не знаю, если this или this link может помочь, но вот и все я получил

действительно надеюсь, что это помогает

1

У меня есть приложение, которое делает это то же самое. Фокус в том, что новый экземпляр не может довести старый экземпляр до фронта. Но старый экземпляр может вывести себя на передний план после того, как он свяжется с новым экземпляром.

Так что ваш старый экземпляр нужно вызвать

PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().forceActive(); 

после того, как уведомляет новый экземпляр. Для моего приложения новый экземпляр не показывает сообщение об ошибке, он просто закрывается прозрачно, и старый экземпляр всплывает.

0

В принципе, у вас могут быть такие функции, как eclipse. Eclipse поддерживает файл .lock для блокировки рабочего пространства. Аналогичным образом можно создать пустой файл .lock в рабочем пространстве.

При запуске каждого экземпляра вы должны проверить, присутствует ли файл .lock, а затем продолжить соответственно. Если файл отсутствует, вы должны создать его, чтобы другой экземпляр обнаружил, что рабочее пространство заблокировано.