Определить, выполняется ли приложение Java через сеанс RDP?

Как я могу определить, запускается ли мое приложение Swing из сеанса Windows RDP?

Предпочтительно решение только для Java, но приложение гарантированно будет работать в Windows, поэтому я не против раскошелиться.


person Allain Lalonde    schedule 06.01.2010    source источник


Ответы (3)


Я думаю, вам придется вызывать собственные библиотеки Windows, чтобы осуществить это. Попробуйте что-то вроде этого:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.*; 
import com.sun.jna.examples.win32.Kernel32;

...

public static boolean isLocalSession() {
  Kernel32 kernel32;
  IntByReference pSessionId;
  int consoleSessionId;
  Kernel32 lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
  pSessionId = new IntByReference();

  if (lib.ProcessIdToSessionId(lib.GetCurrentProcessId(), pSessionId)) {
    consoleSessionId = lib.WTSGetActiveConsoleSessionId();
    return (consoleSessionId != 0xFFFFFFFF && consoleSessionId == pSessionId.getValue());
  } else return false;
}

Это странное условие для consoleSessionId взято из документации по WTSGetActiveConsoleSessionId, в котором говорится:

Возвращаемое значение

Идентификатор сеанса, подключенного к физической консоли. Если к физической консоли не подключен сеанс (например, если сеанс физической консоли находится в процессе присоединения или отсоединения), эта функция возвращает 0xFFFFFFFF.

person John Feminella    schedule 06.01.2010
comment
в каком пакете/библиотеке находятся эти типы? (т.е. Kernel32, IntByReference) - person Trevor Harrison; 06.01.2010
comment
Ой, извините. Добавил импорт. Примечание. Я не проверял это. - person John Feminella; 06.01.2010

Приведенные выше ответы могут работать, но кажутся излишне сложными. Вы можете просто прочитать переменную среды Windows «имя сеанса», чтобы обнаружить сеансы RDP. Значение этой переменной среды будет «Консоль» для обычного локального сеанса. Для сеанса RDP он будет содержать фразу «RDP». Достаточно просто проверить это.

public static boolean isRemoteDesktopSession() {
   System.getenv("sessionname").contains("RDP");
}

Протестировано и подтверждено, что он работает под Windows7 64bit. Одна проблема, которую я заметил при использовании этого метода, заключается в том, что значения переменных среды, считанные из System.getenv(), не изменяются после запуска JVM. Таким образом, если процесс JVM был запущен сеансом консоли, но затем к нему обратился сеанс RDP, дальнейшие вызовы System.getenv("sessionname") по-прежнему возвращают "Консоль".

person Isaiah Simpson    schedule 24.04.2011

Попробуйте использовать NativeCall ( http://johannburkard.de/software/nativecall/ )

Все, что вам нужно, это 2 jar плюс 1 DLL в пути к классам.

Быстрый тест:

import java.io.IOException;
import com.eaio.nativecall.*;

public class WindowsUtils {

public static final int SM_REMOTESESSION = 4096;  // remote session

  public static boolean isRemote() throws SecurityException, UnsatisfiedLinkError, 
  UnsupportedOperationException, IOException 
  {
    NativeCall.init();
    IntCall ic = null;
    ic = new IntCall("user32", "GetSystemMetrics"); 
    int rc = ic.executeCall(new Integer(SM_REMOTESESSION));
    if (ic != null) ic.destroy();
    return (rc > 0);
  }

  public static void main(String ... args) throws Exception {
    System.out.println(WindowsUtils.isRemote());
  }
}
person RealHowTo    schedule 06.01.2010