javascript - 如何从 UWP(通用 Windows 平台)Web 应用程序启动 PDF

标签 javascript windows pdf uwp

我已将现有 Web 应用程序(HTML5、JS、CSS 等)转换为 Windows UWP 应用程序,以便(希望)我可以通过 Windows 应用商店将其分发到 Surface Hub,以便它可以离线运行。一切正常,除了 PDF 查看之外。如果我在新窗口中打开 PDF,基于 Edge 的浏览器窗口就会崩溃。如果我打开 IFRAME 并将 PDFJS 加载到其中,也会崩溃。我真正想做的只是将 PDF 交给操作系统,以便用户可以在他们安装的任何 PDF 查看器中查看它。

我发现一些 Windows 特定的 Javascript API 看起来很有前途,但我无法让它们工作。例如:

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

这会生成一个 file://URL,我可以将其复制到 Edge 中并显示 PDF,因此我知道 URL 内容是正确的。然而,在应用程序中它什么也不做。

如果我将 https://URL 传递到该 launchUriAsync 函数中,那就可以了。所以看起来该函数只是不喜欢 file://URL。

我也尝试过这个:

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

这也不起作用。再次,没有错误。它只是没有做任何事情。

还有什么我可以尝试的其他想法吗?

--更新--

查看已接受的答案。这是我最终使用的代码。 (请注意,我的所有文件都位于名为“app”的子文件夹中):

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 的源文件名无论如何都是自动生成的。)如果您想保留文件名,则必须添加一堆代码来检查它是否已经存在,等等。

最佳答案

我只是想在这个答案上添加一个变体,它将上面的一些细节与 this info 结合起来。关于在 JavaScript 应用程序中将 blob 保存为文件。我的情况是,我有一个代表 epub 文件数据的 BLOB,并且由于 UWP 内容安全策略,不可能简单地强制单击从 BLOB 创建的 URL(该“简单”方法被明确阻止)在 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 文档,将上述内容从片段和帖子回复中组合在一起。

关于javascript - 如何从 UWP(通用 Windows 平台)Web 应用程序启动 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900180/

相关文章:

javascript - 提交前复制表单输入字段的值

java - Elasticsearch 找不到 JAVA_HOME 或 Java,即使这两者都存在

windows - 从父批中杀死子批处理

windows - Visual Studio 2013 Professional 无法启动

linux - 如何生成发票

JavaScript "this.a = 2, b = 3"是在父作用域中查找的 "b"吗?

javascript - 代码可以在 jsfiddle 中运行,但不能在 html 文档中运行。为什么?

javascript - JQuery:级联下拉列表在按下后退按钮时丢失值

html - 使用iText将HTML转换为PDF

javascript - Jquery打印包含在字符串中的pdf