W większości przypadków Service nie chodzi uwierzytelniony jako zalogowany użytkownik, więc to nie ma prawa działać tak, jak to sobie obmyśliłeś. Zależnie od licencji na komputerze może być zalogowanych nawet i kilkanaście osób. Skąd serwis ma wiedzieć której zrobić zrzut ekranu? Nie jest to niewykonalne, ale nie do końca przemyślałeś to, co chcesz zrobić.

Więc co próbujesz napisać? (nie jak? - co?)
Coś w stylu VNC/Remote Desktop. Pierwsza przymiarka, aby zrobić to samemu, ale ostatecznie pewnie będzie trzeba skorzystać z jakiegoś gotowego mechanizmu.
Możesz spróbować zaimportować GDI i zrobić jak tam, czyli (ostrzeżenie: kod pisany z pamięci):
HDC screen = GetDC(0);
HDC hdcBmp = CreateCompatibleDC(screen);
HBITMAP hBmp = CreateCompatibleBitmap(screen);
SelectObject (hdcBmp, hBmp);
BitBlt (screen, /* dużo parametrów */, hdcBmp);
Też o tym pomyślałem, ale czy DC(0) nie zwracał kontekstu samego puplitu bez okienek na nim?
W C# jest Graphics.FromHDC(), więc spróbuję bezpośrednio

SOLVED - gdyby ktoś miał podobny problem:
const int SRCCOPY = 0xcc0020;
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern int BitBlt(
IntPtr hdcDest,
int nXDest,
int nYDest,
int nWidth,
int nHeight,
IntPtr hdcSrc,
int nXSrc,
int nYSrc,
System.Int32 dwRop
);
public static Bitmap GetScreenshot()
{
Graphics desktopGraphics = Graphics.FromHwnd(new IntPtr(0));
int width = (int)desktopGraphics.VisibleClipBounds.Width;
int height = (int)desktopGraphics.VisibleClipBounds.Height;
Bitmap bmp = new Bitmap(width, height, desktopGraphics);
Graphics bmpGraphics = Graphics.FromImage(bmp);
BitBlt(bmpGraphics.GetHdc(), 0, 0, width, height, desktopGraphics.GetHdc(), 0, 0, SRCCOPY);
bmpGraphics.ReleaseHdc();
desktopGraphics.ReleaseHdc();
return bmp;
}