我正在研究批量引擎,因为我们有第三方软件,它是需要批量运行的客户端软件
我使用此代码枚举进程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来启动这个过程
答案 0 :(得分:0)
我假设您使用Vista或更高版本,因为早期版本不会出现此问题。 正如@Damien_The_Unbeliever所说,这是一个session 0 isolation问题。
这可以解决吗?我正在起诉Process.Start来启动这个过程
在会话0中启动第三方应用程序(您无法控制其代码)通常是一个坏主意。
使用CreateProcessAsUser注意将STARTUPINFO的lpDesktop成员设置为“Winsta0 \\ default” &安培;通过CreateEnvironmentBlock获得的环境块。 有关如何从C#调用这些内容,请参阅此post
您可以通过WTSQueryUserToken获取用户令牌,会话ID可通过WTSEnumerateSessions或SERVICE_CONTROL_SESSIONCHANGE消息提供给服务。
正如你所看到的,大多数人都没有头衔,
您无法检索窗口文本的原因是因为Windows通过发送WM_GETTEXT消息来执行此操作(请参阅msdn上的“备注”部分),当然,由于您的引擎位于服务桌面。
您可以在服务中执行此操作,方法是在您使用用户桌面调用SetThreadDesktop的单独线程中执行操作(请注意,请参阅备注中的警告)。