如何检测我的Swing应用程序是否正在从Windows RDP会话运行?
首选Java解决方案,但保证应用程序在Windows上运行,所以我可以解决这个问题。
答案 0 :(得分:4)
我认为您必须调用本机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。
答案 1 :(得分:4)
上述答案可能有效,但似乎不必要地复杂化。您只需读取Windows的“sessionname”环境变量即可检测RDP会话。对于正常的本地会话,此环境变量的值将为“Console”。对于RDP会话,它将包含短语“RDP”。只需检查一下就足够了。
public static boolean isRemoteDesktopSession() {
System.getenv("sessionname").contains("RDP");
}
经测试并确认在Windows7 64bit下工作。我注意到这个技术的一个问题是,一旦JVM启动,看起来从System.getenv()读取的环境变量值不会改变。因此,如果JVM进程由控制台会话启动,但随后由RDP会话访问,则对System.getenv(“sessionname”)的进一步调用仍将返回“Console”。
答案 2 :(得分:1)
尝试使用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());
}
}