本文介绍了如何从UWP(通用Windows平台)Web应用程序启动PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've converted an existing web application (HTML5, JS, CSS, etc.) into a Windows UWP app so that (hopefully) I can distribute it via the Windows Store to Surface Hubs so it can run offline. Everything is working fine, except PDF viewing. If I open a PDF in a new window, the Edge-based browser window simply crashes. If I open an IFRAME and load PDFJS into it, that also crashes. What I'd really like to do is just hand off the PDF to the operating system so the user can view it in whatever PDF viewer they have installed.

我是发现一些特定于Windows的Javascript API似乎很有希望,但我无法让它们工作。例如:

I've found some windows-specific Javascript APIs that seem promising, but I cannot get them to work. For example:

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

生成一个文件://我可以复制到Edge的URL,它显示PDF,所以我知道URL的内容是正确的。但是,在应用程序中它什么都不做。

That generates a file:// URL that I can copy into Edge and it shows the PDF, so I know the URL stuff is right. However, in the application it does nothing.

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

If I pass an https:// URL into that launchUriAsync function, that works. So it appears that function just doesn't like file:// URLs.

I还试过这个:

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

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

That didn't work either. Again, no error. It just didn't do anything.

我可以尝试其他任何想法吗?

Any ideas of other things I could try?

- 更新 -

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

See the accepted answer. Here is the code I ended up using. (Note that all my files are in a subfolder called "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的源文件名。)如果你想保留文件名,你必须添加一堆代码来检查它是否已经存在等等。

Turns out you have to turn the / into \ or it won't find the file. And copyAsync refuses to overwrite, so I just use performance.now to ensure I always use a new file name. (In my application, the source file names of the PDFs are auto-generated anyway.) If you wanted to keep the filename, you'd have to add a bunch of code to check whether it's already there, etc.

推荐答案

LaunchFileAsync是在这里使用的正确API。您无法直接从安装目录启动文件,因为它受到保护。您需要先将其复制到其他应用可访问的位置(例如您的PDF查看器)。使用StorageFile.CopyAsync在所需位置制作副本。

LaunchFileAsync is the right API to use here. You can't launch a file directly from the install directory because it is protected. You need to copy it first to a location that is accessible for the other app (e.g. your PDF viewer). Use StorageFile.CopyAsync to make a copy in the desired location.

官方SDK示例:

这篇关于如何从UWP(通用Windows平台)Web应用程序启动PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 23:55