Fehler beim Screenshot erstellen

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Fehler beim Screenshot erstellen

    Ich lasse jede Sekunde einen kompletten SCreenshot erstellen, dabei kommt es nach ungefähr zehn Minuten zu Fehlern...
    Hier ist mal der Code:

    VB.NET-Quellcode

    1. Public Function screenshot() As Bitmap
    2. On Error Resume Next
    3. Dim b As New Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height)
    4. Dim g As Graphics = Graphics.FromImage(b)
    5. g.CopyFromScreen(0, 0, 0, 0, b.Size)
    6. g.Dispose()
    7. Return b
    8. End Function

    Und so rufe ich sie auf:

    VB.NET-Quellcode

    1. File.Delete(My.Application.Info.DirectoryPath & "\screenshot.jpg")
    2. Thread.Sleep(100)
    3. screenshot.Save(My.Application.Info.DirectoryPath & "\screenshot.jpg")


    Die Fehler Message:

    Der Objektverweis ist nicht auf eine Objektinstanz festgelegt.

    Ich verstehe den Fehler nicht...
    Danke =)
    Edit: Warte ich provoziere den Fehler nochmal...
    Jetzt kommt ne andere Fehlermeldung O.o


    Message:
    Ungültiger Parameter

    Code der angezeigt wird:

    VB.NET-Quellcode

    1. Dim b As New Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height)


    Danke für die Hilfe =)
    ja dann sag halt mal was die parameter für nen wert haben.
    Lies die Fehlermeldung. Ungültige Parameter. Breakpoint schauen was die Parameter für nen Wert haben.
    Wenn dort steht ungültige Parameter müssen wir wissen was für nen Wert die haben dann können wir sagen wieso diese ungültig sind.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Hier mal ne kleine Klasse:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Screenshot
    3. <StructLayout(LayoutKind.Sequential)> _
    4. Private Structure RECT
    5. Public Left As Integer
    6. Public Top As Integer
    7. Public Right As Integer
    8. Public Bottom As Integer
    9. End Structure
    10. <DllImport("user32.dll")> _
    11. Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As IntPtr
    12. End Function
    13. <DllImport("user32.dll")> _
    14. Private Shared Function GetForegroundWindow() As IntPtr
    15. End Function
    16. <FlagsAttribute()> _
    17. Public Enum CaptureMethod As Integer
    18. Screen = 1
    19. Window = 2
    20. End Enum
    21. Public Sub New()
    22. End Sub
    23. Public Function Picture(Optional ByVal Method As CaptureMethod = CaptureMethod.Screen) As Bitmap
    24. If Method = Screenshot.CaptureMethod.Screen Then
    25. Return CreateScreenshot(0, 0, SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height)
    26. Else
    27. Return ActiveWindow()
    28. End If
    29. End Function
    30. Private Function CreateScreenshot(ByVal left As Integer, ByVal top As Integer, ByVal width As Integer, ByVal height As Integer) As Bitmap
    31. Dim bmp As New Bitmap(width, height)
    32. Dim g As Graphics = Graphics.FromImage(bmp)
    33. g.CopyFromScreen(left, top, 0, 0, New Size(width, height))
    34. g.Dispose()
    35. Return bmp
    36. End Function
    37. Private Function ActiveWindow() As Bitmap
    38. Return CreateScreenshot(CType(GetForegroundWindow(), IntPtr))
    39. End Function
    40. Private Function CreateScreenshot(ByVal windowhandle As IntPtr) As Bitmap
    41. Dim windowRectangle As RECT
    42. GetWindowRect(windowhandle, windowRectangle)
    43. Return CreateScreenshot(windowRectangle.Left, windowRectangle.Top, windowRectangle.Right - windowRectangle.Left, windowRectangle.Bottom - windowRectangle.Top)
    44. End Function
    45. End Class


    Das zurückgegebene Bild, sollte kein Problem für dich sein zu speichern.
    @Pseudo-Freak:
    Jetzt hast Du hier (hoffentlich) eine ganze Menge gelernt, zeig doch bitte mal Deinen aktuellen Code und schreib, wenn was nicht funktioniert. :thumbsup:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Habs nochmal probiert:

    Nach ungefähr 60 screenshots im Abstand von 1 Sekunde kommt folgende Fehlermeldung:

    Ungültige Parameter

    Ich hab die Klasse von vorhin ausprobiert:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Windows.Forms
    3. Imports System.Drawing
    4. Public Class Screenshot
    5. <StructLayout(LayoutKind.Sequential)> _
    6. Private Structure RECT
    7. Public Left As Integer
    8. Public Top As Integer
    9. Public Right As Integer
    10. Public Bottom As Integer
    11. End Structure
    12. <DllImport("user32.dll")> _
    13. Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As IntPtr
    14. End Function
    15. <DllImport("user32.dll")> _
    16. Private Shared Function GetForegroundWindow() As IntPtr
    17. End Function
    18. <FlagsAttribute()> _
    19. Public Enum CaptureMethod As Integer
    20. Screen = 1
    21. Window = 2
    22. End Enum
    23. Public Sub New()
    24. End Sub
    25. Public Function Picture(Optional ByVal Method As CaptureMethod = CaptureMethod.Screen) As Bitmap
    26. If Method = Screenshot.CaptureMethod.Screen Then
    27. Return CreateScreenshot(0, 0, SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height)
    28. Else
    29. Return ActiveWindow()
    30. End If
    31. End Function
    32. Private Function CreateScreenshot(ByVal left As Integer, ByVal top As Integer, ByVal width As Integer, ByVal height As Integer) As Bitmap
    33. Dim bmp As New Bitmap(width, height)
    34. Dim g As Graphics = Graphics.FromImage(bmp)
    35. g.CopyFromScreen(left, top, 0, 0, New Size(width, height))
    36. g.Dispose()
    37. Return bmp
    38. End Function
    39. Private Function ActiveWindow() As Bitmap
    40. Return CreateScreenshot(CType(GetForegroundWindow(), IntPtr))
    41. End Function
    42. Private Function CreateScreenshot(ByVal windowhandle As IntPtr) As Bitmap
    43. Dim windowRectangle As RECT
    44. GetWindowRect(windowhandle, windowRectangle)
    45. Return CreateScreenshot(windowRectangle.Left, windowRectangle.Top, windowRectangle.Right - windowRectangle.Left, windowRectangle.Bottom - windowRectangle.Top)
    46. End Function
    47. End Class


    Der Fehler kommt in dieser Zeile:

    VB.NET-Quellcode

    1. g.CopyFromScreen(left, top, 0, 0, New Size(width, height))


    Die Parameter sind:

    height: 1024

    left: 0

    top: 0

    width: 1280
    Danke für die Hilfe :D
    Rufst Du das in einer Timer_Tick-Prozedur auf?
    Verhindere, dass diese Prozedur aufgerufen werden kann, wenn sie noch nicht verlassen wurde:

    VB.NET-Quellcode

    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2. Static isCalled As Boolean = False
    3. If isCalled Then
    4. Return
    5. End If
    6. isCalled = True
    7. '----------------------------
    8. ' Deinen Timer-Code einfügen
    9. '----------------------------
    10. isCalled = False
    11. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    haiyyu schrieb:

    Gibt's dafür nicht Locks?
    Eindeutig die elegantere, einfachere und weniger fehleranfällige Variante.

    Zum debuggen:
    homeandlearn.co.uk/csharp/csharp_s5p4.html
    Du kannst auch z.B. rechtsklick auf eine Variable machen und anschließend eine Überwachung hinzufügen. Ach ja und oben im Menü kannst du ein Debugging-Menü einblenden. Dort kannst du dann schritt für schritt durch den Code navigieren (F11),...


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Da gibts nur eins dort wo die Exception los geht nen Breakpoint setzten und schauen was nach 60 Sekunden anderes ist als zuvor.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Es funktioniert einwandfrei:
    Einfach das "New" aus der Timer Routine nehmen! Da kommt es oft zu Fehlern, hat mir Google gesagt!
    Jetzt funktioniert es wunderbar!
    Danke :D
    Ihr seit super!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Pseudo-Freak“ ()