窗口在服务模式下没有文本

时间:2013-04-16 12:34:33

标签: c# winapi

我正在研究批量引擎,因为我们有第三方软件,它是需要批量运行的客户端软件

我使用此代码枚举进程Id的

public IEnumerable<int> EnumerateProcessWindowHandles(int processId)
{
    var handles = new List<IntPtr>();
    try
    {
        foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
            Win32.EnumThreadWindows(thread.Id,
                                    (hWnd, lParam) =>
                                        {
                                            handles.Add(hWnd);
                                            return true;
                                        }, IntPtr.Zero);

    }
    catch (Exception e) {}
    return handles.Select(h => (int)h);
}

然后这段代码获取每个窗口的Text

public string GetText(int hWnd)
{
    // Allocate correct string length first
    int length = Win32.GetWindowTextLength(hWnd);
    var sb = new StringBuilder(length + 1);
    Win32.GetWindowText(hWnd, sb, sb.Capacity);
    return sb.ToString();
}

从服务执行程序时,从未找到我正在寻找的窗口,如果我从控制台程序启动它可以工作。如果我尝试从服务启动calc.exe,我会得到计算器窗口,因此可以从服务中获取窗口。从我的服务中侦听calc.exe时的输出

  

2013-04-16 13:52:09;冗长; 23000; 1728; 5592;批处理:窗口   hwnd:8454324;标题:计算器

     

2013-04-16 13:52:09;冗长; 23000; 1728; 5592;批处理:窗口   hwnd:393910;标题:

     

2013-04-16 13:52:09;冗长; 23000; 1728; 5592;批处理:窗口   hwnd:328806;标题:GDI +窗口

     

2013-04-16 13:52:09;信息; 23000; 1728; 5592;批量:   计算器显示

在收听我的真实应用程序时输出

  

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:524976;标题:.NET-BroadcastEventWindow.2.0.0.0.218f99c.0

     

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:524978;标题:GDI +窗口

     

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:590366;标题:

     

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:787088;标题:

     

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:656044;标题:

     

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:721578;标题:

     

2013-04-16 14:25:16;冗长; 23000; 5076; 5140;批处理:窗口   hwnd:590926;名称:

正如你所看到的,大多数hwnds都是无标题的,如果我这样做,但是从控制台模式我得到了

  

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:66672;标题:MSCTFIME UI

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:328694;标题:

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:328754;标题:

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:197656;标题:

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132122;标题:

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132178;标题:.NET-BroadcastEventWindow.2.0.0.0.218f99c.0

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132100;标题:MSCTFIME UI

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132186;标题:默认IME

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132176;标题:GDI +窗口

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:197654;标题:默认IME

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132144;标题:

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132142;标题:

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132140;标题:默认IME

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:459078;标题:任务进度

     

2013-04-16 14:21:08;冗长; 23000; 4864; 4120;控制台:窗口   hwnd:132078;标题:默认IME

我得到更多的hwnds和更多的标题,我感兴趣的窗口是任务进度

这可以解决吗?我正在起诉Process.Start来启动这个过程

1 个答案:

答案 0 :(得分:0)

我假设您使用Vista或更高版本,因为早期版本不会出现此问题。 正如@Damien_The_Unbeliever所说,这是一个session 0 isolation问题。

  

这可以解决吗?我正在起诉Process.Start来启动这个过程

在会话0中启动第三方应用程序(您无法控制其代码)通常是一个坏主意。

  • 您不知道该应用是否设计为在会话0的限制下运行。
  • 安全问题,因为您可以从此会话中对系统造成更大的损害。

使用CreateProcessAsUser注意将STARTUPINFO的lpDesktop成员设置为“Winsta0 \\ default” &安培;通过CreateEnvironmentBlock获得的环境块。 有关如何从C#调用这些内容,请参阅此post

您可以通过WTSQueryUserToken获取用户令牌,会话ID可通过WTSEnumerateSessions或SERVICE_CONTROL_SESSIONCHANGE消息提供给服务。

  

正如你所看到的,大多数人都没有头衔,

您无法检索窗口文本的原因是因为Windows通过发送WM_GETTEXT消息来执行此操作(请参阅msdn上的“备注”部分),当然,由于您的引擎位于服务桌面。

您可以在服务中执行此操作,方法是在您使用用户桌面调用SetThreadDesktop的单独线程中执行操作(请注意,请参阅备注中的警告)。