在进程窗口中进行截屏

6

我想对Windows 7 64位中的进程窗口进行截屏,问题是我总是在下面这行代码中遇到错误:

var bmp = new Bitmap (width, height, PixelFormat.Format32bppArgb);

当出现“无效参数”时,我使用throw来查看错误,发现宽度和高度始终为0。

之前在32位系统中可以正常工作,但是在64位系统中不再有效。

代码如下:

public void CaptureApplication()
{
    string procName = "firefox";

    var proc = Process.GetProcessesByName(procName)[0];
    var rect = new User32.Rect();
    User32.GetWindowRect(proc.MainWindowHandle, ref rect);

    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

    var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    Graphics graphics = Graphics.FromImage(bmp);
    graphics.CopyFromScreen(rect.left, rect.top, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy);

    bmp.Save("c:\\tmp\\test.png", ImageFormat.Png);
}

private class User32
{
    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);
}

我该如何修复这个错误?


3
你还应该检查GetWindowRect的返回值——如果它返回IntPtr.Zero,则在该步骤中出现了错误。 - C.Evenhuis
1
我已经尝试过了,它总是为零,我不明白为什么,在之前我擅长32位。 - Chris
2
通过 GetProcessesByName 返回多少条目?我没有 FireFox,但是使用 GoogleChrome 和 Internet Explorer 进行测试,返回的第 0 个条目的矩形边界全部为 0,但是如果我检查数组中的下一个元素(var proc = Process.GetProcessesByName(procName)[1]),则矩形会有合理的值。在 Internet Explorer 中,我有 1 个实例和 5 个选项卡 - 这会导致返回 5 个进程。另一方面,Chrome 对于单个实例和单个选项卡有 6 个进程。 - PaulF
好的 - 现在你知道有3个进程 - 你需要找到正确的那一个。 - PaulF
@PaulF 我现在安装了 Firefox,并运行了几个实例,但是使用上面的代码工作了...也许我只是碰巧找到了正确的进程。 - M. Schena
显示剩余15条评论
1个回答

2
获取firefox进程的过程将返回一个进程数组,您需要查找具有真实大小矩形的进程,这是主要进程。
Process[] procs = Process.GetProcessesByName(procName);
var rect = new User32.Rect();
int width = 0;
int height = 0:
foreach (Process proc in procs)
{
    User32.GetWindowRect(proc.MainWindowHandle, ref rect);
    width = rect.right - rect.left;
    height = rect.bottom - rect.top;
    // break foreach if an realistic rectangle found => main process found
    if (width != 0 && height != 0)
    {
        break;
    }
}

似乎在Internet Explorer上可以工作(1个实例,4个选项卡)-只有1个具有非零矩形的进程。但是,在Google Chrome(1个实例单个选项卡)中,有7个进程,其中3个大小不为零的矩形(全部相同)-因此无法使用。我没有FireFox,所以无法评论。 - PaulF
@PaulF 做了一些更改,现在允许 0 值,但不允许在矩形中,这更有意义。现在它是否也适用于 Chrome?对我来说,它可以工作,但我在第二个屏幕上打开了 Chrome。 - M. Schena
1
感谢您的帮助。 - Chris
正如我所说的 - 我得到了多个Chrome进程,它们都具有相同的(非零)宽度和高度 - 但如果这对FireFox有效,那就太好了。我发现定位Chrome和IE的正确进程的唯一方法是检查命令行。 - PaulF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接