2

我知道这是一个关于 Win 7 中带有 c# 上的 winService 的屏幕截图的老问题。我已经阅读了关于 Stack Overflow 的所有文章以及 CodeProject 上的很多文章......我知道服务的 0 会话,从 Win Vista 开始以及关于允许服务与桌面检查交互......但我被卡住了(我可以'不要从服务中截取屏幕截图,因为我不知道显示图像(屏幕)保存在哪里。

   using System;
   using System.Collections.Generic;
   using System.ComponentModel;
   using System.Data;
   using System.Diagnostics;
   using System.Linq;
   using System.ServiceProcess;
   using System.Text;
   using System.Timers;

   namespace MyThirdTry
   {
public partial class Third : ServiceBase
{
    private static MyTimer aTimer;
    public Third()
    {
        InitializeComponent();
        if (!System.Diagnostics.EventLog.SourceExists("MySource"))
        {
            System.Diagnostics.EventLog.CreateEventSource(
                "MySource", "MyNewLog");
        }
        eventLog1.Source = "MySource";
        eventLog1.Log = "MyNewLog";
        aTimer = new MyTimer();
        aTimer.Elapsed += new System.Timers.ElapsedEventHandler(aTimer_Elapsed);
        aTimer.Interval = 10000;
    }

    protected override void OnStart(string[] args)
    {
        eventLog1.WriteEntry("Started\t" + DateTime.Now.ToString("G"));
        aTimer.Enabled = true;
    }

    protected override void OnStop()
    {
        aTimer.Enabled = false;
        eventLog1.WriteEntry("Stopped\t" + DateTime.Now.ToString("G"));
    }
    protected override void OnPause()
    {
        aTimer.Enabled = false;
        eventLog1.WriteEntry("Paused\t" + DateTime.Now.ToString("G"));
        base.OnPause();
    }
    protected override void OnContinue()
    {
        base.OnContinue();
        aTimer.Enabled = true;
        eventLog1.WriteEntry("Continued\t" + DateTime.Now.ToString("G"));
    }
    protected override void OnShutdown()
    {
        aTimer.Enabled = false;
        eventLog1.WriteEntry("Shutted down\t" + DateTime.Now.ToString("G"));
        base.OnShutdown();
    }
    private void aTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        eventLog1.WriteEntry("Evented\t" + aTimer.TimeTaker() + "\t" + Environment.CurrentDirectory);
        aTimer.TakeScreenShot();
    }
}
}

这是 MyTimer 类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Timers;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Security.Principal;
    using System.IO;

    namespace MyThirdTry
    {
class MyTimer:Timer
{
    Bitmap mainBit;
    System.Windows.Forms.Screen main;

    public string TimeTaker()
    {
        return DateTime.Now.ToString("G");
    }

    public void TakeScreenShot()
    {
        string PathToSave = @"c:\results";
        System.IO.Directory.CreateDirectory(PathToSave);

        main = System.Windows.Forms.Screen.PrimaryScreen;
        mainBit = new Bitmap(main.Bounds.Width, main.Bounds.Height, PixelFormat.Format32bppArgb);
        Graphics gScreenShot = Graphics.FromImage(mainBit);

        gScreenShot.CopyFromScreen(main.Bounds.X,
                                   main.Bounds.Y,
                                   0, 0,
                                   main.Bounds.Size,
                                   CopyPixelOperation.SourceCopy);

        string fileName = "result" + Directory.GetFiles(PathToSave).Count().ToString().Trim() + ".png";
        mainBit.Save(System.IO.Path.Combine(PathToSave, fileName), System.Drawing.Imaging.ImageFormat.Png);
    }
}
}

并且此代码返回盲(空)屏幕截图...一切正常,但服务无法获取屏幕截图,因为它处于 0 会话中...如何从当前登录用户的会话中获取 gui?

4

1 回答 1

1

由于您需要访问会话 0 以外的桌面,因此请考虑使用任务计划程序中的任务而不是 Windows 服务来捕获屏幕截图。TS 使在用户会话中启动进程变得更加容易。应将任务配置为在任何用户登录时启动。您需要将任务运行的用户帐户设置为组,例如Users,并仅在用户登录时运行任务。这两个安全选项对于创建可以访问用户桌面会话的进程至关重要。过去,我已经能够使用 User32 / Gdi32 API 调用来截取屏幕截图。

如果您仍想使用 Windows 服务以某种方式聚合屏幕截图,请使用 WCF 将屏幕截图从任务进程发送到 Windows 服务。

于 2013-03-13T01:33:23.733 回答