脚本通知ms-appdata [英] Script Notify for ms-appdata

查看:174
本文介绍了脚本通知ms-appdata的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从HTML文件中的按钮通知我的web视图并触发javascript:

 函数notify(str){ 
window.external.notify(str);



$ b

使用 wv_ScriptNotify(..., ...)

  void wv_ScriptNotify(object sender,NotifyEventArgs e)
{
颜色c = Colors.Red; (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(来自'{0}'脚本的响应:'{1}',e.CallingUri,e.Value),c);
}

我在 ms-appx- web ,它运行良好,我意识到该html文件必须存储到本地文件夹中。因此,我将 ms-appx-web:///.../index.html 更改为 ms-appdata:/// local /。 ../ index.html



已在Microsoft论坛中搜索并获取这是。在那个线程上有一个使用解析器的解决方案,但我仍然感到困惑,它如何通过javascript来通知,比如使用 window.external.notify ?在C#中哪种事件会捕获JavaScript以外的通知,而不是ScriptNotify?




更新



有一个解决方案来自 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



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

 公共密封类StreamUriWinRTResolver:IUriToStreamResolver 
{
///< summary>
///将Uri解析为流的入口点。
///< / summary>
///< param name =uri>< / param>
///<返回>< /返回>
public IAsyncOperation< IInputStream> UriToStreamAsync(Uri uri)
{
if(uri == null)
{
throw new Exception();
}
string path = uri.AbsolutePath;
//由于此方法的签名,它不能使用await,所以我们
//调用一个可以使用C#await模式的单独辅助方法。
return getContent(path).AsAsyncOperation();
}
///< summary>
/// Helper将路径映射到包内容并解析Uri
///使用C#await模式来协调异步操作
///< / summary>
私人异步任务< IInputStream> getContent(字符串路径)
{
//我们使用包文件夹作为源,但同样的原则应该适用
//从其他位置提供内容时
try
{
//我的软件包名称是WebViewResolver
// KEY是MyTag
string scheme =ms-local-stream:/// WebViewResolver_MyTag / local / MyFolderOnLocal +路径; //无效路径
// string scheme =ms-local-stream:/// WebViewResolver_MyTag / MyFolderOnLocal+ 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){抛出新的异常(Invalid path); }


在我的MainPage.xaml.cs中:

  protected override OnNavigatedTo(NavigationEventArgs e)
{
// URI的'Host'部分因为ms-local-stream协议需要是包名
//和一个应用程序定义的关键字的组合,这个关键字标识了特定的解析器,在这种情况下是'MyTag'。

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

//将解析器对象传递给导航调用。
wv.NavigateToLocalStreamUri(url,myResolver);
}

当它到达 StorageFile时,它总会得到异常f = await StorageFile.GetFileFromApplicationUriAsync(localUri); line。



如果有人遇到这个问题并且已经解决了,请告知。 p>

解决方案

调试完成后,我发现一些有趣的事情, BuildLocalStreamUri 自动创建 ms-local-stream



我对 getContent进行了一些更改方法在 StreamUriWinRTResolver 类中:

  public密封类StreamUriWinRTResolver:IUriToStreamResolver 
{
///< summary>
///将Uri解析为流的入口点。
///< / summary>
///< param name =uri>< / param>
///<返回>< /返回>
public IAsyncOperation< IInputStream> UriToStreamAsync(Uri uri)
{
if(uri == null)
{
throw new Exception();
}
string path = uri.AbsolutePath;
//由于此方法的签名,它不能使用await,所以我们
//调用一个可以使用C#await模式的单独辅助方法。
return getContent(path).AsAsyncOperation();
}
///< summary>
/// Helper将路径映射到包内容并解析Uri
///使用C#await模式来协调异步操作
///< / summary>
私人异步任务< IInputStream> getContent(字符串路径)
{
//我们使用包文件夹作为源,但同样的原则应该适用
//从其他位置提供内容时
try
{
//不要在方案字符串中使用ms-appdata:///,因为在路径
//中将包含/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){抛出新的异常(Invalid path); }
}
}

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

  protected override OnNavigatedTo(NavigationEventArgs e)
{
//'Host'部分的ms-local-stream协议的URI需要是包名称
//和应用程序定义的关键字的组合,该关键字标识特定的解析器,在本例中为MyTag。

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

//将解析器对象传递给导航调用。
wv.NavigateToLocalStreamUri(url,myResolver);
wv.ScriptNotify + = wv_ScriptNotify;
}

protected override void wv_ScriptNotify(object sender,NavigationEventArgs e)
{
if(e.CallingUri.Scheme ==ms-local-stream)
{
//在这里工作......
}
}


I want to notify my web view from button in html file and trigger the javascript:

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

The event captured using 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);
}

I set the html file on ms-appx-web and it running well, and I realize that the html file must be store into local folder. So I change the ms-appx-web:///.../index.html to ms-appdata:///local/.../index.html.

Already search in microsoft forum and get this. On that thread there is a solution using resolver, but I'm still confusing, how can it notify from javascript like using window.external.notify? And what kind of event in C# side that will capture the "notify" from javascript other than "ScriptNotify"?


Update

There is a solution from here, example using the resolver and it said to use ms-local-stream:// rather than using ms-appdata://local so I can still use the ScriptNotify event. But unfortunately the example using the ms-appx that means using the InstalledLocation not the LocalFolder.

Trying to googling and search in msdn site for the documentation for ms-local-stream but the only documentation is just the format of ms-local-stream without any example like this ms-local-stream://appname_KEY/folder/file.

Based from that documentation, I made some sample to try it:

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"); }
    }
}

And inside my 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);
}

It always get the exception when it reach the StorageFile f = await StorageFile.GetFileFromApplicationUriAsync(localUri); line.

If anybody ever got this problem and already solved it, please advise.

解决方案

After debugging it, I found something interesting, the BuildLocalStreamUri part is already make the ms-local-stream automatically.

I made some changes on the getContent method inside StreamUriWinRTResolver class:

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"); }
    }
}

Change the file path on the 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...
    }
}

这篇关于脚本通知ms-appdata的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