RedX
RedX

Reputation: 15184

Clipboard SetText fails whereas SetDataObject does not

I was trying to copy a string to the clipboard via

System.Windows.Clipboard.SetText(someString);

and it was failing (Clearing before setting before setting did not work because Clear also needs to open the clipboard). The call to GetOpenClipboardWindow() indicated that some window was keeping the clipboard open (in this case it was notepad++).

By changing the above line to:

System.Windows.Clipboard.SetDataObject(someString);

the call succeeds every time and the contents of the clipboard are what I expect.

Does anybody have an explanation for this behaviour?

The documentation does not state much about what it does differently (except for clearing the clipboard when the program exits).

Upvotes: 4

Views: 3492

Answers (2)

gavin
gavin

Reputation: 1346

From MSDN

Clipboard.SetDataObject() : This method attempts to set the data ten times in 100-millisecond intervals, and throws an ExternalException if all attempts are unsuccessful.

Clipboard.SetText(): Clears the Clipboard and then adds text data to it.

Upvotes: 3

Anders Marzi Tornblad
Anders Marzi Tornblad

Reputation: 19345

When looking at the code for the two methods, I see the following differences:

public static void SetText(string text, TextDataFormat format)
{
    if (text == null)
    {
        throw new ArgumentNullException("text");
    }
    if (!DataFormats.IsValidTextDataFormat(format))
    {
        throw new InvalidEnumArgumentException("format", (int)format, typeof(TextDataFormat));
    }
    Clipboard.SetDataInternal(DataFormats.ConvertToDataFormats(format), text);
}

[SecurityCritical]
public static void SetDataObject(object data, bool copy)
{
    SecurityHelper.DemandAllClipboardPermission();
    Clipboard.CriticalSetDataObject(data, copy);
}

The SetDataObject method is marked as security-critical, which might seem like the important difference. However, the SetText method eventually just calls SetDataObject internally. The difference being:

/* From SetText: */
Clipboard.SetDataObject(dataObject, true);

/* From SetDataObject: */
Clipboard.SetDataObject(data, false);

SetText(text) never clears the Clipboard when the application exits, while SetDataObject(object) always does. That is the only real difference between calls. Try calling SetDataObject(someString, false) and SetDataObject(SomeString, true) to see any difference. If both behave the same, the difference must lie somewhere else.

Upvotes: 2

Related Questions