是否有“在终端会话中运行”谎言垫片?

Ian*_*oyd 4 windows remote-desktop

Windows 提供了许多垫片来解决程序中的错误和限制。

Shims 可以就各种事情对程序撒谎

  • 关于 Windows 版本的谎言
  • 关于文件操作失败的谎言
  • 谎报无法打开的注册表项

关于从终端会话(例如远程桌面)运行的软件是否有谎言

我有一个软件可以检测它是否在终端会话中运行并相应地改变其行为。另一个软件拒绝运行,因为它说它根本不受支持。

就像一个拒绝在高于 Windows 2000 的任何系统上运行的程序一样,它可以运行得很好——只要它给自己一个机会。

是否有“终端会话谎言”垫片?


想象一下包含以下内容的伪代码

static class Program
{
   if (System.Windows.Forms.SystemInformation.TerminalServerSession)
   {
       System.Environment.FastFail("We're too lazy to make our software work under TS.");
   }
   ...
}
Run Code Online (Sandbox Code Playgroud)

其他应用程序在终端会话下更改其行为:

//Don't enable animations if we're in a TS window, or on battery
Boolean animationsEnabled = 
        (!System.Windows.Forms.SystemInformation.TerminalServerSession)
        &&
        (System.Windows.Forms.SystemInformation.PowerStatus.PowerLineStatus != 
               PowerLineStatus.Offline);
Run Code Online (Sandbox Code Playgroud)

我希望 Windows 对应用程序撒谎,这样它就不会认为它是在终端会话/远程桌面会话中运行的。


这类似于其他程序不知道如何编写版本检查代码,因此在比 Windows XP 更新的任何程序上都失败:

static class Program
{
   //Make sure we're on Windows 5.0 or later:
   if (!(WinMajorVersion >= 5) && !(WinMinorVersion >= 0))
       FastFail("Requires Windows XP or later");
}
Run Code Online (Sandbox Code Playgroud)

上面的代码提示在 Windows 版本 6.0 上失败 - 这正是版本谎言垫片存在的原因。

Col*_*ard 5

我不相信这是可能的。您的程序可能正在查看的特定标志代码是SM_REMOTESESSION标志。正如 SQLChicken 指出的那样,您可以通过尝试获取控制台会话来为单个用户击败它,这会给您留下SM_REMOTESESSION = 0,但对于多个用户,我认为这是不可能的。

我很欣赏这令人沮丧,但您可能必须与程序供应商合作才能解决此问题。纠正在 TS 下行为不端的软件需要做很多工作,因为它通常是由糟糕的 Windows 心态造成的,即所有计算机都只是大屏幕 PDA,并且不可能有多个用户(而网络确实是为高级用户准备的)。由此引起的问题不仅限于您描述的“无法打扰测试”功能(类似这样:

#include <windows.h>
#pragma comment(lib, "user32.lib")

BOOL IsRemoteSession(void)
{
   return GetSystemMetrics( SM_REMOTESESSION );
}
Run Code Online (Sandbox Code Playgroud)

) 还有共享资源的使用和图形的正确使用(Raymond Chen 讨论了实际上很难做到正确的原因)。

因此,除非您有其他机制来证明该软件可以在多个用户下正常运行,否则我倾向于假设通过SM_REMOTESESSION检查实际上是不够的。