如何检测我的 Swing 应用程序是否正在从 Windows RDP 会话运行?
首选仅限 Java 的解决方案,但该应用程序保证可以在 Windows 上运行,所以我可以接受。
我认为您必须调用本机 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。
上述答案可能有效,但似乎不必要地复杂。您可以简单地读取 Windows 'sessionname' 环境变量来检测 RDP 会话。对于正常的本地会话,此环境变量的值将是“控制台”。对于 RDP 会话,它将包含短语“RDP”。只需检查一下就很容易了。
public static boolean isRemoteDesktopSession() {
System.getenv("sessionname").contains("RDP");
}
Tested and confirmed working under Windows7 64bit. One issue I have noticed with this technique is that it appears that environment variable values as read from System.getenv() do not change once the JVM has started. So if the JVM process was started by a console session, but then accessed by an RDP session, further calls to System.getenv("sessionname") still return 'Console.'
尝试使用 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());
}
}