Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用剪贴板访问的陌生度_C#_Clipboard - Fatal编程技术网

C# 使用剪贴板访问的陌生度

C# 使用剪贴板访问的陌生度,c#,clipboard,C#,Clipboard,我正在尝试编写一个小应用程序,它需要使用剪贴板来实现一些功能。由于我不想覆盖剪贴板中当前的用户数据,我决定将其保存到内存中,完成我的工作,然后将其写回。下面的代码是一个控制台应用程序,它是我正在尝试做的一个简单示例 我遇到的问题是恢复状态。如果我在运行应用程序之前从VisualStudio将某些内容复制到剪贴板,那么剪贴板中总共有六个对象(各种字符串格式和区域设置),它们都会被放入缓存中。一旦我恢复了它们,尽管剪贴板中只有区域设置,而且似乎每次调用SetData()都会覆盖最后一次。(顺便说一句

我正在尝试编写一个小应用程序,它需要使用剪贴板来实现一些功能。由于我不想覆盖剪贴板中当前的用户数据,我决定将其保存到内存中,完成我的工作,然后将其写回。下面的代码是一个控制台应用程序,它是我正在尝试做的一个简单示例

我遇到的问题是恢复状态。如果我在运行应用程序之前从VisualStudio将某些内容复制到剪贴板,那么剪贴板中总共有六个对象(各种字符串格式和区域设置),它们都会被放入缓存中。一旦我恢复了它们,尽管剪贴板中只有区域设置,而且似乎每次调用SetData()都会覆盖最后一次。(顺便说一句,SetDataObject似乎不是GetDataObject的倒数,所以我不能直接使用它)

你知道我如何存储剪贴板状态并在以后恢复吗

    [STAThread]
    static void Main(string[] args)
    {
        //Store the old clipboard data
        Dictionary<string, object> clipboardCache = new Dictionary<string, object>();

        IDataObject clipboardData = Clipboard.GetDataObject();

        foreach (string format in clipboardData.GetFormats())
        {
            clipboardCache.Add(format, clipboardData.GetData(format));
        }

        Clipboard.SetText("Hello world!");

        string value = Clipboard.GetText();

        Console.WriteLine(value);

        //Clear the clipboard again and restore old data
        Clipboard.Clear();

        foreach (KeyValuePair<string, object> valuePair in clipboardCache)
        {
            Clipboard.SetData(valuePair.Key, valuePair.Value);
            Thread.Sleep(100);
        }

        Console.ReadLine();
    }
[STAThread]
静态void Main(字符串[]参数)
{
//存储旧的剪贴板数据
Dictionary clipboardCache=新字典();
IDataObject clipboardData=剪贴板.GetDataObject();
foreach(clipboardData.GetFormats()中的字符串格式)
{
添加(格式,clipboardData.GetData(格式));
}
Clipboard.SetText(“你好,世界!”);
字符串值=剪贴板.GetText();
控制台写入线(值);
//再次清除剪贴板并恢复旧数据
剪贴板。清除();
foreach(剪贴板缓存中的KeyValuePair-valuePair)
{
剪贴板.SetData(valuePair.Key,valuePair.Value);
睡眠(100);
}
Console.ReadLine();
}

马丁,我已经试过你的代码了。我已经在我的系统上安装了。当我运行你的代码时,它会运行,我会得到和ClipX缓存中一样多的项目。但是调用
Clipboard.GetDataObject()
只返回最新的对象。所以当你调用这个循环时会发生什么:

foreach (string format in clipboardData.GetFormats())
{
    clipboardCache.Add(format, clipboardData.GetData(format));
}
它返回ClipX中所有对象的格式,并转换

IDataObject clipboardData = Clipboard.GetDataObject();
实际上,当你执行这个循环时

foreach (KeyValuePair<string, object> valuePair in clipboardCache)
{
    Clipboard.SetData(valuePair.Key, valuePair.Value);
    Thread.Sleep(100);
}
foreach(剪贴板缓存中的KeyValuePair-valuePair)
{
剪贴板.SetData(valuePair.Key,valuePair.Value);
睡眠(100);
}
您只有一个对象被设置为剪贴板


其次,当使用剪贴板时,SetData(格式,对象)用新对象覆盖旧对象是正常行为,而不是正常行为。如果您正在构建多条目剪贴板之类的东西,那么您需要拦截复制和粘贴系统调用,并将对象保留在程序的内存或磁盘中。您不能依赖默认剪贴板。

windows剪贴板一次只有一个对象。但是一个对象有多种可用格式(例如RTF、文本、HTML)。我认为你把它弄得太复杂了,你的代码应该是这样的:

//Store the old clipboard data
IDataObject clipboardData = Clipboard.GetDataObject();

Clipboard.SetText("Hello world!");

string value = Clipboard.GetText();
Console.WriteLine(value);

//Clear the clipboard again and restore old data
Clipboard.Clear();
Clipboard.SetDataObject(clipboardData);

Console.ReadLine();

您是否使用了ClipX之类的多对象剪贴板插件?该代码片段实际上解决了我的问题——与您的完全不同——但google将我带到这里,因此我将在这里发布详细信息:对于任何无法从控制台应用程序访问windows剪贴板的人,请确保使用“[StatThread]”属性装饰您的“Main”方法!:谢谢你的回复。我根本不使用任何剪贴板扩展,我只想保存一个项目,但如果从Visual Studio复制文本(例如),剪贴板中将存储多个项目-文本的字符串表示形式、RTF版本、语言环境-我的剪贴板数据总共有六种格式,我想把这六个对象都放回剪贴板。可以尝试从Visual Studio复制文本吗?那么你从clipboardData.GetFormats()中得到了多少结果呢?只是想补充一下-我还以为你只能在剪贴板中存储一个项目,但是由于今天对它进行了处理,你可以在每个格式中存储一个项目。我也很想知道我是否在这方面做得不对……正如我在问题中所说的,我认为SetDatObject不起作用,因为它似乎不接受IDataObject并将剪贴板留空,但我错了。默认情况下,它仅在应用程序退出之前将数据保留在剪贴板中。仔细阅读后,我发现您的代码在您用SetDataObject(clipboardData,true)替换SetDataObject(clipboardData)时起作用。谢谢-我觉得应该很简单。