GDI+ 中发生一般性错误(屏幕截图 SaveAsFile、ExternalException)

A generic error occurred in GDI+ (screenshot SaveAsFile, ExternalException)

你好,我试着浏览了可能有我答案的问题,但 none 有答案。

我正在进行 Web 自动化测试,并尝试在发生错误时截取屏幕截图并将其保存到另一个文件夹中的文件中。

我的程序在页面上搜索元素时超时 30 秒。如果 30 秒后没有找到任何元素,它会获取一个 SS,重新加载页面,然后重试。

第一个截图效果很好。但是在第二次 运行 通过时,它试图将另一个屏幕截图保存到文件夹中,我得到了这个难以置信的模糊错误,这个错误似乎是由一百种不同的原因引起的,所以我不太确定问题出在哪里。

这是我的代码:

public void takeScreenShot()
    {
        string ssPath = _persistencePath += "\Errors";

        string currTime = DateTime.Now.ToString(@"MMM-ddd-d-HH.mm");

        Screenshot ss = ((ITakesScreenshot)_driver).GetScreenshot();

        try
        {
            ss.SaveAsFile(ssPath + "\ERROR-" + currTime + ".png", System.Drawing.Imaging.ImageFormat.Png);
            ssCount = 0;
        }
        catch (System.Runtime.InteropServices.ExternalException)
        {
            ssCount++;

            //error occurs here
            ss.SaveAsFile(ssPath + "\ERROR-" + currTime + "(" + ssCount + ")" + ".png", System.Drawing.Imaging.ImageFormat.Png);
        }

我最初认为问题是它试图保存同名文件,因为如果错误发生在同一分钟,那么文件名是相同的。所以这就是为什么我添加了那个 catch 块,试图在同一分钟内更改名称。但这并没有解决问题。

我再次尝试搜索所有内容,但找不到答案。非常感谢任何帮助。

截图class没有正确处理图像资源,所以它可能是Selenium框架中的一个错误。解决方法是自己动手:

public void takeScreenShot()
{
    string ssPath = System.IO.Path.Combine(_persistencePath, @"\Errors");

    string currTime = DateTime.Now.ToString(@"MMM-ddd-d-HH.mm");
    string fileName = System.IO.Path.Combine(ssPath, @"\ERROR-" + currTime + ".png");

    Screenshot ss = ((ITakesScreenshot)_driver).GetScreenshot();

    using (MemoryStream ms = new MemoryStream(ss.AsByteArray))
    using (Image screenShotImage = Image.FromStream(ms))
    {
        Bitmap cp = new Bitmap(screenShotImage);
        cp.Save(filename, ImageFormat.Png);
        cp.Dispose();
    }
}

不能保证这会解决问题,但至少您可以合理地确信资源已得到妥善处理。

注意需要在项目中引用System.Drawing.dll

编辑 已发布另一个解决方法。

好吧,如果有人好奇我解决了。原来我只是个白痴

string ssPath = _persistencePath += "\Errors";

这一行在第二个 运行 的目标路径上附加了另一个 \Errors。从而使路径无效,因为 \Errors\Errors 不存在。

感谢所有commented/tried提供帮助的人!

我终于做到了!

看看这个,只要写完整的 PATHNAME,

pathname+filename+extension: @"C:\folderWithPermission\test.bmp"

只获取具有写入权限的文件夹,就像 o.0

这是方法

 public DriverExecutor CaptureScreen(string filename)
    {
        Screenshot shot = this.myRemoteWebDriver.GetScreenshot();
        MemoryStream ms;
        Image imgShot;
        Bitmap bitmap;
        try 
        {
            using (ms = new MemoryStream(shot.AsByteArray))
            using (imgShot = Image.FromStream(ms))
            using (bitmap = new Bitmap(imgShot))
            {
                bitmap.Save(filename, ImageFormat.Bmp);
            }
        }catch(Exception err){}
        return this;
    } 

注意:我假设什么 remoteDriver 被正确地实例化并封装在一个自己的对象上,我希望这对大家有所帮助 ^^