我已将现有 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/