С# Буфер обмена.GetText()

Как я могу получить текст буфера обмена в нестатическом потоке? У меня есть решение, но я пытаюсь найти самый чистый/кратчайший путь. При обычном вызове результаты отображаются как пустая строка.


person Drake    schedule 10.05.2011    source источник


Ответы (4)


Я бы добавил вспомогательный метод, который может запускать действие как поток STA в основном потоке MTA. Я думаю, что это, вероятно, самый чистый способ добиться этого.

class Program
{
    [MTAThread]
    static void Main(string[] args)
    {
        RunAsSTAThread(
            () =>
            {
                Clipboard.SetText("Hallo");
                Console.WriteLine(Clipboard.GetText());
            });
    }

    /// <summary>
    /// Start an Action within an STA Thread
    /// </summary>
    /// <param name="goForIt"></param>
    static void RunAsSTAThread(Action goForIt)
    {
        AutoResetEvent @event = new AutoResetEvent(false);
        Thread thread = new Thread(
            () =>
            {
                goForIt();
                @event.Set();
            });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        @event.WaitOne();
    }
}
person BitKFu    schedule 10.05.2011

попробуйте добавить ApartmentStateAttribute к вашему основному методу

[STAThread]
static void Main() {
  //my beautiful codes
}
person Rejinderi    schedule 10.05.2011
comment
Я не думаю, что этот путь предназначен. - person BitKFu; 10.05.2011

Я не знаю, каковы ваши определения чистого или короткого, но если вы хотите использовать полное доверие, вы можете просто P/вызвать собственные функции буфера обмена, чтобы избежать проблем с потоками. Вот полная программа для печати текста в буфер обмена:

using System;
using System.Runtime.InteropServices;

namespace PasteText
{
    public static class Clipboard
    {
        [DllImport("user32.dll")]
        static extern IntPtr GetClipboardData(uint uFormat);
        [DllImport("user32.dll")]
        static extern bool IsClipboardFormatAvailable(uint format);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool CloseClipboard();
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        static extern bool GlobalUnlock(IntPtr hMem);

        const uint CF_UNICODETEXT = 13;

        public static string GetText()
        {
            if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
                return null;
            if (!OpenClipboard(IntPtr.Zero))
                return null;

            string data = null;
            var hGlobal = GetClipboardData(CF_UNICODETEXT);
            if (hGlobal != IntPtr.Zero)
            {
                var lpwcstr = GlobalLock(hGlobal);
                if (lpwcstr != IntPtr.Zero)
                {
                    data = Marshal.PtrToStringUni(lpwcstr);
                    GlobalUnlock(lpwcstr);
                }
            }
            CloseClipboard();

            return data;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Clipboard.GetText());
        }
    }
}
person Gabe    schedule 10.05.2011
comment
Так много ограничений на использование класса .NET ClipBoard, это лучшее решение, которое я нашел, спасибо. - person Jerry Liang; 18.03.2013
comment
Как проверить текст в буфере обмена? - person GooliveR; 20.05.2018

Вы не можете; необходимо указать атрибут STAThread.

Примечание:

ThreadStateException

Текущий поток не находится в режиме однопоточного подразделения (STA). Добавьте STAThreadAttribute в метод Main вашего приложения.

person pickypg    schedule 10.05.2011