0

我了解 3rd 方应用程序的开发人员不一定希望我访问他们的剪贴板数据,在最好的情况下,除了我从 Word 粘贴到记事本时得到的文本摘要之外。尽管如此,假设我想获取底层剪贴板内容并尝试提取对自己有用的东西。我该怎么做?这是否涉及弄乱其他进程的内存?或者尝试使用 dotnet 中的反射从剪贴板对象中检测和提取属性?或者你会如何处理这个问题?

ETA:好的,对于不太抽象的人,让我们考虑一个示例:在 Visual Studio 表单设计器中,我选择了一些小部件并进行复制。现在我想解析剪贴板以查找我刚刚复制的小部件的名称、位置和大小(我不想为 Visual Studio 等编写插件,我想专门从剪贴板获取信息)。我知道这在理论上是可能的,因为可以在 Visual Studio 进程的 2 个实例之间复制粘贴小部件(包括它们的名称、位置和其他属性)。

4

1 回答 1

2

好吧,您可以直接从System.Windows.Clipboard. 就是这么简单!

您可能需要使用一些更深奥的数据格式,但是一旦数据在剪贴板中,您就可以自由地阅读它。对于 Word,您可能会发现它放置在剪贴板中的 HTML 格式非常适合您的需要。

这里没有安全或隐私问题,因为用户已同意运行您的程序。允许您阅读另一个登录用户的剪贴板是错误的,但您不能这样做。


您已经更新了问题,现在要问一些更具体的问题。所以我将一些小部件复制到剪贴板,然后使用剪贴板查看器查看其中的格式。跳出来的是CF_DESIGNERCOMPONENTS_V2。对此的快速网络搜索将我带到了这个网站:

http://www.windowsdevelop.com/windows-forms-designer/for-designer-copycutpaste-what-type-data-format-does-ms-set-the-clipboard-dataobject-to-8507.shtml

那里有一些代码,显然来自 Reflector,它显示了设计器如何处理 Copy 命令:

protected void OnMenuCopy(object sender, EventArgs e)
{
      if (this.SelectionService != null)
      {
            Cursor cursor1 = Cursor.Current;
            try
            {
                  Cursor.Current = Cursors.WaitCursor;
                  ICollection collection1 = this.GetCopySelection();
                  collection1 = this.PrependComponentNames(collection1);
                  IDesignerSerializationService service1 = (IDesignerSerializationService) this.GetService(typeof(IDesignerSerializationService));
                  if (service1 != null)
                  {
                        object obj1 = service1.Serialize(collection1);
                        MemoryStream stream1 = new MemoryStream();
                        new BinaryFormatter().Serialize(stream1, obj1);
                        stream1.Seek((long) 0, SeekOrigin.Begin);
                        byte[] buffer1 = stream1.GetBuffer();
                        IDataObject obj2 = new DataObject("CF_DESIGNERCOMPONENTS_V2", buffer1);
                        Clipboard.SetDataObject(obj2);
                  }
                  this.UpdateClipboardItems(null, null);
            }
            finally
            {
                  Cursor.Current = cursor1;
            }
      }
}

这应该让你开始!

于 2011-03-08T20:05:13.720 回答