UWP支持使用Javascript来调用Windows Runtime接口。但是有一个问题,官方例子中Create a “Hello, world” app (JS)只适用于Visual Studio 2017。因为Visual Studio 2019在可创建的项目列表中移除了模板Blank App (Universal Windows) JavaScript
。
关于Visual Studio 2019为什么移除Blank App (Universal Windows) JavaScript
,网上有一些讨论:
- Please don’t remove JavaScript UWP development from VS 2019
- Finding Blank App (Universal Windows) JavaScript
- VS2019 drops .jsproj (UWP JS) support, VS2017 keeps working #327
- Visual Studio 2019 PWA Guidance
根据这条信息:
You can build PWAs optimized for Windows using the tools provided in Visual Studio 2019. Support for WWAs is available in Visual Studio 2017 and not Visual Studio 2019.
上面的PWA指ProgressiveWebApp,WWA指WindowsWebApp。我觉得大体的问题是微软决定转而支持PWA这种标准的架构,而不是Cordorva这种基于Electron的混合架构(需要采用wwahost.exe)。
使用UWP的WebView
虽然没有了JS的UWP应用模板,但是还是可以在UWP的WebView中使用JS调用WinRT的API。打开VS2019,创建一个Blank App Universal Windows C#项目,取名HelloJS。
根据Call WinRT APIs from your PWA的指示,打开Package.appxmanifest文件,设置相应的Application Content URI Rules (ACURs)。具体的做法是在Content URIs面版上添加
- URI:
ms-appx-web:///hello.html
- Rule:
Include
- WinRT Access:
All
第二步是添加一个Text文件,会自动生成TextFile1.txt,将其重命名为hello.html,将差不多来自Create a “Hello, world” app (JS)的内容填入:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello World</title>
</head>
<body>
<p>Click the button..</p>
<button id="button">Hello world!</button>
<script language="javascript">
// Your code here!
window.onload = function () {
document.getElementById("button").onclick = function (evt) {
sayHello()
}
}
function sayHello() {
var messageDialog = new Windows.UI.Popups.MessageDialog("Hello, world!", "Alert");
messageDialog.showAsync();
}
</script>
</body>
</html>
保存完上述文件后,记得在Solution Explorer里面选中该文件,然后
Alt+Enter
编辑该文件的属性,将Item Type改为Copy File
。
接下来,只要打开MainPage.xaml,将里面的<Grid></Gride>
换成:
<WebView Source="ms-appx-web:///hello.html"/>
然后编译运行,就可以看到和Create a “Hello, world” app (JS)一样的HTML页面,有一个按键,点击以后会产生一个Alert。任务完成。
关于AllowForWeb
WinRT Access除了All
以外,还可以设置成AddWebAllowedObject
。但是AddWebAllowedObject有一个要求,那就是其API必须来自另外一个Windows Runtime Component(也就是另外一个DLL)。否则就会出错,参考UWP WebView Javascript “Object doesn’t support property or method”
文档中的说法是:
The object passed into AddWebAllowedObject(System.String,System.Object) must be imported from a Windows Runtime component that is separate from the app assembly. This is necessary for the AllowForWeb attribute to be property identified by the WebView security subsystem. If you use a class from your app project, AddWebAllowedObject(System.String,System.Object) does not work.
其他参考
- WebView (EdgeHTML) for Windows 10 apps
- 2015 Project Westminster in a nutshell
- Tailor your PWA for Windows
- Windows Runtime (WinRT) for JavaScript
- Progressive Web Apps on Windows
- W3C WebDriver
- uwp - Dave’s Blog
- MicrosoftEdge/WebAppsDocs
(完)
更新2019-10-02,如何在VS2019 Debug Webview中的JS
官网上只有VS2017的指导:Debug a WebView control in a UWP App
在2019中,也可以做类似的操作,在项目的Debugging配置中,选择Script only,然后再启动调试。也可以不启动调试,但是以Script only的方式去attach目前进程。
- JavaScript Debugging in a Web Browser Control with Visual Studio
- Walkthrough of creating a C++/CX Windows Runtime component, and calling it from JavaScript or C#
ActivatableClass
- ActivatableClass (in InProcessServer) (Windows 10)
- Extension (in Package/Extensions) (Windows 10)
- Package manifest schema reference for Windows 10
- How to specify extensions in a package manifest
- Calling WinRT Components from a Win32 process via the Desktop Bridge
(更新完)