|
-
Nov 4th, 2009, 03:04 PM
#1
Thread Starter
Addicted Member
[RESOLVED]Screenshot, without screen?
Hello,
I have a pc, without a monitor attached to it. I want to make a screenshot once in x minutes, and then upload the image. The problem is, I cannot make a screenshot, because there is no screen?
I tried this code:
Code:
public Image CaptureScreen()
{
System.Windows.Forms.SendKeys.SendWait("{PRTSC}");
return System.Windows.Forms.Clipboard.GetImage();
}
I don't get anything this way.
I also tried this (Also with hardcoded values, 800*600), and don't get anything.
Code:
public Image CaptureScreen()
{
Bitmap bmpScreenshot;
Graphics gfxScreenshot;
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner
gfxScreenshot.CopyFromScreen(System.Windows.Forms.Screen.PrimaryScreen.Bounds.X, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Y, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
return bmpScreenshot;
}
And this (Which gives me a black 800*600 file)
Code:
public Image CaptureScreen()
{
return CaptureWindow(User32.GetDesktopWindow());
}
public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}
private class User32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
}
Is there any other way to make a screenshot? Is there even a way to do it without having a screen?
With kind regards,
Thomas
Last edited by Mindstorms; Nov 15th, 2009 at 12:28 PM.
Reason: Resolved
-
Nov 5th, 2009, 02:02 AM
#2
Re: Screenshot, without screen?
Following is the class I am using. Here is a sample usage. I am not sure if this will work when you don't have a screen. =)
Code:
Image img = ScreenCapture.FullScreen();
string imageFile = applicationPath + @"\Exceptions\ExceptionLog" + DateTime.Now.ToString("MMddyyyy-hhmmss") + ".jpg";
img.Save(imageFile);
ScreenCapture class.
Code:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Common
{
public class ScreenCapture
{
public static Bitmap FullScreen()
{
return ScreenCapture.ScreenRectangle(SystemInformation.VirtualScreen);
}
public static Bitmap DisplayMonitor(System.Windows.Forms.Screen monitor)
{
Rectangle rect;
try
{
rect = monitor.Bounds;
}
catch (Exception ex)
{
throw new ArgumentException("Invalid parameter.", "monitor", ex);
}
return ScreenCapture.ScreenRectangle(monitor.Bounds);
}
public static Bitmap ActiveWindow()
{
IntPtr hwnd;
Win32.RECT wRect = new Win32.RECT();
hwnd = Win32.GetForegroundWindow();
if (hwnd != IntPtr.Zero)
{
if (Win32.GetWindowRect(hwnd, ref wRect))
{
Rectangle rect = new Rectangle(wRect.Left, wRect.Top, wRect.Right - wRect.Left, wRect.Bottom - wRect.Top);
return ScreenCapture.ScreenRectangle(rect);
}
else
{
throw new System.ComponentModel.Win32Exception();
}
}
else
{
throw new Exception("Could not find any active window.");
}
}
public static Bitmap Window(IntPtr hwnd)
{
Win32.RECT wRect = new Win32.RECT();
if (hwnd != IntPtr.Zero)
{
if (Win32.GetWindowRect(hwnd, ref wRect))
{
Rectangle rect = new Rectangle(wRect.Left, wRect.Top, wRect.Right - wRect.Left, wRect.Bottom - wRect.Top);
return ScreenCapture.ScreenRectangle(rect);
}
else
{
throw new System.ComponentModel.Win32Exception();
}
}
else
{
throw new ArgumentException("Invalid window handle.", "hwnd");
}
}
public static Bitmap Control(Point p)
{
IntPtr hwnd;
Win32.RECT wRect = new Win32.RECT();
hwnd = Win32.WindowFromPoint(p);
if (hwnd != IntPtr.Zero)
{
if (Win32.GetWindowRect(hwnd, ref wRect))
{
Rectangle rect = new Rectangle(wRect.Left, wRect.Top, wRect.Right - wRect.Left, wRect.Bottom - wRect.Top);
return ScreenCapture.ScreenRectangle(rect);
}
else
{
throw new System.ComponentModel.Win32Exception();
}
}
else
{
throw new Exception("Could not find any window at the specified point.");
}
}
public static Bitmap Control(IntPtr hwnd)
{
Win32.RECT wRect = new Win32.RECT();
if (hwnd != IntPtr.Zero)
{
if (Win32.GetWindowRect(hwnd, ref wRect))
{
Rectangle rect = new Rectangle(wRect.Left, wRect.Top, wRect.Right - wRect.Left, wRect.Bottom - wRect.Top);
return ScreenCapture.ScreenRectangle(rect);
}
else
{
throw new System.ComponentModel.Win32Exception();
}
}
else
{
throw new ArgumentException("Invalid control handle.", "hwnd");
}
}
public static Bitmap ScreenRectangle(Rectangle rect)
{
if (!(rect.IsEmpty) && rect.Width != 0 && rect.Height != 0)
{
System.ComponentModel.Win32Exception win32Ex = null;
IntPtr wHdc = Win32.GetDC(IntPtr.Zero);
if (wHdc == IntPtr.Zero)
{
throw new System.ComponentModel.Win32Exception();
}
Graphics g;
Bitmap img = new Bitmap(rect.Width, rect.Height);
img.MakeTransparent();
g = Graphics.FromImage(img);
IntPtr gHdc = g.GetHdc();
if (!(Win32.BitBlt(gHdc, 0, 0, rect.Width, rect.Height, wHdc, rect.X, rect.Y, Win32.SRCCOPY | Win32.CAPTUREBLT)))
{
win32Ex = new System.ComponentModel.Win32Exception();
}
g.ReleaseHdc(gHdc);
g.Dispose();
Win32.ReleaseDC(IntPtr.Zero, wHdc);
if (!(win32Ex == null))
{
throw win32Ex;
}
else
{
return img;
}
}
else
{
throw new ArgumentException("Invalid parameter.", "rect");
}
}
private class Win32
{
public const int CAPTUREBLT = 1073741824;
public const int BLACKNESS = 66;
public const int DSTINVERT = 5570569;
public const int MERGECOPY = 12583114;
public const int MERGEPAINT = 12255782;
public const int NOTSRCCOPY = 3342344;
public const int NOTSRCERASE = 1114278;
public const int PATCOPY = 15728673;
public const int PATINVERT = 5898313;
public const int PATPAINT = 16452105;
public const int SRCAND = 8913094;
public const int SRCCOPY = 13369376;
public const int SRCERASE = 4457256;
public const int SRCINVERT = 6684742;
public const int SRCPAINT = 15597702;
public const int WHITENESS = 16711778;
public const int HORZRES = 8;
public const int VERTRES = 10;
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[DllImport("user32", SetLastError = true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);
[DllImport("user32", SetLastError = true)]
public static extern IntPtr WindowFromPoint(Point pt);
[DllImport("user32", SetLastError = true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32", SetLastError = true)]
public static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("gdi32", SetLastError = true)]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("gdi32", SetLastError = true)]
public static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
}
}
}
-
Nov 5th, 2009, 05:38 AM
#3
Thread Starter
Addicted Member
Re: Screenshot, without screen?
Thanks for your reply. It does work when I'm logged in via my Remote Desktop, (Like all the code), but when I'm not logged in, I get an exeption:
************** Tekst van uitzondering **************
System.ComponentModel.Win32Exception: Toegang geweigerd
bij Common.ScreenCapture.ScreenRectangle(Rectangle rect)
bij Common.ScreenCapture.FullScreen()
bij WindowsFormsApplication1.Form1.timer1_Tick(Object sender, EventArgs e)
bij System.Windows.Forms.Timer.OnTick(EventArgs e)
bij System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
bij System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
"Acces denied".
-
Nov 5th, 2009, 08:31 AM
#4
Hyperactive Member
Re: Screenshot, without screen?
I have had this function laying around for a while:
csharp Code:
public static Bitmap CaptureScreen() { Bitmap BMP = new Bitmap(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Drawing.Graphics GFX = System.Drawing.Graphics.FromImage(BMP); GFX.CopyFromScreen(System.Windows.Forms.Screen.PrimaryScreen.Bounds.X, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Y, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size, System.Drawing.CopyPixelOperation.SourceCopy); return BMP; }
"The only thing that interferes with my learning is my education."
-
Nov 5th, 2009, 01:09 PM
#5
Thread Starter
Addicted Member
Re: Screenshot, without screen?
Too bad, it gives an exception too.
************** Tekst van uitzondering **************
System.ComponentModel.Win32Exception: De ingang is ongeldig
bij System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation)
bij WindowsFormsApplication1.Form1.CaptureScreen()
bij WindowsFormsApplication1.Form1.timer1_Tick(Object sender, EventArgs e)
bij System.Windows.Forms.Timer.OnTick(EventArgs e)
bij System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
bij System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Which means something like "Invalid handle". Hardcoding the screen size give's the same error.
Should there really be no option to do this?
-
Nov 5th, 2009, 01:47 PM
#6
Hyperactive Member
Re: Screenshot, without screen?
Note that the function I posted returns a Bitmap and not an Image.
"The only thing that interferes with my learning is my education."
-
Nov 5th, 2009, 02:28 PM
#7
Thread Starter
Addicted Member
Re: Screenshot, without screen?
Saving the image as a BMP gives the same error.
-
Nov 5th, 2009, 02:39 PM
#8
Hyperactive Member
Re: Screenshot, without screen?
vb Code:
private void button1_Click(object sender, EventArgs e) { Bitmap screen = CaptureScreen(); screen.Save(@"C:\myScreen.bmp", System.Drawing.Imaging.ImageFormat.Bmp); }
"The only thing that interferes with my learning is my education."
-
Nov 5th, 2009, 02:49 PM
#9
Thread Starter
Addicted Member
Re: Screenshot, without screen?
Code:
private void timer1_Tick(object sender, EventArgs e)
{
Bitmap screen = CaptureScreen();
screen.Save(@"C:\" + DateTime.Now.ToLongTimeString().Replace(":",".") + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
public static Bitmap CaptureScreen()
{
Bitmap BMP = new Bitmap(800, 600, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
System.Drawing.Graphics GFX = System.Drawing.Graphics.FromImage(BMP);
GFX.CopyFromScreen(0, 0, 0, 0, new Size(800,600), System.Drawing.CopyPixelOperation.SourceCopy);
return BMP;
}
Same error
-
Nov 6th, 2009, 03:21 AM
#10
Re: Screenshot, without screen?
 Originally Posted by Mindstorms
Thanks for your reply. It does work when I'm logged in via my Remote Desktop, (Like all the code), but when I'm not logged in, I get an exeption: "Acces denied". 
You mean it does not work when no user is logged?
-
Nov 6th, 2009, 06:47 AM
#11
Thread Starter
Addicted Member
Re: Screenshot, without screen?
Exactly. When I'm logged in, it works fine, just like all the other snippets I used. When I'm not logged in, I get a Win32Exception: Acces denied.
-
Nov 7th, 2009, 08:23 AM
#12
Thread Starter
Addicted Member
Re: Screenshot, without screen?
I messed a bit around with all the code. The only snippet that actually makes a screenshot is my third code. It makes a black screenshot, but it does at least something. I also tried another window handle instead of the whole desktop. The size and everything is correct, but it's black when I'm not logged in.
I think that means the screen is not rendered if it hasn't a screen, or an output like RDP?
-
Nov 7th, 2009, 04:16 PM
#13
Re: Screenshot, without screen?
I just want to ask, why would you want to take a screenshot of the screen if you are not logged in?
-
Nov 7th, 2009, 04:22 PM
#14
Thread Starter
Addicted Member
Re: Screenshot, without screen?
I can only login with RDP right now. But I'm developing a website with some very basic controls (Start program, shutdown program), so I can watch the system from (for example) my cellphone. It should be nice to have a screenshot, so I can see what's happening.
-
Nov 8th, 2009, 02:18 PM
#15
Hyperactive Member
Re: Screenshot, without screen?
 Originally Posted by Mindstorms
Exactly. When I'm logged in, it works fine, just like all the other snippets I used. When I'm not logged in, I get a Win32Exception: Acces denied.
I've done this a few times already and yes when you're not logged in or locked the workstation, a Win32Exception is generated. I have done a lot of research on this but didnt find any way to resolve it.
However if the monitor is not attached but the user is still logged in, I see no problem why you can't take a snap shot. Taking a snap shot with remote access though has the same effect as locking the computer - a win32 exception is generated.
Jennifer.
-
Nov 8th, 2009, 02:28 PM
#16
Thread Starter
Addicted Member
Re: Screenshot, without screen?
If you're not logged in and there is no screen, there is no reason for rendering everything, so Windows doesn't do it.
I did some research today, but I think I have to build this to make Windows think there is a screen attached, and so render everything. That should do the trink I think.
-
Nov 10th, 2009, 02:47 PM
#17
Hyperactive Member
Re: Screenshot, without screen?
 Originally Posted by Mindstorms
If you're not logged in and there is no screen, there is no reason for rendering everything, so Windows doesn't do it.
I did some research today, but I think I have to build this to make Windows think there is a screen attached, and so render everything. That should do the trink I think.
come on, there's got to be another way to do this. I'm not saying this method won't work but it seems to me like going after a fly with a bomb.
-
Nov 10th, 2009, 03:52 PM
#18
Re: Screenshot, without screen?
Why do you need a screenshot when there is no screen as described? If the form has information you want at specific intervals why not write them to a database table or physical file?
-
Nov 10th, 2009, 03:55 PM
#19
Thread Starter
Addicted Member
Re: Screenshot, without screen?
There are also other programs running, possibly messages to take care of, Windows Update bothering me, etcetera. A screenshot certainly is a lot better than creating a database of all those things.
-
Nov 10th, 2009, 04:21 PM
#20
Re: Screenshot, without screen?
Sorry this is not much help to resolve your question but perhaps might assist in why various code is failing.
I am wondering if your wrote the results of the following to a file and then see what the reported width and height is? Since there is no monitor I would guess a) an exception is thrown or b) width and height are 0.
Code:
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height
-
Nov 11th, 2009, 07:50 AM
#21
Thread Starter
Addicted Member
Re: Screenshot, without screen?
It gives the output 800*600, which is the screen resolution I set. The third code in my first post does actually create a bitmap with this size, but it's black.
-
Nov 11th, 2009, 10:44 AM
#22
Fanatic Member
Re: Screenshot, without screen?
You first need to define "logged in", do you mean "Logged in but locked", or never logged in at all.
If your screen is locked then you should be able to accomplish this, unless you are running a full screen OpenGL or DirectX 10 app underneath the lock, in which case you will only ever get a black result without some nasty hooking trickery.
If you have never logged on, then none of "your user" services or your desktop are running, and there is nothing to take a picture of as there is no desktop.
The access denied errors from sending keys and the like could be for a couple of reasons - first sending keys to other apps (im not sure about just out into the ether) isnt allowed any more (post vista) without a manifest and running <requestedExecutionLevel level="requireAdministrator" uiAccess="true" specified - which requires a digital cert. The second is because theres physically no logged on winlogon session running in which to run the program - try running it as a service and see where that gets you.
But it might be a lot easier to grab the events from event viewer to see what your pc is doing in the background.
For example - what if one window was hidden behind another - a screenshot would miss that.....
Crispin
VB6 ENT SP5
VB.NET
W2K ADV SVR SP3
WWW.BLOCKSOFT.CO.UK
[Microsoft Basic: 1976-2001, RIP]
-
Nov 11th, 2009, 11:03 AM
#23
Thread Starter
Addicted Member
Re: Screenshot, without screen?
Thank you for your reply.
I have no fullscreen apps running.
The pc decodes radiosignals, and my decodingprograms are allways running. TweakUI logs the pc in automatically when I restart.
However, I get exceptions, black files, or no screenshots at all. When I log in with Remote Desktop, I can see what's happening, and if all the programs run correctly. All the snippets work, and do what they should do, as long as I'm logged in with Remote Desktop.
As soon as I close the connection, the computer stays logged in, and the programs keep on running. At this time, the screenshotsnippets don't work anymore.
The computer runs on WinXp SP3 with the latest updates, and both the computer and my Remote Desktop use the user Administrator.
The screenshot would snap the decodingprograms, so I can watch the latest signals and the status of decoding. I can't watch those things in the eventviewer unfortunately.
-
Nov 13th, 2009, 11:01 PM
#24
Hyperactive Member
Re: Screenshot, without screen?
 Originally Posted by crispin
You first need to define "logged in", do you mean "Logged in but locked", or never logged in at all.
If your screen is locked then you should be able to accomplish this, ......
Could you prove this?
I have tried taking screen shots many times in the past and when the computer was locked I got the Win32Exception and at other times I would get a blank picture. Similar to you I believe it could be done but was unable to find a way to do so.
Also when taking snap shots via the remote administer tool, again sometimes the exception is thrown and other times a blank picture. Again, could you prove this?
Jennifer.
-
Nov 14th, 2009, 06:07 PM
#25
Hyperactive Member
Re: Screenshot, without screen?
Are you logged in as a administrator and is the application running as an administrator? Anyways, try this.
Code:
public static Bitmap Bitmap1
{
get
{
System.Windows.Forms.SendKeys.Send("{PRTSC}");
IDataObject data = Clipboard.GetDataObject();
return (Bitmap)data.GetData(DataFormats.Bitmap,true);
}
}
Last edited by VB6Learner; Nov 14th, 2009 at 06:07 PM.
Reason: Accidentally put two lines!
-
Nov 15th, 2009, 10:42 AM
#26
Thread Starter
Addicted Member
Re: Screenshot, without screen?
The application is run as Administrator, yes. But I already tried the sendkeys method, it doesn't work.
Nevertheless, I solved the problem today. I made a VGA-dummy, and instead of closing the RDP connection with the red X, I use the command
%windir%\system32\tscon.exe 0 /dest:console
That insures that the screen isn't locked.
In combination with the last code in my first post, it finally works.
Thank you for all your suggestions everyone!
With kind regards,
Thomas
-
Nov 15th, 2009, 12:24 PM
#27
Hyperactive Member
Re: Screenshot, without screen?
Remember to mark the thread as resolved! 
1) Go to top of page.
2) Click Thread Tools
3) Click Mark Thread as Resolved.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|