非窗口程序如何监视系统剪贴板?

3

I want to write a program to monitor windows clipboard using C#. I found some post about this topic. According thread How to monitor clipboard content changes in C#? and Finding the handle to a WPF window, I write a demo using WPF. In all samples code I found, all of them are WinForm or WPF apps, and win32 api they interop with need window handle as parameters. Such as api function SetClipboardViewer(HWND hWndNewViewer)

But in my scenario, I need my program run background as a service to monitor and collect clipboard content. How to monitor clipboard without window UI?

Could you give me some suggestions? Thanks in advance.


According user1795804's suggestion, I write following test code

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    public static class User32
    {


  [DllImport("User32.dll")]
    public static extern IntPtr OpenClipboard(IntPtr hWndNewOwner);

    [DllImport("User32.dll")]
    public static extern IntPtr GetClipboardData(uint uFormat);
}
class Program
{
    static void Main(string[] args)
    {
        int result = (int)User32.OpenClipboard(new IntPtr(0));
        if (result == 0)
        {
            Console.WriteLine("error");
        }
        else
        {
            Console.WriteLine("success");
        }

        int returnHandle = (int)User32.GetClipboardData(1); //CF_TEXT 1
        if (returnHandle == 0)
        {
            Console.WriteLine("can't get text data");
        }

        Console.ReadKey();
    }
    }
}

The result is I can open clipboard and seem to get a handle to date object. But now I have two issue.

1. Although I have a handle to data object in clipboard, how can I get this data using handle? I can't find related function.

2. I need pass a proc function as callback so that it can receive message when system event raise. But I can't find counterpart in non-window app.

1个回答

1
根据Microsoft的说法,“有三种监视剪贴板更改的方法。最古老的方法是创建一个剪贴板查看器窗口。Windows 2000添加了查询剪贴板序列号的功能,Windows Vista添加了对剪贴板格式侦听器的支持。剪贴板查看器窗口支持向后兼容早期版本的Windows。新程序应使用剪贴板格式侦听器或剪贴板序列号。”
此GetClipboardSequenceNumber不需要任何参数,并且根据Microsoft的说法,“系统为每个窗口站点保留剪贴板的序列号。每当剪贴板的内容发生更改或清空剪贴板时,该数字会递增。您可以跟踪此值以确定剪贴板内容是否已更改并优化创建DataObjects。如果延迟剪贴板呈现,则不会递增序列号,直到更改被呈现。”
这将满足您的要求:“我想编写一个使用C#监视Windows剪贴板的程序。”

貌似你可以使用 HANDLE WINAPI GetClipboardData() 函数来获取文本,如果以上指示有变化的话。希望这能帮到你! - user1795804
在使用函数 GetClipboardData 之前,需要先使用函数 GetClipboardData(HWND hWndNewOwner) 打开剪贴板,并将其句柄作为参数传递。看起来我们必须寻找其他方法。 - KyL
请原谅,但我没看到它说必须使用 GetClipboardData() 打开。如果可以使用 OpenClipboard 打开,也许你可以尝试。注意,它说如果传入 null,剪贴板将与当前任务相关联。BOOL WINAPI OpenClipboard( In_opt HWND hWndNewOwner );参数: 与打开的剪贴板相关联的窗口句柄。如果此参数为 NULL,则打开的剪贴板将与当前任务相关联。 - user1795804
我不确定“当前任务”是什么意思,但这可能是值得探索的东西。 - user1795804
抱歉,我打错了。我的意思是“使用OpenClipboard(HWND hWndNewOwner)”。我会尝试并希望它能够正常工作。 - KyL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接