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