【问题标题】:Clipboard transfer between apps应用程序之间的剪贴板传输
【发布时间】:2012-12-10 21:58:57
【问题描述】:

神秘的剪贴板问题:

我有一个正在开发的应用程序,它启动一个外部应用程序(作为 System.Diagnostics.Process 对象),该应用程序预计会将一些数据(文本)复制到剪贴板。当外部应用程序关闭时,客户端应用程序会从剪贴板中检索文本。

问题是,尽管一旦外部应用程序将文本复制到剪贴板,我可以将其粘贴到记事本中,但客户端应用程序从剪贴板获取空字符串。

外部应用代码:

    private void btn1_Click(object sender, EventArgs e)
    {
        //copy text pane to clipboard
        DataObject obj = new DataObject();
        obj.SetData(tbText.Text);
        System.Windows.Forms.Clipboard.SetDataObject(obj);
    }

客户端应用代码:

        string returnedValues = string.Empty;

        System.Windows.Forms.IDataObject data = System.Windows.Forms.Clipboard.GetDataObject();
        if (data != null && data.GetDataPresent(System.Windows.Forms.DataFormats.Text) == true)
        {
            returnedValues = (string) data.GetData(System.Windows.Forms.DataFormats.Text, true));
        }

数据对象始终为空,即使剪贴板中有文本并且我可以将其粘贴到其他应用程序中。

谁能指出客户端应用程序代码中的缺陷?为什么'data'总是为空,即使剪贴板上有数据?

【问题讨论】:

  • 我已经尝试运行您的代码,它运行良好并且可以在剪贴板上获取任何文本。但是,将数据复制到剪贴板的应用程序可能会决定在退出时清除剪贴板,但我认为这不是问题的根源,因为您可以将文本粘贴到记事本中。
  • 我目前使用的复制应用程序是一个非常简单的 Windows 窗体测试应用程序,它只执行 Clipboard.SetText(tbTextBox.text) 操作。它不会在任何地方明确清除剪贴板,正如您指出的那样,我可以在测试应用程序关闭后粘贴到记事本中,但我的客户端应用程序检索到一个空字符串!
  • 改用 DataFormats.UnicodeText。使用方便的方法,Clipboard.SetText() 和 GetText(),陷入成功的陷阱。
  • 这是空的数据对象 - 里面没有任何东西可以应用 DataFormats.UnicodeText。

标签: c# .net clipboard


【解决方案1】:

当您的剪贴板中只有一个复制为文本的字符串时,您必须将其检索为

Clipboard.GetText()

要检索其他类型的对象,您可以使用 GetData()

【讨论】:

  • 更改为 SetText 和 GetText 没有区别。即使我可以从剪贴板粘贴到记事本,Clipboard.GetText() 也会返回一个空字符串。这可能是一些跨应用程序边界问题吗?
  • 不,我不这么认为,剪贴板是有史以来最基本的功能之一。您确定要将 GetText 的内容保存到 String 类型的变量而不是 Object 中吗?
  • 是:字符串返回值=""; if (System.Windows.Forms.Clipboard.ContainsText()) 返回值 = System.Windows.Forms.Clipboard.GetText();
  • 我能说清楚一些吗? DataObject 对象为空,这就是为什么我无法从剪贴板中检索任何内容的原因。问题是为什么这个对象是空的?代码是:`string returnedValues = string.Empty; System.Windows.Forms.IDataObject 数据 = System.Windows.Forms.Clipboard.GetDataObject(); if (data != null && data.GetDataPresent(System.Windows.Forms.DataFormats.Text) == true) { returnedValues = (string) data.GetData(System.Windows.Forms.DataFormats.Text, true)); }`
  • 使用 SetText() 和 GetText() 没有区别——那里什么都没有(尽管我仍然可以粘贴到记事本中!)
【解决方案2】:

对于文本,您确实应该使用SetText()GetText()。并确保覆盖剪贴板的当前内容是用户在您的场景中所期望的。如果没有,您应该改用进程间通信,参见例如What is the simplest method of inter-process communication between 2 C# processes?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多