tags:

views:

1253

answers:

4

Hi -

My clip board is populated with text but when I run

string clipboardData = Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text);

I get back an empty string. I've toyed with various forms of the call including:

string clipboardData = Clipboard.GetText();
string clipboardData = Clipboard.GetText(System.Windows.Forms.TextDataFormat.UnicodeText);

but same result.

Am I missing something obvious?

Thanks

+10  A: 

You can only access the clipboard from an STA thread. Rick Brewster ran into this with some refactoring of the regular Edit->Paste command, in Paint.NET.

Code:

IDataObject idat = null;
Exception threadEx = null;
Thread staThread = new Thread(
    delegate
    {
        try
        {
            idat = Clipboard.GetDataObject();
        }

        catch (Exception ex) 
        {
            threadEx = ex;            
        }
    });
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();
// at this point either you have clipboard data or an exception

Code is from Rick. http://forums.getpaint.net/index.php?/topic/13712-/page__view__findpost__p__226140

BoltBait
A: 

For some reason BoltBait's code didn't quite work (idat was still null even after staThread.Join()). I just did Clipboard.GetText() inside of the staThread delegate instead of Clipboard.GetDataObject() and that worked fine.

Thanks though - your code snippet got me 99% there :)

Jonathan Yee
Awesome. I'm glad you got it working.
BoltBait
Hi Jonathan - I saw the exact same thing and did the same thing as well.
Matt
+1  A: 

I have written this class, it works, and do the same thing and can be easily improved just adding the method who you need

    Private Class ClipboardAsync

    Private _GetText As String
    Private Sub _thGetText(ByVal format As Object)
        Try
            If format Is Nothing Then
                _GetText = Clipboard.GetText()
            Else
                _GetText = Clipboard.GetText(DirectCast(format, TextDataFormat))
            End If

        Catch ex As Exception
            _GetText = String.Empty
        End Try
    End Sub
    Public Function GetText() As String
        Dim instance As New ClipboardAsync
        Dim staThread As New Thread(AddressOf instance._thGetText)
        staThread.SetApartmentState(ApartmentState.STA)
        staThread.Start()
        staThread.Join()
        Return instance._GetText
    End Function
    Public Function GetText(ByVal format As TextDataFormat) As String
        Dim instance As New ClipboardAsync
        Dim staThread As New Thread(AddressOf instance._thGetText)
        staThread.SetApartmentState(ApartmentState.STA)
        staThread.Start(format)
        staThread.Join()
        Return instance._GetText
    End Function

    Private _ContainsText As Boolean
    Private Sub _thContainsText(ByVal format As Object)
        Try
            If format Is Nothing Then
                _ContainsText = Clipboard.ContainsText()
            Else
                _ContainsText = Clipboard.ContainsText(DirectCast(format, TextDataFormat))
            End If
        Catch ex As Exception
            _ContainsText = False
        End Try
    End Sub
    Public Function ContainsText() As Boolean
        Dim instance As New ClipboardAsync
        Dim staThread As New Thread(AddressOf instance._thContainsFileDropList)
        staThread.SetApartmentState(ApartmentState.STA)
        staThread.Start()
        staThread.Join()
        Return instance._ContainsText
    End Function
    Public Function ContainsText(ByVal format As Object) As Boolean
        Dim instance As New ClipboardAsync
        Dim staThread As New Thread(AddressOf instance._thContainsFileDropList)
        staThread.SetApartmentState(ApartmentState.STA)
        staThread.Start(format)
        staThread.Join()
        Return instance._ContainsText
    End Function

    Private _ContainsFileDropList As Boolean
    Private Sub _thContainsFileDropList(ByVal format As Object)
        Try
            _ContainsFileDropList = Clipboard.ContainsFileDropList
        Catch ex As Exception
            _ContainsFileDropList = False
        End Try
    End Sub
    Public Function ContainsFileDropList() As Boolean
        Dim instance As New ClipboardAsync
        Dim staThread As New Thread(AddressOf instance._thContainsFileDropList)
        staThread.SetApartmentState(ApartmentState.STA)
        staThread.Start()
        staThread.Join()
        Return instance._ContainsFileDropList
    End Function

    Private _GetFileDropList As Specialized.StringCollection
    Private Sub _thGetFileDropList()
        Try
            _GetFileDropList = Clipboard.GetFileDropList
        Catch ex As Exception
            _GetFileDropList = Nothing
        End Try
    End Sub
    Public Function GetFileDropList() As Specialized.StringCollection
        Dim instance As New ClipboardAsync
        Dim staThread As New Thread(AddressOf instance._thGetFileDropList)
        staThread.SetApartmentState(ApartmentState.STA)
        staThread.Start()
        staThread.Join()
        Return instance._GetFileDropList
    End Function
