【问题标题】:Why is this code not preserving the clipboard?为什么这段代码不保留剪贴板?
【发布时间】:2014-07-03 16:03:47
【问题描述】:
[STAThread]
static void Main(string[] args)
{
    Clipboard.SetDataObject(Clipboard.GetDataObject(), true);
}

这只是我能想象到的使用DataObject 剪贴板方法的最简单的测试,但是如果从记事本复制一些文本然后运行此应用程序,我将无法在应用程序退出后再粘贴该文本。没有抛出异常。使用名为 ClipView 的应用程序,我可以看到剪贴板中的文本已消失。

我使用的命名空间来自 System.Windows.Forms。如您所见,这是一个控制台应用程序而不是 Windows 窗体应用程序,因此这可能是问题的根源。但如果是这样,我想了解原因。

编辑

为了清楚起见,这只是一个测试,我使用剪贴板的实际目标更复杂。我意识到如果我只关心文本,我可以使用专门针对文本的方法。

编辑 2

虽然方法文档有很多不足之处,但this Code Project articlethis MSDN article 似乎都表明使用DataObject 调用Clipboard.SetDataObject 应该可以按预期工作,添加该数据对象中的所有数据并使用格式正确。

【问题讨论】:

  • 尽管名称不同,但 GetDataObject 和 SetDataObject 可能不是对称函数。 GetDataObject 返回一个IDataObject,可用于检索实际有效负载,而 SetDataObject 需要一些可序列化的有效负载。 (这是我从文档中收集到的。)
  • @Heinzi 是的,有点不清楚。不过,通过本文的最后一部分,我认为SetDataObject 应该能够正确处理IDataObjectcodeproject.com/Articles/2207/Clipboard-handling-with-NET
  • 你必须这样做 Clipboard.SetDataObject(Clipboard.GetDataObject().GetData(DataFormats.Text), true); ..你将 idataobject 本身设置为数据而不是它包含的数据。
  • @terrybozzio 如果我在剪贴板上同时有多种不同的数据类型,如我之前评论中的链接所示,该怎么办?
  • 那么请参考这个链接 - msdn.microsoft.com/en-us/library/637ys738(v=vs.110).aspx - 在以多种格式将数据添加到剪贴板部分中。

标签: c# clipboard


【解决方案1】:

根据MSDNClipboard.SetDataObject 方法“清除剪贴板然后在其上放置数据并指定应用程序退出后数据是否应保留”(强调我的)。 p>

SetDataObject 中的代码何时实际从 Windows 剪贴板检索数据似乎存在幕后计时问题。如果GetDataObject 返回的DataObject 延迟其读取,并且SetDataObject 的清除代码在GetDataObject 返回上调用GetData 之前执行,则剪贴板可能在SetDataObject 尝试设置时为空它的数据。

(我的第一个想法是清除发生在对 Clipboard.GetDataObject 的调用发生之前;但是,正如下面的评论者所指出的,任何方法调用的参数都会在该方法调用发生之前进行评估。)

【讨论】:

  • 你是说一个方法在它的参数被解析之前被调用了?我不明白这怎么可能是真的。
  • 显然不可能是的,首先解决参数
  • 好吧,这不是在调用GetDataObject 之前发生(如上面的cmets 解释的那样),但我相信DataObject 本身可能会推迟从剪贴板检索数据,直到它的方法被调用。 .事实上我几乎可以肯定是这样的。所以这是一个合理的解释。
  • 这将是一个解释:由于您只是收到 GetDataObjectreference,因此在输入 SetDataObject 时实际内容将被删除 - 然后参考什么都没有。这也可以解释为什么手动复制(“新”对象)确实有效。
  • 如果你更新这个答案更准确(根据 cmets),我会接受它
【解决方案2】:

您是否检查过您的应用程序是否以足够的权限运行以访问剪贴板?

尝试在剪贴板前面添加以下代码行,看看是否出现安全异常:

IPermission permission = new UIPermission(PermissionState.None);
permission.Clipboard = UIPermissionClipboard.AllClipboard;
permission.Demand();

我已经测试了代码,对我来说它显示了相同的行为。 但是,手动备份每个剪贴板条目并手动恢复它就可以了。 (按钮 1 存储它,按钮 2 恢复它)

Dictionary<string, object> d = new Dictionary<string, object>();

private void button1_Click(object sender, EventArgs e)
{
    d = new Dictionary<string, object>();
    IDataObject o = Clipboard.GetDataObject();
    foreach (string format in o.GetFormats())
    {
        d.Add(format, o.GetData(format));
    }
}

private void button2_Click(object sender, EventArgs e)
{
    DataObject o = new DataObject();

    foreach (string format in d.Keys)
    {
        o.SetData(format, d[format]);
    }

    Clipboard.SetDataObject(o);

}

【讨论】:

    猜你喜欢
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2011-05-27
    相关资源
    最近更新 更多