Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clipboard SetText fails whereas SetDataObject does not

Tags:

c#

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).

like image 522
RedX Avatar asked Oct 30 '25 18:10

RedX


2 Answers

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.

like image 187
gavin Avatar answered Nov 01 '25 09:11

gavin


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.

like image 30
Anders Marzi Tornblad Avatar answered Nov 01 '25 08:11

Anders Marzi Tornblad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!