Search code examples
vb.netscreenshot

VB.NET - Take a screenshot of all screens on a computer


I'm trying to capture any and all screens on a computer, I tried to fiddle with Screen.AllScreens and also something with VirtualScreens that I can't remember, so I moved to PrimaryScreen to make sure everything else worked properly.

Here is my current class:

Public Class wmCapture

    Public Shared Function screenCapture()
        Dim userName As String = Environment.UserName
        Dim savePath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
        Dim dateString As String = Date.Now.ToString("yyyyMMddHHmmss")
        Dim captureSavePath As String = String.Format("{0}\WM\{1}\capture_{2}.png", savePath, userName, dateString)
        Dim bmp As Bitmap = New Bitmap( _
                            Screen.PrimaryScreen.Bounds.Width, _
                            Screen.PrimaryScreen.Bounds.Height)

        Dim gfx As Graphics = Graphics.FromImage(bmp)

        gfx.CopyFromScreen( _
            Screen.PrimaryScreen.Bounds.Location, _
            New Point(0, 0), Screen.PrimaryScreen.Bounds.Size)

        bmp.Save(captureSavePath)

    End Function

End Class

What should I be using in the Screen namespace to include all active screens?


Solution

  • You were close. I made a couple adjustments and can confirm it's working on my end.

    Public Shared Sub screenCapture()
        Dim userName As String = Environment.UserName
        Dim savePath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
        Dim dateString As String = Date.Now.ToString("yyyyMMddHHmmss")
        Dim captureSavePath As String = String.Format("{0}\WM\{1}\capture_{2}.png", savePath, userName, dateString)
        ' This line is modified for multiple screens, also takes into account different screen size (if any)
        Dim bmp As Bitmap = New Bitmap( _
                            Screen.AllScreens.Sum(Function(s As Screen) s.Bounds.Width),
                            Screen.AllScreens.Max(Function(s As Screen) s.Bounds.Height))
        Dim gfx As Graphics = Graphics.FromImage(bmp)
        ' This line is modified to take everything based on the size of the bitmap
        gfx.CopyFromScreen(SystemInformation.VirtualScreen.X,
                           SystemInformation.VirtualScreen.Y,
                           0, 0, SystemInformation.VirtualScreen.Size)
        ' Oh, create the directory if it doesn't exist
        Directory.CreateDirectory(Path.GetDirectoryName(captureSavePath))
        bmp.Save(captureSavePath)
    End Sub