You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

远程服务器任务计划执行时Graphics.CopyFromScreen()抛无效句柄异常

问题分析与解决方案

核心原因

关闭远程桌面会话后,Windows服务器会挂起或注销当前用户的交互式桌面会话,此时计划任务运行的程序无法访问有效桌面环境:

  • Screen.PrimaryScreen可能返回null或无效屏幕边界
  • Graphics.CopyFromScreen依赖活跃交互式桌面会话才能捕获屏幕内容
  • 计划任务默认工作目录可能不是EXE所在目录,导致图片保存路径无效

代码修复建议

修改代码,解决路径可靠性、屏幕检测和截图逻辑问题:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World");

        // 用程序集路径获取EXE所在目录,比Application.StartupPath更可靠
        string exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        string filename = Path.Combine(exeDir, "Screenshot.png");

        ScreenCapture(filename);

        Console.WriteLine("Press <ENTER> key to exit");
        Console.ReadLine();
    }

    private static void ScreenCapture(string filename)
    {
        try
        {
            // 先检查主屏幕是否存在
            var primaryScreen = Screen.PrimaryScreen;
            if (primaryScreen == null)
            {
                Console.WriteLine("无法获取主屏幕,可能当前无活跃桌面会话");
                return;
            }

            Rectangle screenBounds = primaryScreen.Bounds;
            // 使用屏幕实际尺寸,避免硬加偏移导致范围超出
            using (Bitmap bitmap = new Bitmap(screenBounds.Width, screenBounds.Height))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(screenBounds.Left, screenBounds.Top, 0, 0, screenBounds.Size);
                }
                bitmap.Save(filename, ImageFormat.Png);
                Console.WriteLine($"截图已保存至: {filename}");
            }
        }
        catch (Exception ex)
        {
            // 输出完整异常信息,包括内部异常
            Console.WriteLine($"错误来源: {ex.Source}");
            Console.WriteLine($"错误信息: {ex.Message}");
            Console.WriteLine($"调用栈: {ex.StackTrace}");
            if (ex.InnerException != null)
            {
                Console.WriteLine($"内部错误: {ex.InnerException.Message}");
            }
        }
    }
}

计划任务设置调整

  1. 会话权限配置:

    • 打开任务计划程序,进入任务「属性」→「常规」选项卡
    • 勾选「不管用户是否登录都要运行」,取消勾选「不存储密码」,确保程序能访问桌面资源
    • 勾选「以最高权限运行」
  2. 工作目录指定:

    • 进入「操作」选项卡,编辑启动操作
    • 在「起始于(可选)」中填写EXE文件所在的完整目录路径,避免路径解析错误
  3. 保持会话活跃:

    • 运行gpedit.msc,找到「计算机配置」→「管理模板」→「Windows组件」→「远程桌面服务」→「远程桌面会话主机」→「会话时间限制」
    • 禁用「设置断开连接的会话的时间限制」和「设置活动但空闲的远程桌面服务会话的时间限制」

额外调试建议

  • 在计划任务的启动操作中添加参数> C:\Logs\screenshot.log 2>&1,将程序输出重定向到日志文件,方便查看异常信息
  • 先在用户登录状态下测试计划任务,确认截图正常后再测试断开远程会话的场景

内容的提问来源于stack exchange,提问作者idelin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 08:32:09