Как я могу передать реализацию «IStorageItem» в DataPackage.SetStorageItems (items) и не получить InvalidCastException, возникающую в UWP? - PullRequest
0 голосов
/ 07 февраля 2019

Я разрабатываю приложение UWP, которое сможет обмениваться файлами.Я следовал документации от Microsoft , и решение работало довольно хорошо.

Вот моя реализация:

public void ShareLocalFile(LocalFileToShare file)
{
    DataTransferManager.GetForCurrentView().DataRequested += async (sender, args) =>
    {
        var deferral = args.Request.GetDeferral();

        try
        {
            var storageFile = await StorageFile.GetFileFromPathAsync(file.FilePath).AsTask();

            args.Request.Data.SetStorageItems(new[] { storageFile });
        }
        finally
        {
            deferral.Complete();
        }
    };

    DataTransferManager.ShowShareUI();
}

Тем не менее, приложение хранит все файлы, не относящиеся к человеку.читаемые имена, которые делают пользователей неудобным с обменом.Итак, я хотел поделиться файлом с альтернативным именем, не переименовывая его в файловой системе, потому что файлы открываются в стороннем считывателе.Кроме того, файлы довольно большие, и копирование их с новыми именами не очень хороший выбор.

Сначала я подумал, что могу создать символическую ссылку, но это возможно только с правами администратора

Затем я посмотрел на подпись метода "void DataPackage.SetStorageItems (IEnumerable value)" и предположил, что, вероятно, можно передать мою собственную реализацию IStorageItem чтоЯ сделал:

public class StorageItemWithAlternativeName : IStorageItem
{
    private readonly IStorageItem storageItem;

    public StorageItemWithAlternativeName(IStorageItem storageItem, string alternativeItemName)
    {
        this.storageItem = storageItem;
        Name = alternativeItemName;
    }

    public string Name { get; }

    // the interface implementation omitted for briefness but it simply delegates all actions to the decorated storageItem
}

public static class LocalFileToShareExtensions
{
    public static async Task<IStorageItem> GetStorageItem(this LocalFileToShare file)
    {
        var storageFile = await StorageFile.GetFileFromPathAsync(file.FilePath).AsTask();

        if (!string.IsNullOrWhiteSpace(file.AlternativeFileName))
        {
            storageFile = new StorageItemWithAlternativeName(storageFile, file.AlternativeFileName);
        }

        return storageFile;
    }
}

И тут я потерпел неудачу.Ошибка довольно глупая - метод SetStorageItems вызывает InvalidCastException: "Такой интерфейс не поддерживается. Коллекция содержит элементы, которые нельзя преобразовать в форму только для чтения."

Я исследовал журнал событий Windows и обнаружил следующую запись:

Faulting application name: [MyApp].Windows.exe, version: 7.0.0.0, time stamp:    0x5bb69bfe
Faulting module name: combase.dll, version: 10.0.17763.253, time stamp: 0xa3f81b2d
Exception code: 0xc000027b
Fault offset: 0x00209931
Faulting process id: 0x4ee4
Faulting application start time: 0x01d4be3ccca1f00f
Faulting application path: [PathToMyApp].Windows.exe
Faulting module path: C:\WINDOWS\System32\combase.dll
Report Id: 35999df1-6b4f-4675-a821-a84e6ea0cfb4
Faulting package full name: [MyAppPackageName]
Faulting package-relative application ID: App

Кажется, что объект DataPackage связывается с COM, поэтому я также попытался использовать атрибут [assembly: [ComVisible(true)] в своей сборке, но мне это не удалось.

Вопрос в том, как я могу ошарашить систему и поделиться файлом с другим именем? Можно ли передать мои собственные реализации в методы UWP SDK?Потому что теперь он нарушает принцип подстановки Лискова .

Буду признателен за любую помощь в этом!

1 Ответ

0 голосов
/ 07 февраля 2019

Пожалуйста, попробуйте использовать перегруженный метод SetStorageItems с параметром readOnly:false, что-то вроде этого:

args.Request.Data.SetStorageItems(new[] { storageFile }, false);
...