使用Win32 API(C#pInvoke)拍摄不在IIS中工作的屏幕截图
我想拍一张外部网站的截图。 目前,我的工作流程是使用指定的URL启动Firefox实例,并在Win32 API中使用PrintWindow截图 当我在IISExpress中运行此应用程序时,它工作正常,但当我在windows VPS上的IIS中运行相同的应用程序时,它不工作(屏幕截图为空白) 我不知道我做错了什么 我的代码:使用Win32 API(C#pInvoke)拍摄不在IIS中工作的屏幕截图,c#,asp.net-mvc,windows,winapi,iis,C#,Asp.net Mvc,Windows,Winapi,Iis,我想拍一张外部网站的截图。 目前,我的工作流程是使用指定的URL启动Firefox实例,并在Win32 API中使用PrintWindow截图 当我在IISExpress中运行此应用程序时,它工作正常,但当我在windows VPS上的IIS中运行相同的应用程序时,它不工作(屏幕截图为空白) 我不知道我做错了什么 我的代码: using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Di
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Web;
namespace WebTools.Web
{
public class RemoteScreenshot
{
public static Bitmap TakeScreenshot(Process process)
{
// may need a process Refresh before
return TakeScreenshot(process.MainWindowHandle);
}
public static Bitmap TakeScreenshot(IntPtr handle)
{
RECT rc = new RECT();
GetWindowRect(handle, ref rc);
Bitmap bitmap = new Bitmap(rc.right - rc.left, rc.bottom - rc.top);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
PrintWindow(handle, graphics.GetHdc(), 0);
}
return bitmap;
}
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);
[DllImport("user32.dll")]
private static extern bool PrintWindow(IntPtr hWnd, IntPtr hDC, int flags);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
public static void Save(string url, string file, int timeout = 0)
{
var proc = Process.Start(new ProcessStartInfo("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe", url)
{
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Maximized
});
Thread.Sleep(timeout);
var bitmap = TakeScreenshot(proc);
bitmap.Save(file, ImageFormat.Png);
bitmap.Dispose();
proc.Kill();
}
}
}
编辑:运行Firefox工作正常,因为AppPool位于另一个有权执行Firefox的帐户下 使用IIS您无法拍摄屏幕截图,因为它在Windows server的NetworkService帐户下工作IIS服务无权访问服务器桌面。IIS中的ASP.NET代码正在服务器端运行。它将试图捕获服务器的屏幕,但被拒绝 您将需要使用在客户端计算机上运行代码的silverlight。 以下链接可能会有所帮助:
由于安全原因,在浏览器中使用网页的用户可能需要提供权限。您正在拍摄哪个屏幕的截图 如果应用程序在笔记本电脑上运行,它将绘制到物理显示适配器上。如果它在RDP会话结束时在一台机器上运行,它将绘制到一个虚拟显示适配器,并且图像将通过线路发送 但如果应用程序在非交互式会话中运行,则不会显示。所以什么都不画
没有要捕获的屏幕位图。它怎么不工作?它会引发异常吗?很有可能你碰到了一个代码访问边界,它抛出了一个错误UnauthorizedException@SimonWhitehead我使用用户标识运行apppool。我最终在位图构造函数部分遇到ArgumentException,因为无法计算屏幕的宽度和高度,但当我将其设置为1600x900时,它也不起作用。您需要添加一些日志记录。将要传递的值记录到位图构造函数中。我知道传递的值是0和0,因为“GetWindowRect”函数返回该值。但是,当我将1600x900传递给构造函数时,会得到一个空白映像。您确定运行IIs池时使用的用户帐户已正确初始化,并且具有正确的用户配置文件(想想%USERPROFILE%)等等吗?我认为Firefox需要一个用户配置文件才能正常工作。我可以这样做,因为我正在使用IIS中的“用户标识”设置,在NetworkService帐户以外的其他帐户下运行应用池。IIS服务可能是非交互式的,子进程将继承它。我在windows server上遇到类似问题,当我在时间内找不到合适的解决方案时,我最终编写了一个托管在控制台应用程序上的WCF服务,因为它甚至在windows服务中也不工作。我不想使用Silverlight,因为它在本地工作,我相信在一些帮助下,我可以使它在线工作;)无论如何都不会从服务器端捕获客户端屏幕。请查看我编辑过的答案。我100%确信我可以让它工作,我创建的用户有打开Firefox的权限,我可以使用Win32 API捕获屏幕以制作Firefox浏览器的屏幕截图。嗯,该应用程序正在CloudVPS的虚拟专用服务器上运行。但是,有没有办法让会话具有交互性呢?@DillenMeijboom如果你使用XP,你可能会侥幸逃脱,但Vista和以后会尽量避免交互性:@ta.speot.is我会看一看,我目前在我的VPS上运行Windows 8 server。