Как я могу получить текст буфера обмена в нестатическом потоке? У меня есть решение, но я пытаюсь найти самый чистый/кратчайший путь. При обычном вызове результаты отображаются как пустая строка.
С# Буфер обмена.GetText()
Ответы (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
Я не думаю, что этот путь предназначен.
- 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
Так много ограничений на использование класса .NET ClipBoard, это лучшее решение, которое я нашел, спасибо.
- person Jerry Liang; 18.03.2013
Как проверить текст в буфере обмена?
- person GooliveR; 20.05.2018
Вы не можете; необходимо указать атрибут STAThread.
Примечание:
ThreadStateException
Текущий поток не находится в режиме однопоточного подразделения (STA). Добавьте
STAThreadAttributeв метод Main вашего приложения.
person
pickypg
schedule
10.05.2011