3

背景

SendKeys()用来向活动窗口发送键盘命令,但是当应用程序通过 RemoteApp 运行时,我没有找到子窗口的运气。当我在本地运行应用程序时,这一切都按预期工作。

Microsoft RemoteApp允许用户通过 RDP 协议连接到应用程序,但它不会显示整个远程虚拟机,而只是显示应用程序窗口。对于最终用户而言,在 RemoteApp 下运行的应用程序与在其桌面上运行的应用程序之间没有区别。

我一直在使用 ManagedSpy 来确定 .NET 应用程序窗口的类名,以便我可以使用 Win32 API 函数FindWindowEx使其中一个子窗口处于活动状态,并且效果很好。但是,当应用程序通过 RemoteApp 运行时,我遇到了问题。

我仍然可以使用 .NETProcess.GetProcessesByName()来查找应用程序,我只需要调用它mstsc.exe

IntPtr hwndChild = IntPtr.Zero;
Process[] processess = Process.GetProcessesByName("mstsc");
IntPtr appHandle = IntPtr.Zero;

foreach (Process p in processess)
{
    if ((p.MainWindowHandle != IntPtr.Zero))
    {
        appHandle = p.MainWindowHandle;
    }
}

if (appHandle == IntPtr.Zero)
{
    MessageBox.Show("Application is not Running.");
    return;
}

但是,我不能FindWindowEx以相同的方式使用。这个问题围绕着这个展开。

为了让非托管代码告诉我哪些窗口mstsc.exe处于活动状态,我使用了 Spy++,但mstsc.exe它返回了一个不同的类名,称为RAIL_WINDOW

替代文字

这是我用来查找子窗口的代码:

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
hwndChild = FindWindowEx(appHandle, IntPtr.Zero, "RAIL_WINDOW", "MyApplication (Remote)");
SetForegroundWindow(hwndChild);

问题

  1. 我可以使用 Spy++ 突出显示 RemoteApp 版本的应用程序中的活动子窗口,我得到了RAIL_WINDOW,但我似乎无法以编程方式访问此窗口。鉴于上面的代码,我缺少什么能够做到这一点?

  2. 是否有其他方法可以将键盘敲击发送到通过 Remote App 运行的应用程序?

4

3 回答 3

2

知道微软是如何做事的,我敢打赌,“铁路窗口”只不过是一个愚蠢的本地代理,它不会费心响应 SendKeys 发送的内容。我没看过,但我敢打赌最终会发送 WM_CHAR 消息,愚蠢的代理可能不会费心响应。相反,尝试手动发送 WM_KEYUP 和 WM_KEYDOWN 消息,看看是否可行,因为我希望它会传输这些和鼠标点击(以及其他什么)而不是翻译版本。

于 2010-10-05T21:45:45.287 回答
0

What commands are you sending using SendKeys()?

It may be better to look for an alternative solution instead of using `SendKeys()'.

于 2010-10-05T10:32:48.313 回答
0

您可能可以利用处理 IMsTscAxEvents:: OnRemoteWindowDisplayed事件,在正确的时间为您提供正确的窗口句柄,而无需调用 FindWindowEx 等。

于 2014-07-28T18:00:23.050 回答