Skip to content

Commit

Permalink
Merge pull request #33480 from dotnet/merges/master-to-features/reado…
Browse files Browse the repository at this point in the history
…nly-members

Merge master to features/readonly-members
  • Loading branch information
dotnet-automerge-bot authored Feb 19, 2019
2 parents c7b9557 + c067867 commit cec9a9a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,30 @@
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using PixelFormats = System.Windows.Media.PixelFormats;

namespace Microsoft.VisualStudio.IntegrationTest.Utilities
{
internal class ScreenshotService
internal static class ScreenshotService
{
private static readonly object s_gate = new object();

/// <summary>
/// Takes a picture of the screen and saves it to the location specified by
/// <paramref name="fullPath"/>. Files are always saved in PNG format, regardless of the
/// file extension.
/// </summary>
public static void TakeScreenshot(string fullPath)
{
using (var bitmap = TryCaptureFullScreen())
// This gate prevents concurrency for two reasons:
//
// 1. Only one screenshot is held in memory at a time to prevent running out of memory for large displays
// 2. Only one screenshot is written to disk at a time to avoid exceptions if concurrent calls are writing
// to the same file
lock (s_gate)
{
var bitmap = TryCaptureFullScreen();
if (bitmap == null)
{
return;
Expand All @@ -26,7 +36,12 @@ public static void TakeScreenshot(string fullPath)
var directory = Path.GetDirectoryName(fullPath);
Directory.CreateDirectory(directory);

bitmap.Save(fullPath, ImageFormat.Png);
using (var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write))
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
encoder.Save(fileStream);
}
}
}

Expand All @@ -37,7 +52,7 @@ public static void TakeScreenshot(string fullPath)
/// A <see cref="Bitmap"/> containing the screen capture of the desktop, or null if a screen
/// capture can't be created.
/// </returns>
private static Bitmap TryCaptureFullScreen()
private static BitmapSource TryCaptureFullScreen()
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
Expand All @@ -49,8 +64,7 @@ private static Bitmap TryCaptureFullScreen()
return null;
}

var bitmap = new Bitmap(width, height);

using (var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb))
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(
Expand All @@ -60,9 +74,29 @@ private static Bitmap TryCaptureFullScreen()
destinationY: 0,
blockRegionSize: bitmap.Size,
copyPixelOperation: CopyPixelOperation.SourceCopy);
}

return bitmap;
var bitmapData = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
try
{
return BitmapSource.Create(
bitmapData.Width,
bitmapData.Height,
bitmap.HorizontalResolution,
bitmap.VerticalResolution,
PixelFormats.Bgra32,
null,
bitmapData.Scan0,
bitmapData.Stride * bitmapData.Height,
bitmapData.Stride);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private static void FirstChanceExceptionHandler(object sender, FirstChanceExcept
var assemblyDirectory = GetAssemblyDirectory();
var testName = CaptureTestNameAttribute.CurrentName ?? "Unknown";
var logDir = Path.Combine(assemblyDirectory, "xUnitResults", "Screenshots");
var baseFileName = $"{testName}-{eventArgs.Exception.GetType().Name}-{DateTime.Now:HH.mm.ss}";
var baseFileName = $"{DateTime.Now:HH.mm.ss}-{testName}-{eventArgs.Exception.GetType().Name}";
ScreenshotService.TakeScreenshot(Path.Combine(logDir, $"{baseFileName}.png"));

var exception = eventArgs.Exception;
Expand Down

0 comments on commit cec9a9a

Please sign in to comment.