Solved

Capture Screen with ASP.net (VB)

Posted on 2006-07-07
7
523 Views
Last Modified: 2011-08-18
Hi all

I need to capture the screen just like the print screen key on the keyboard and save this image, I have been surfing around for this and I found code for it. After a lot search and coding I have the following class. This code works PERFECTLY on a Windows Forms project on visual studio, BUT the same class on a web application returns a huge BLACK image the size of the screen. I finally found that the problem lies on a GDI32 library function called BitBlt, which returns false if there is an error, on the web app this fuctions reurns false, BUT NO reasons why.

Here is the class to Capture Screen:

Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging

Namespace ScreenShot
    '/ <summary>
    '/ Provides functions to capture the entire screen, or a particular window, and save it to a file.
    '/ </summary>
    Friend Class ScreenCapture
        '/ <summary>
        '/ Creates an Image object containing a screen shot of the entire desktop
        '/ </summary>
        '/ <returns></returns>
        Public Function CaptureScreen() As Image
            Return CaptureWindow(User32.GetDesktopWindow())
        End Function 'CaptureScreen

        '/ <summary>
        '/ Creates an Image object containing a screen shot of a specific window
        '/ </summary>
        '/ <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
        '/ <returns></returns>
        Public Function CaptureWindow(ByVal handle As IntPtr) As Image
            ' get te hDC of the target window
            Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
            ' get the size
            Dim windowRect As New User32.RECT
            User32.GetWindowRect(handle, windowRect)
            Dim width As Integer = windowRect.right - windowRect.left
            Dim height As Integer = windowRect.bottom - windowRect.top
            ' create a device context we can copy to
            Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
            ' create a bitmap we can copy it to,
            ' using GetDeviceCaps to get the width/height
            Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
            ' select the bitmap object
            Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
            ' bitblt over
            Dim functionOK As Boolean

            functionOK = GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY)
            If Not functionOK Then
                Dim errorValue As Integer
                Dim errorString As String
                errorValue = Err.LastDllError
                errorString = Err.Description
            End If
            ' restore selection
            GDI32.SelectObject(hdcDest, hOld)
            ' clean up
            GDI32.DeleteDC(hdcDest)
            User32.ReleaseDC(handle, hdcSrc)

            ' get a .NET image object for it
            Dim img As Image = Image.FromHbitmap(hBitmap)
            ' free up the Bitmap object
            GDI32.DeleteObject(hBitmap)

            Return img
        End Function 'CaptureWindow


        '/ <summary>
        '/ Captures a screen shot of a specific window, and saves it to a file
        '/ </summary>
        '/ <param name="handle"></param>
        '/ <param name="filename"></param>
        '/ <param name="format"></param>
        Public Sub CaptureWindowToFile(ByVal handle As IntPtr, ByVal filename As String, ByVal format As ImageFormat)
            Dim img As Image = CaptureWindow(handle)
            img.Save(filename, format)
        End Sub 'CaptureWindowToFile


        '/ <summary>
        '/ Captures a screen shot of the entire desktop, and saves it to a file
        '/ </summary>
        '/ <param name="filename"></param>
        '/ <param name="format"></param>
        Public Sub CaptureScreenToFile(ByVal filename As String, ByVal format As ImageFormat)
            Dim img As Image = CaptureScreen()
            img.Save(filename, format)
        End Sub 'CaptureScreenToFile
        '/ <summary>
        '/ Helper class containing Gdi32 API functions
        '/ </summary>
        Friend Class GDI32
            Public Shared SRCCOPY As Integer = &HCC0020
            ' BitBlt dwRop parameter
            <DllImport("gdi32.dll")> Public Shared Function BitBlt(ByVal hObject As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hObjectSource As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean
            End Function
            <DllImport("gdi32.dll")> Public Shared Function CreateCompatibleBitmap(ByVal hDC As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
            End Function
            <DllImport("gdi32.dll")> Public Shared Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr
            End Function
            <DllImport("gdi32.dll")> Public Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
            End Function
            <DllImport("gdi32.dll")> Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
            End Function
            <DllImport("gdi32.dll")> Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
            End Function
        End Class 'GDI32
        '/ <summary>
        '/ Helper class containing User32 API functions
        '/ </summary>
        Private Class User32
            <StructLayout(LayoutKind.Sequential)> Public Structure RECT
                Public left As Integer
                Public top As Integer
                Public right As Integer
                Public bottom As Integer
            End Structure
            <DllImport("user32.dll")> Public Shared Function GetDesktopWindow() As IntPtr
            End Function
            <DllImport("user32.dll")> Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
            End Function
            <DllImport("user32.dll")> Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr
            End Function
            <DllImport("user32.dll")> Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr
            End Function
        End Class 'User32
    End Class 'ScreenCapture
End Namespace 'ScreenShot
0
Comment
Question by:sguerra
  • 4
  • 2
7 Comments
 
LVL 14

Assisted Solution

by:Ramuncikas
Ramuncikas earned 100 total points
ID: 17058781
The reason is that windows app works on the user account who has launched the app. But web app works under ASPNET account. It's not the same as ASPNET user account has no so called interaction with desktop. If you want to grab printscreen from your web app user you have to use javascript or activex for that purpose, but if you want to grab server's screen then I'm afraid it's imposible
0
 
LVL 1

Author Comment

by:sguerra
ID: 17058818
Yes I need to grab users screen NOT SERVER's.
So Is there any chance you have a link or something to where I can find the javascript version of this?

Sguerra
0
 
LVL 1

Author Comment

by:sguerra
ID: 17058852
Also, if what you say it's true, the problem lies in the "User32.GetDesktopWindow()" function, which is probably trying to get ASPNET's account desktop. Its probably not posible but can I use another function or the same but whith the purpose of obating the web users desktop?

Sguerra
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 13

Expert Comment

by:devsolns
ID: 17059578

There is no way to do that in jscript.  You are going to have to create an ActiveX control to do this.   Without ActiveX there is no way to execute the native commands needed to capture scree data on the client.
0
 
LVL 1

Author Comment

by:sguerra
ID: 17059623
Yes I was looking arround and I found that too. And even if it were posible to do soo, there is no way I can save that image on a file of the server. So ActiveX its the solution ..... were do I start and How ... can anyone point me on the right direction, I never programmed an activex before.
0
 
LVL 13

Accepted Solution

by:
devsolns earned 400 total points
ID: 17060692
Well you might be able to leverage an existing ActiveX control.  For example microsoft uses one for its remote desktop web.  There might be a free one that exists.  Try google, http://www.google.com/search?hl=en&q=activex+screen+capture

If not writing your own ActiveX control is pretty easy, http://www.c-sharpcorner.com/Code/2003/March/ActiveXInNet.asp

0
 
LVL 1

Author Comment

by:sguerra
ID: 17081102
I tried your google search but it gave me activex components which I have to buy ... no good. But anyway thanks for your help. The all thing was for a web page in which I must capture an image from a webcam. Finally I did it with flash (webcam part) and sending the captured image to my aspx page with xml. Worked ok.

Sguerra
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

AJAX ModalPopupExtender has a required property "TargetControlID" which may seem to be very confusing to new users. It means the server control that will be extended by the ModalPopup, for instance, if when you click a button, a ModalPopup displays,…
Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now