Я преобразовал существующее веб-приложение (HTML5, JS, CSS и т. Д.) В приложение Windows UWP, чтобы (надеюсь) я мог распространять его через Магазин Windows для Surface Hubs, чтобы оно могло работать в автономном режиме. Все работает нормально, кроме просмотра PDF. Если я открываю PDF в новом окне, окно браузера на основе Edge просто вылетает. Если я открываю IFRAME и загружаю в него PDFJS, это также приводит к сбою. Что я действительно хотел бы сделать, так это просто передать PDF в операционную систему, чтобы пользователь мог просматривать его в любом установленном им просмотрщике PDF.

Я нашел некоторые специфичные для Windows API Javascript, которые кажутся многообещающими, но я не могу заставить их работать. Например:

 Windows.System.Launcher.launchUriAsync(
   new Windows.Foundation.Uri(
     "file:///"+
     Windows.ApplicationModel.Package.current.installedLocation.path
       .replace(/\//g,"/")+"/app/"+url)).then(function(success) {
                if (!success) {

Это генерирует файл: // URL, который я могу скопировать в Edge, и показывает PDF, так что я знаю, что URL-адрес правильный. Однако в приложении это ничего не делает.

Если я передаю https: // URL в эту функцию launchUriAsync, это работает. Таким образом, похоже, что функция просто не любит file: // URLs.

Я тоже пробовал это:

Windows.ApplicationModel.Package.current.installedLocation.getFileAsync(url).then(
  function(file) { Windows.System.Launcher.launchFileAsync(file) })

Это тоже не сработало. Опять без ошибок. Он просто ничего не делал.

Любые идеи о других вещах, которые я мог бы попробовать?

-- Обновить --

Смотрите принятый ответ. Вот код, который я использовал в конечном итоге. (Обратите внимание, что все мои файлы находятся в подпапке под названием «приложение»):

if (location.href.match(/^ms-appx:/)) {
        url = url.replace(/\?.+/, "");
        Windows.ApplicationModel.Package.current.installedLocation.getFileAsync(("app/" + url).replace(/\//g,"\\")).then(
            function (file) {
                var fn = performance.now()+url.replace(/^.+\./, ".");
                file.copyAsync(Windows.Storage.ApplicationData.current.temporaryFolder,
                    fn).then(
                    function (file2) {
                        Windows.System.Launcher.launchFileAsync(file2)
                    })
            });
        return;
    }

Оказывается, вы должны включить / в \, иначе файл не будет найден. А copyAsync отказывается перезаписывать, поэтому я просто использую performance.now, чтобы всегда использовать новое имя файла. (В моем приложении имена исходных файлов PDF все равно генерируются автоматически.) Если вы хотите сохранить имя файла, вам нужно добавить кучу кода, чтобы проверить, есть ли оно там и т. Д.

2
Joshua Smith 27 Авг 2017 в 01:31

3 ответа

Лучший ответ

LaunchFileAsync - это правильный API для использования здесь. Вы не можете запустить файл непосредственно из каталога установки, потому что он защищен. Сначала необходимо скопировать его в место, доступное для другого приложения (например, для просмотра PDF). Используйте StorageFile.CopyAsync, чтобы сделать копию в нужном месте.

Официальный пример SDK: https://github.com/Microsoft/ Windows, универсальные - образцы / дерево / мастер / образцы / AssociationLaunching

1
Stefan Wick MSFT 27 Авг 2017 в 18:47

Вам нужно будет использовать PDF API https: // github.com/Microsoft/Windows-universal-samples/tree/master/Samples/PdfDocument/js

https://github.com/Microsoft/Windows-universal-samples/blob/master/Samples/PdfDocument/js/js/scenario1-render.js

Вы просто пытаетесь сделать PDF-файл?

0
Kevin Hill - Salesforce 27 Авг 2017 в 06:19

Я просто подумал, что добавлю вариант этого ответа, который объединяет некоторые детали сверху с эта информация о сохранении большого двоичного объекта как файл в приложении JavaScript. В моем случае у меня есть BLOB, который представляет данные для файла epub, и из-за политики безопасности содержимого UWP невозможно просто принудительно щелкнуть URL-адрес, созданный из BLOB (этот «простой» метод явно заблокирован в UWP, хотя это работает в Edge). Вот код, который работал для меня:

// Copy BLOB to downloads folder and launch from there in Edge
// First create an empty file in the folder
Windows.Storage.DownloadsFolder.createFileAsync(filename,
    Windows.Storage.CreationCollisionOption.generateUniqueName).then(
    function (file) {
    // Open the returned dummy file in order to copy the data to it 
    file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (output) {
        // Get the InputStream stream from the blob object 
        var input = blob.msDetachStream();
        // Copy the stream from the blob to the File stream 
        Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output).then(
        function () {
            output.flushAsync().done(function () {
                input.close();
                output.close();
                Windows.System.Launcher.launchFileAsync(file);
            });
        });
    });
}); 

Обратите внимание, что CreationCollisionOption.generateUniqueName обрабатывает переименование файла автоматически, поэтому мне не нужно возиться с performance.now(), как в ответе выше.

Просто добавлю, что одна из вещей, которая так сложна в разработке приложений UWP, особенно в JavaScript, это то, как трудно найти целостную информацию. Мне потребовались часы и часы, чтобы собрать все вышеперечисленное из фрагментов и после ответов, следуя ложным путям и неполной документации MS.

1
Jaifroid 29 Ноя 2018 в 14:52