Clipboard.GetText renvoie null (chaîne vide)

Mon presse-papier est rempli de texte, mais quand je cours

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

Je récupère une chaîne vide. J’ai joué avec différentes formes de l’appel, notamment:

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

Mais avec le même résultat.

Est-ce que je manque quelque chose d’évident?

Vous ne pouvez accéder au presse-papiers qu’à partir d’un thread STA. Rick Brewster a eu un problème avec la refactorisation de la commande standard Éditer-> Coller dans 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 

Le code vient de Rick. http://forums.getpaint.net/index.php?/topic/13712-/page__view__findpost__p__226140

Mise à jour : Jason Heine a fait un bon point en ajoutant () après le delegate pour corriger l’erreur de méthode ambiguë.

Honnêtement, je ne sais pas ce qu’est un thread STA, mais dans des projets simples, cela pourrait résoudre le problème pour append [STAThread] juste avant la méthode Main :

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

Cela fonctionne pour moi, donc je ne remets pas en question la méthode;)


Pour plus d’informations sur le décorateur [STAThread] article sur le blog Pourquoi STAThread est-il nécessaire? .

J’ai écrit ce cours, ça marche et je fais la même chose et je peux facilement l’améliorer en ajoutant simplement la méthode dont vous avez besoin

  Private Class ClipboardAsync Private _GetText As Ssortingng 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 = Ssortingng.Empty End Try End Sub Public Function GetText() As Ssortingng 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 Ssortingng 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.SsortingngCollection Private Sub _thGetFileDropList() Try _GetFileDropList = Clipboard.GetFileDropList Catch ex As Exception _GetFileDropList = Nothing End Try End Sub Public Function GetFileDropList() As Specialized.SsortingngCollection 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 

Voici la version CSharp:

 private class ClipboardAsync { private ssortingng _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 = ssortingng.Empty; } } public ssortingng GetText() { ClipboardAsync instance = new ClipboardAsync(); Thread staThread = new Thread(instance._thGetText); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); staThread.Join(); return instance._GetText; } public ssortingng 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.SsortingngCollection _GetFileDropList; private void _thGetFileDropList() { try { _GetFileDropList = Clipboard.GetFileDropList; } catch (Exception ex) { //Throw ex _GetFileDropList = null; } } public Specialized.SsortingngCollection GetFileDropList() { ClipboardAsync instance = new ClipboardAsync(); Thread staThread = new Thread(instance._thGetFileDropList); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); staThread.Join(); return instance._GetFileDropList; } } 

Vous pouvez simplement l’utiliser avec: Vb.net:

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

Csharp:

 ClipboardAsync Clipboard2 = new ClipboardAsync(); MessageBox.Show (Clipboard2.ContainsText()); 

Le code de BoltBait ne fonctionnait pas pour IDataObject car l’object de données perdait des informations en dehors du thread. Tout fonctionne bien si IDataObject est utilisé uniquement à l’intérieur du thread comme ceci:

 IDataObject idat = null; Exception threadEx = null; Ssortingng text = ""; Thread staThread = new Thread( delegate () { try { idat = Clipboard.GetDataObject(); text = idat.GetData(DataFormats.Text) } catch (Exception ex) { threadEx = ex; } }); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); staThread.Join(); // here you can use text, which contains data from clipboard 

Ceci est un problème de threading. Nous devons obtenir le bon fil et exécuter à travers les delegates.

Je mets à jour mes propriétés grâce à une timer qui s’écoule toutes les 500 ms. Voici le code:

  public delegate void ClipboarDelegate(); ClipboarDelegate clipboardDelegate = null; void clipboardTimer_Elapsed(object sender, ElapsedEventArgs e) { if (clipboardDelegate == null) clipboardDelegate = ClipboarDelegateMethod; //Here we get the right thread, most probably the application thread Application.Current.Dispatcher.BeginInvoke(clipboardDelegate); } public void ClipboarDelegateMethod() { try { if (Clipboard.ContainsData(DataFormats.Text)) { //It's important to lock this section lock (ClipboardSsortingng) { ClipboardSsortingng = Clipboard.GetData(DataFormats.Text) as ssortingng; } } } catch { } } 

De plus, j’ai fait un DependencyProperty avec ClipboardSsortingng:

  public static readonly DependencyProperty ClipboardSsortingngDP = DependencyProperty.Register("ClipboardSsortingng", typeof(ssortingng), typeof(MainWindow), new UIPropertyMetadata(ssortingng.Empty)); public ssortingng ClipboardSsortingng { get { return (ssortingng)this.GetValue(ClipboardSsortingngDP); } set { this.SetValue(ClipboardSsortingngDP, value); } } 

De cette façon, il peut être lié à mon TextBox dans XAML en assumant mon contrôle ou ma fenêtre x:Name="_this" :

  

Pour une raison quelconque, le code de BoltBait ne fonctionnait pas correctement (idat était toujours nul même après staThread.Join ()). Je viens de faire Clipboard.GetText () à l’intérieur du délégué staThread au lieu de Clipboard.GetDataObject () et cela a bien fonctionné.

Merci cependant – votre extrait de code m’a eu 99% là 🙂