Содержимое буфера обмена закрытого универсального приложения Windows

Я пишу универсальное приложение С# для Windows, в котором пользователь может скопировать файл в буфер обмена. Но если приложение закрыто, содержимое буфера обмена теряется. Удобство использования ужасно, если пользователь может так легко потерять содержимое буфера обмена. Есть ли способ сделать содержимое буфера обмена приложения постоянным, как в любом другом классическом приложении Windows?

Образец кода:

public static void CopyFileToClipboard(StorageFile file) {
    DataPackage dp = new DataPackage();
    dp.RequestedOperation = DataPackageOperation.Copy;
    dp.SetStorageItems(new List<StorageFile>() { file });
    Clipboard.SetContent(dp); // not available after app closed
    Clipboard.Flush();
}

public static void CopyTextToClipboard(string text) {
    DataPackage dp = new DataPackage();
    dp.RequestedOperation = DataPackageOperation.Copy;
    dp.SetText(text); // available after app closed
    Clipboard.SetContent(dp);
    Clipboard.Flush();
}

//I have tried to copy the file to the app folder first but it has nothing changed.
public async static void CacheAndCopyFileToClipboard(StorageFile file) {
    DataPackage dp = new DataPackage();
    dp.RequestedOperation = DataPackageOperation.Copy;
    var xfile = await ApplicationData.Current.LocalFolder.CreateFileAsync(file.Name);
    await file.CopyAndReplaceAsync(xfile);
    dp.SetStorageItems(new List<StorageFile>() { xfile });
    Clipboard.SetContent(dp); // not available after app closed
    Clipboard.Flush();
}

Итак, вопрос в том, как я могу поместить файл в буфер обмена, чтобы пользователи могли вставлять его, даже если приложение закрыто?

Редактировать: кажется, что это проблема всех универсальных приложений Windows, например, если вы копируете изображение в приложении Windows Photo, вы можете вставить его только во время работы приложения Photo. Я не могу представить, что это странное поведение должно быть поведением приложений по умолчанию. Это больше похоже на ошибку, потому что я не вижу причин для такого странного поведения.

Edit2: новый пример проблемы (спасибо Joe300 за отзыв). Он работает со строками, но не с StorageFile (даже если он сначала скопирован в локальную папку приложения). По какой причине команда Flush() не работает с файлами? Есть ли что-то особенное, что следует учитывать при использовании файлов (разрешения, ...)?


person ctron    schedule 03.08.2015    source источник


Ответы (1)


Вам нужно будет добавить вызов Flush чтобы контент был доступен после закрытия приложения.

Добавляет содержимое в буфер обмена и освобождает объект DataPackage из исходного приложения. Этот метод позволяет содержимому оставаться доступным после завершения работы приложения.

Вы также должны установить RequestedOperation:

dp.RequestedOperation = DataPackageOperation.Copy;
try
{
    Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dp);
    Clipboard.Flush();
}
catch (Exception ex)
{
   // Copying data to Clipboard can potentially fail - for example, if another application is holding Clipboard open                  
}

Помимо этого, действительно нет никаких других вариантов манипулирования Clipboard.

person WiredPrairie    schedule 05.08.2015
comment
Это не решило проблему, если я закрою приложение, файл будет потерян. Вызов Clipboard.Flush() не изменил этого, хотя описание этой команды выглядит так, как будто это решение. Возможно, это проблема с объектами StorageFile, потому что кажется, что он работает со строками. - person ctron; 10.08.2015
comment
Как вы инициализируете StorageFile? - person WiredPrairie; 10.08.2015
comment
дп.Flush(); не существует в DataPackage только в буфере обмена. StorageFile и SetContent не должны быть проблемой, потому что все работает отлично, пока приложение работает, но если приложение закрывается, содержимое буфера обмена теряется. Расширения Flush и DataPackageOperation.Copy к моему исходному коду не решают эту проблему... - person ctron; 10.08.2015
comment
Если файл недоступен после выхода из приложения, операция с файлом буфера обмена не будет работать. Flush в коде действительно была опечатка. Как вы создаете и инициализируете файл? - person WiredPrairie; 10.08.2015
comment
Clipboard.Flush(); должен быть после Clipboard.SetContent(dp);, чтобы содержимое оставалось в буфере обмена после закрытия приложения. Clipboard.SetContent(dp); Clipboard.Flush(); - person Andrew Sauder; 15.04.2016
comment
Если возможно, вам следует отложить Clipboard.Flush(), пока вы не закроете или не приостановите свое приложение. Существует высокая вероятность того, что какой-то процесс может открыть буфер обмена, чтобы увидеть его содержимое сразу после вызова SetContent(), что может конфликтовать с вызовом Flush. В противном случае вам, возможно, придется поместить вызов Flush в отдельный блок try-catch и повторить попытку несколько раз после задержки, если сначала он не удался. - person Filip Skakun; 14.10.2020