我正在实现不同的屏幕抓取来比较它们。其中一个应该使用“printscreen”键和剪贴板。
我用keybd_event发送击键
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void keybd_event(byte vVK, byte bScan, int dwFlags,int dwExtraInfo);
public const int KEYEVENTF_EXTENDEDKEY=0x0001; //key down
public const int KEYEVENTF_KEYUP=0x0002; //key up
public const int VK_SNAPSHOT=0x2C; //VirtualKey code for print key
public static void PrintScreen(){
keybd_event(VK_SNAPSHOT,0,KEYEVENTF_EXTENDEDKEY,0);
keybd_event(VK_SNAPSHOT,0,KEYEVENTF_KEYUP,0);
}在我的IEnumerable中,我调用这个方法,然后尝试获取图像:
...
InputController.PrintScreen();
var img=Clipboard.GetImage();
...返回的图像始终为null,而Clipboards.ContainsImage()始终为false。我已经试过在发送钥匙后等一会儿,但它也不起作用。我是遗漏了某种设置,还是有根本错误?
PS:在运行程序后,我能够将正确的图像粘贴到油漆或剪贴画中。
发布于 2013-09-20 12:21:23
这是一个控制台程序
这是最相关的细节,你应该把它写在你的问题上。剪贴板是一个系统对象,其底层api是基于COM的。这使得它对使用api的线程的单元状态很敏感。.NET剪贴板类有一点错误,如果线程的状态是错误的,它应该会抛出异常。在控制台模式应用程序中,它是错误的,它的主线程默认是MTA,您需要STA来使用api。
修复很简单,您可以在Main()方法上放置一个属性来请求STA:
[STAThread]
static void Main(string[] args) {
// etc...
}从技术上讲,STA线程也应该像Winforms或WPF应用程序那样,提供一个消息循环。但是,只要只从主线程发出方法调用,就可以逃脱它。
发布于 2013-09-20 11:17:59
您试过使用SendKeys类吗?
public static Image TakeScreenSnapshot(bool activeWindowOnly)
{
// PrtSc = Print Screen Key
string keys = "{PrtSc}";
if (activeWindowOnly)
keys = "%" + keys; // % = Alt
SendKeys.SendWait(keys);
return Clipboard.GetImage();
}代码样本的来源
发布于 2013-09-20 11:20:37
public const int KEYEVENTF_EXTENDEDKEY=0x0001; //key down
public const int KEYEVENTF_KEYUP=0x0002; //key up但你用的是:
keybd_event(VK_SNAPSHOT,0,KEYEVENT_EXTENDEDKEY,0);
keybd_event(VK_SNAPSHOT,0,KEYEVENT_KEYUP,0);使用KEYEVENTF_EXTENDEDKEY和KEYEVENTF_KEYUP它可以工作
整个过程运行在线程池上的一个工作线程中,我找不到将PrintScreen()发布到'Main-SynchronizationContext‘的方法,因为它是一个控制台程序。
你可以试试这个:
class Program
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void keybd_event(byte vVK, byte bScan, int dwFlags, int dwExtraInfo);
public const int KEYEVENTF_EXTENDEDKEY = 0x0001; //key down
public const int KEYEVENTF_KEYUP = 0x0002; //key up
public const int VK_SNAPSHOT = 0x2C; //VirtualKey code for print key
public static void PrintScreen()
{
keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0);
}
public static void test(Action<Image> action)
{
PrintScreen();
var image = Clipboard.GetImage();
action.BeginInvoke(image, ar => action.EndInvoke(ar), null);
}
[STAThread]
static void Main(string[] args)
{
var processAction = new Action<Image>(img =>
{
if (img == null)
Console.WriteLine("none");
else
Console.WriteLine(img.PixelFormat);
});
test(processAction);
System.Console.ReadLine();
}https://stackoverflow.com/questions/18915209
复制相似问题