如何使用 Clipboard.GetText 使用任务?
How to use Clipboard.GetText using a Task?
我正在编写一个 Windows 表单应用程序来自动化一个旧软件。为了在该软件和我的应用程序之间传输信息,我使用剪贴板。单击旧软件上的按钮会将一些信息放入剪贴板。
为了使用 Clipboard.GetText 我应该从 windows 形式调用它。但我不想 UI 线程上的所有内容。
在另一个任务中调用 Clipboard.GetText 时,我得到它说你应该从 STAThread 调用 Clipboard.GetText。
你将不得不改变你的期望。标准要求只有 UI 线程与剪贴板交互。
从技术上讲,如文档中所述,实际要求是只有 single-threaded apartment (STA) threads 可以访问剪贴板。因为大多数后台线程,如 .NET 中 ThreadPool class 创建的线程,都是多线程单元 (MTA) 线程,它们无法访问剪贴板。您可以通过手动创建自己的 STA 线程和 运行 消息泵来解决此问题,但仅使用 UI 线程要容易得多,所以每个人都这样做。
但是,尝试使用剪贴板在两个进程之间共享信息是一个糟糕的设计。剪贴板是为 用户 存储信息而设计的。您写入剪贴板的任何内容都会破坏用户存储在那里的任何内容。如果你的应用程序这样做,并覆盖了我想保留的东西,我会非常生你的气。
进程之间有更好的通信方式;搜索 "interprocess communication"(缩写为 "IPC")以获取各种想法。
如果您不想使用 Windows.Forms 或 Wpf 剪贴板,您可以调用本机剪贴板 api,如下所示:
How can I copy a string to clipboard within my console app WITHOUT adding a reference to System.Windows.Forms?
从剪贴板获取字符串的示例
OpenClipboard(IntPtr.Zero);
var ptr = GetClipboardData(13);
var s = Marshal.PtrToStringUni(ptr);
Marshal.FreeHGlobal(ptr);
CloseClipboard();
我使用 13 作为剪贴板类型 (CF_UNICODETEXT)
您可以在此处看到的完整列表:
https://msdn.microsoft.com/de-de/library/windows/desktop/ff729168(v=vs.85).aspx
您的 UI 话题是 STA。但这并不意味着您必须在 UI 线程中执行 all 您的逻辑。您可以在后台执行 除 UI 行之外的所有行。这可以通过将你的 Clipboard.GetText
回调从你的工作线程编组回 UI 线程来实现(假设你有一个 Form
或任何其他 Control
可用 - 在 ctrl
变量):
//Do something
Func<string> getClipboardText = delegate() { return Clipboard.GetText(); };
string clipboardText = (string)ctrl.Invoke(getClipboardText);
//Do something else
我正在编写一个 Windows 表单应用程序来自动化一个旧软件。为了在该软件和我的应用程序之间传输信息,我使用剪贴板。单击旧软件上的按钮会将一些信息放入剪贴板。
为了使用 Clipboard.GetText 我应该从 windows 形式调用它。但我不想 UI 线程上的所有内容。
在另一个任务中调用 Clipboard.GetText 时,我得到它说你应该从 STAThread 调用 Clipboard.GetText。
你将不得不改变你的期望。标准要求只有 UI 线程与剪贴板交互。
从技术上讲,如文档中所述,实际要求是只有 single-threaded apartment (STA) threads 可以访问剪贴板。因为大多数后台线程,如 .NET 中 ThreadPool class 创建的线程,都是多线程单元 (MTA) 线程,它们无法访问剪贴板。您可以通过手动创建自己的 STA 线程和 运行 消息泵来解决此问题,但仅使用 UI 线程要容易得多,所以每个人都这样做。
但是,尝试使用剪贴板在两个进程之间共享信息是一个糟糕的设计。剪贴板是为 用户 存储信息而设计的。您写入剪贴板的任何内容都会破坏用户存储在那里的任何内容。如果你的应用程序这样做,并覆盖了我想保留的东西,我会非常生你的气。
进程之间有更好的通信方式;搜索 "interprocess communication"(缩写为 "IPC")以获取各种想法。
如果您不想使用 Windows.Forms 或 Wpf 剪贴板,您可以调用本机剪贴板 api,如下所示:
How can I copy a string to clipboard within my console app WITHOUT adding a reference to System.Windows.Forms?
从剪贴板获取字符串的示例
OpenClipboard(IntPtr.Zero);
var ptr = GetClipboardData(13);
var s = Marshal.PtrToStringUni(ptr);
Marshal.FreeHGlobal(ptr);
CloseClipboard();
我使用 13 作为剪贴板类型 (CF_UNICODETEXT) 您可以在此处看到的完整列表: https://msdn.microsoft.com/de-de/library/windows/desktop/ff729168(v=vs.85).aspx
您的 UI 话题是 STA。但这并不意味着您必须在 UI 线程中执行 all 您的逻辑。您可以在后台执行 除 UI 行之外的所有行。这可以通过将你的 Clipboard.GetText
回调从你的工作线程编组回 UI 线程来实现(假设你有一个 Form
或任何其他 Control
可用 - 在 ctrl
变量):
//Do something
Func<string> getClipboardText = delegate() { return Clipboard.GetText(); };
string clipboardText = (string)ctrl.Invoke(getClipboardText);
//Do something else