End Class

Here is the CSharp Version:

private class ClipboardAsync
{

private string _GetText;
private void _thGetText(object format)
{
    try {
        if (format == null) {
            _GetText = Clipboard.GetText();
        }
        else {
            _GetText = Clipboard.GetText((TextDataFormat)format);

        }
    }
    catch (Exception ex) {
        //Throw ex 
        _GetText = string.Empty;
    }
}
public string GetText()
{
    ClipboardAsync instance = new ClipboardAsync();
    Thread staThread = new Thread(instance._thGetText);
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start();
    staThread.Join();
    return instance._GetText;
}
public string GetText(TextDataFormat format)
{
    ClipboardAsync instance = new ClipboardAsync();
    Thread staThread = new Thread(instance._thGetText);
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start(format);
    staThread.Join();
    return instance._GetText;
}

private bool _ContainsText;
private void _thContainsText(object format)
{
    try {
        if (format == null) {
            _ContainsText = Clipboard.ContainsText();
        }
        else {
            _ContainsText = Clipboard.ContainsText((TextDataFormat)format);
        }
    }
    catch (Exception ex) {
        //Throw ex 
        _ContainsText = false;
    }
}
public bool ContainsText()
{
    ClipboardAsync instance = new ClipboardAsync();
    Thread staThread = new Thread(instance._thContainsFileDropList);
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start();
    staThread.Join();
    return instance._ContainsText;
}
public bool ContainsText(object format)
{
    ClipboardAsync instance = new ClipboardAsync();
    Thread staThread = new Thread(instance._thContainsFileDropList);
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start(format);
    staThread.Join();
    return instance._ContainsText;
}

private bool _ContainsFileDropList;
private void _thContainsFileDropList(object format)
{
    try {
        _ContainsFileDropList = Clipboard.ContainsFileDropList;
    }
    catch (Exception ex) {
        //Throw ex 
        _ContainsFileDropList = false;
    }
}
public bool ContainsFileDropList()
{
    ClipboardAsync instance = new ClipboardAsync();
    Thread staThread = new Thread(instance._thContainsFileDropList);
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start();
    staThread.Join();
    return instance._ContainsFileDropList;
}

private Specialized.StringCollection _GetFileDropList;
private void _thGetFileDropList()
{
    try {
        _GetFileDropList = Clipboard.GetFileDropList;
    }
    catch (Exception ex) {
        //Throw ex 
        _GetFileDropList = null;
    }
}
public Specialized.StringCollection GetFileDropList()
{
    ClipboardAsync instance = new ClipboardAsync();
    Thread staThread = new Thread(instance._thGetFileDropList);
    staThread.SetApartmentState(ApartmentState.STA);
    staThread.Start();
    staThread.Join();
    return instance._GetFileDropList;
}
}

You can simple use it with: Vb.net:

Dim Clipboard2 As New ClipboardAsync
MessageBox.Show (Clipboard2.ContainsText())

Csharp:

ClipboardAsync Clipboard2 = new ClipboardAsync();
MessageBox.Show (Clipboard2.ContainsText());
Braian Bressan
A: 

Honestly I don't know what a STA Thread is exactly, but in simple projects it might solve the problem to add [STAThread] right before the Main method.

[STAThread]
static void Main(string[] args)
{ (...)

Works for me, so I don't question the method ;)

danilo