c# - ms-appdata 的脚本通知

标签 c# javascript html windows-8.1

我想通过 html 文件中的按钮通知我的 Web View 并触发 javascript:

function notify(str) {
    window.external.notify(str);
}

使用wv_ScriptNotify(..., ...)捕获的事件:

void wv_ScriptNotify(object sender, NotifyEventArgs e)
{
    Color c=Colors.Red;
    if (e.CallingUri.Scheme =="ms-appx-web" || e.CallingUri.Scheme == "ms-appdata")
    {
        if (e.Value.ToLower() == "blue") c = Colors.Blue;
        else if (e.Value.ToLower() == "green") c = Colors.Green;
    }
    appendLog(string.Format("Response from script at '{0}': '{1}'", e.CallingUri, e.Value), c);
}

我在 ms-appx-web 上设置了 html 文件并且它运行良好,我意识到 html 文件必须存储到本地文件夹中。所以我将 ms-appx-web:///.../index.html 更改为 ms-appdata:///local/.../index.html.

已经在微软论坛搜索得到this .在该线程上有一个使用解析器的解决方案,但我仍然感到困惑,它如何像使用 window.external.notify 一样从 javascript 通知?除了“ScriptNotify”之外,C# 端的哪种事件会捕获来自 javascript 的“通知”?


更新

here 有一个解决方案,使用解析器的示例,它说使用 ms-local-stream:// 而不是使用 ms-appdata://local 所以我仍然可以使用 ScriptNotify 事件。但不幸的是,使用 ms-appx 的示例意味着使用 InstalledLocation 而不是 LocalFolder

尝试谷歌搜索并搜索 msdn ms-local-stream 文档的站点,但唯一的文档只是 ms-local-stream 的格式,没有任何像这样的例子 ms-local- stream://appname_KEY/folder/file.

根据该文档,我做了一些示例来尝试:

public sealed class StreamUriWinRTResolver : IUriToStreamResolver
{
    /// <summary>
    /// The entry point for resolving a Uri to a stream.
    /// </summary>
    /// <param name="uri"></param>
    /// <returns></returns>
    public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
    {
        if (uri == null)
        {
            throw new Exception();
        }
        string path = uri.AbsolutePath;
        // Because of the signature of this method, it can't use await, so we 
        // call into a separate helper method that can use the C# await pattern.
        return getContent(path).AsAsyncOperation();
    }
    /// <summary>
    /// Helper that maps the path to package content and resolves the Uri
    /// Uses the C# await pattern to coordinate async operations
    /// </summary>
    private async Task<IInputStream> getContent(string path)
    {
        // We use a package folder as the source, but the same principle should apply
        // when supplying content from other locations
        try
        {
            // My package name is "WebViewResolver"
            // The KEY is "MyTag"
            string scheme = "ms-local-stream:///WebViewResolver_MyTag/local/MyFolderOnLocal" + path; // Invalid path
            // string scheme = "ms-local-stream:///WebViewResolver_MyTag/MyFolderOnLocal" + path; // Invalid path

            Uri localUri = new Uri(scheme);
            StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
            IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
            return stream.GetInputStreamAt(0);
        }
        catch (Exception) { throw new Exception("Invalid path"); }
    }
}

在我的 MainPage.xaml.cs 中:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    // The 'Host' part of the URI for the ms-local-stream protocol needs to be a combination of the package name
    // and an application-defined key, which identifies the specific resolver, in this case 'MyTag'.

    Uri url = wv.BuildLocalStreamUri("MyTag", "index.html");
    StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();

    // Pass the resolver object to the navigate call.
    wv.NavigateToLocalStreamUri(url, myResolver);
}

当它到达 StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri); 行时总是会出现异常。

如果有人遇到过这个问题并且已经解决了,请指教。

最佳答案

调试之后,我发现了一些有趣的事情,BuildLocalStreamUri部分已经自动生成了ms-local-stream

我对 StreamUriWinRTResolver 类中的 getContent 方法做了一些修改:

public sealed class StreamUriWinRTResolver : IUriToStreamResolver
{
    /// <summary>
    /// The entry point for resolving a Uri to a stream.
    /// </summary>
    /// <param name="uri"></param>
    /// <returns></returns>
    public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
    {
        if (uri == null)
        {
            throw new Exception();
        }
        string path = uri.AbsolutePath;
        // Because of the signature of this method, it can't use await, so we 
        // call into a separate helper method that can use the C# await pattern.
        return getContent(path).AsAsyncOperation();
    }
    /// <summary>
    /// Helper that maps the path to package content and resolves the Uri
    /// Uses the C# await pattern to coordinate async operations
    /// </summary>
    private async Task<IInputStream> getContent(string path)
    {
        // We use a package folder as the source, but the same principle should apply
        // when supplying content from other locations
        try
        {
            // Don't use "ms-appdata:///" on the scheme string, because inside the path
            // will contain "/local/MyFolderOnLocal/index.html"
            string scheme = "ms-appdata://" + path;

            Uri localUri = new Uri(scheme);
            StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri);
            IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
            return stream.GetInputStreamAt(0);
        }
        catch (Exception) { throw new Exception("Invalid path"); }
    }
}

更改 MainPage.xaml.cs 上的文件路径:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    // The 'Host' part of the URI for the ms-local-stream protocol needs to be a combination of the package name
    // and an application-defined key, which identifies the specific resolver, in this case 'MyTag'.

    Uri url = wv.BuildLocalStreamUri("MyTag", "/local/MyFolderOnLocal/index.html");
    StreamUriWinRTResolver myResolver = new StreamUriWinRTResolver();

    // Pass the resolver object to the navigate call.
    wv.NavigateToLocalStreamUri(url, myResolver);
    wv.ScriptNotify += wv_ScriptNotify;
}

protected override void wv_ScriptNotify(object sender, NavigationEventArgs e)
{
    if (e.CallingUri.Scheme == "ms-local-stream")
    {
        // Do your work here...
    }
}

关于c# - ms-appdata 的脚本通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18872269/

相关文章:

php - 面包屑 : change links depending on where I am

php - 努力用 php 显示 blob 图像

c# - 如何用很多参数重构类的方法?

c# - Visual Studio 快速操作和重构问题

c# - 带构造函数的模型与不带构造函数的模型 ASP.NET MVC

javascript - Kendo 网格计算变量

c# - 如何仅在 C# 控制台应用程序中生成 .csproj 项目文件?

javascript - Openlayers 4 - 使图层在功能点击时不可见

javascript - 输入字段仅接受数值使用 Vue.js 中的指令

html - 如何在 HTML 表单中创建一组项目的数组