Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从UWP(通用Windows平台)Web应用程序启动PDF_Javascript_Windows_Pdf_Uwp - Fatal编程技术网

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

Javascript 如何从UWP(通用Windows平台)Web应用程序启动PDF,javascript,windows,pdf,uwp,Javascript,Windows,Pdf,Uwp,我已将现有的web应用程序(HTML5、JS、CSS等)转换为Windows UWP应用程序,以便(希望)通过Windows应用商店将其分发到Surface集线器,使其能够脱机运行。除了查看PDF外,一切正常。如果在新窗口中打开PDF,则基于边缘的浏览器窗口将崩溃。如果我打开一个IFRAME并将PDFJS加载到其中,这也会崩溃。我真正想做的是将PDF文件交给操作系统,这样用户就可以在他们安装的任何PDF查看器中查看它 我发现了一些特定于windows的Javascript API,这些API似乎

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

我发现了一些特定于windows的Javascript API,这些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) {
这将生成一个文件://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”的子文件夹中):


结果是您必须将/转换为\或找不到该文件。CopySync拒绝覆盖,所以我只使用performance.now来确保始终使用新的文件名。(在我的应用程序中,PDF的源文件名是自动生成的。)如果你想保留文件名,你必须添加一堆代码来检查它是否已经存在,等等。

你需要使用PDF API


您只是在尝试呈现PDF文件吗?

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


官方SDK示例:

我只是想在这个答案上添加一个变体,它结合了上面的一些细节和关于在JavaScript应用程序中将blob保存为文件的内容。我的情况是,我有一个BLOB,它表示epub文件的数据,并且由于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文档。

理想情况下,我只想在用户安装的任何PDF查看器中启动它。这就是我在基于电子的应用程序中所做的,而且效果非常好。一旦他们有了PDF,他们就可以查看、打印、发送电子邮件、将其保存在应用程序之外的某个地方。在我的移动应用程序中也是如此。我只是把它扔到iOS上的QuickLook上,或者扔到Android上的任何PDF查看器上。如果无法启动文件,那么编写一大堆代码来呈现PDF可能是一种退路。但为什么启动该文件是不可能的呢?这有点疯狂。该C#示例中的这条评论告诉我们:“无法直接从安装文件夹启动文件,所以请先将其复制到临时文件夹”。我会看看我是否能想出如何在javascript web应用程序中进行复制。正确,您需要从安装位置进行复制。您可以使用StorageFile.CopySync来实现这一点。我将编辑我的答案以捕获该细节。我将更新我的问题以显示我最终使用的代码。
// 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);
            });
        });
    });
});