none
HtmlPage.Window.Invoke() 在IE7.0报iexplore.exe异常,在360浏览器正常 RRS feed

  • 问题

  • BLOCKED SCRIPT

      <script type="text/javascript">

            function CloseBuoyage() {
                var control = document.getElementById("silverlightBuoyage");
                control.style.display = "none";
            }


        </script>

    HTML:

    <body>
        <object id="SilverlightMain" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            style="width: 0px; height: 0px; position: absolute; top: 250px; left: 500px;">
            <param name="source" value="ClientBin/MainAnimation.xap" />

            .......

       </object>


       <object id="silverlightBuoyage" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            style="position: absolute; width: 40px; height: 120px">
            <param name="source" value="ClientBin/TencentBuoyage.xap" />

           .......
              </object>
    </body>

    C#:

           private void Close_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                HtmlPage.Window.Invoke("CloseBuoyage"); 在IE7.0报iexplore.exe异常,在360浏览器正常
            }

     

    2008年12月9日 5:02

答案

  • 堆栈和异常信息,哥们。

     

    没有这些东西,我们只能瞎猜你的问题,然后随便给你一个解决方案。

     

    HtmlPage.Window.Invoke函数的过程是这样的:

    1. C#代码通过P/Invoke调用Silverlight Runtime的DLL里面的C函数(虽然是用C++写的,但是声明成C兼容的函数)InvokeBrowseFunc(假设的名字)
    2. C函数InvokeBrowseFunc判断浏览器的内核(例如是否是IE,Firefox还是Safari - Mac机),然后通过一些预定义的C++基类调用针对各个内核实现的子类,例如IEBrowserHelp(假设的名字)
    3. IEBrowserHelp->Invoke里面调用IE提供的IHTMLXXXXXX接口来操作网页的DOM对象,例如调用脚本程序。
    4. IHTMLXXXXXX发现你调用的是脚本函数,调用Javascript解释引擎,告诉Javascript引擎调用脚本函数
    5. Javascript引擎将调用结果返回给IHTMLXXXXXX
    6. IHTMLXXXXXX将结果返回给IEBrowserHelp->Invoke
    7. IEBrowserHelp->Invoke再将结果返回给InvokeBrowseFunc
    8. InvokeBrowseFunc再将结果返回给我们的HtmlPage.Window.Invoke
    9. HtmlPage.Window.Invoke判断返回的HRESULT值,然后转换成对应的.NET异常。

    这9个步骤里面,可能会有Javascript异常,也可能会有C++异常,还有可能会有.NET异常。一般C++异常会将你的IE干掉,而其他两种异常可以被IE消化,然后在左下角出现一个惊叹号!

     

    因此,请给我们你的堆栈和异常信息。

     

    附,你可以用Eval函数试一下,Eval应该可以用。

    2008年12月9日 11:35
  •  

    查证上面楼主代码没问题,不会引起ie报错...楼主那个程序明天偶再研究下,不是这里的问题
    2008年12月9日 12:25
    版主

全部回复

  • 你可以试试别的方法,如 ScriptObject..Invoke 之类的
    2008年12月9日 5:10
    版主
  •  孟宪会 写:
    你可以试试别的方法,如 ScriptObject..Invoke 之类的

     ScriptObject so = HtmlPage.Window.GetProperty("CloseBuoyage") as ScriptObject;
                so.InvokeSelf(); 也是一样报异常

    有时候还会报:已禁用 DOM/脚本桥。
    2008年12月9日 5:36
  • <object data="data:application/x-silverlight,"
        type="application/x-silverlight-2-b2"
        width="300" height="100"
    <param name="source"     value="MySample.xap"/>
    <param name="enableHtmlAccess" value="true" />
    </object>

    同一个域默认为true

    enableHtmlAccess设置true,直接调用 HtmlPage..Document 可以吗

    有时间我做个例子试试
    2008年12月9日 6:00
    版主
  • 有劳孟哥亲自出马!

    <param name="enableHtmlAccess" value="true" />加上还是异常

    2008年12月9日 6:27
  •  

    经测试没问题啊,360浏览器也是用的ie内核,估计是你的ie7装什么东西或者常年的不正常关机积累了些问题,重新安装修复下再看看
    2008年12月9日 7:36
    版主
  •  

    其他机器访问我的机器也是这样的。
    2008年12月9日 8:33
  •  八爪熊 写:

     

    经测试没问题啊,360浏览器也是用的ie内核,估计是你的ie7装什么东西或者常年的不正常关机积累了些问题,重新安装修复下再看看


    可以先禁用一些加载项试试
    2008年12月9日 8:34
    版主
  • 堆栈和异常信息,哥们。

     

    没有这些东西,我们只能瞎猜你的问题,然后随便给你一个解决方案。

     

    HtmlPage.Window.Invoke函数的过程是这样的:

    1. C#代码通过P/Invoke调用Silverlight Runtime的DLL里面的C函数(虽然是用C++写的,但是声明成C兼容的函数)InvokeBrowseFunc(假设的名字)
    2. C函数InvokeBrowseFunc判断浏览器的内核(例如是否是IE,Firefox还是Safari - Mac机),然后通过一些预定义的C++基类调用针对各个内核实现的子类,例如IEBrowserHelp(假设的名字)
    3. IEBrowserHelp->Invoke里面调用IE提供的IHTMLXXXXXX接口来操作网页的DOM对象,例如调用脚本程序。
    4. IHTMLXXXXXX发现你调用的是脚本函数,调用Javascript解释引擎,告诉Javascript引擎调用脚本函数
    5. Javascript引擎将调用结果返回给IHTMLXXXXXX
    6. IHTMLXXXXXX将结果返回给IEBrowserHelp->Invoke
    7. IEBrowserHelp->Invoke再将结果返回给InvokeBrowseFunc
    8. InvokeBrowseFunc再将结果返回给我们的HtmlPage.Window.Invoke
    9. HtmlPage.Window.Invoke判断返回的HRESULT值,然后转换成对应的.NET异常。

    这9个步骤里面,可能会有Javascript异常,也可能会有C++异常,还有可能会有.NET异常。一般C++异常会将你的IE干掉,而其他两种异常可以被IE消化,然后在左下角出现一个惊叹号!

     

    因此,请给我们你的堆栈和异常信息。

     

    附,你可以用Eval函数试一下,Eval应该可以用。

    2008年12月9日 11:35
  • 可以提供异常信息么

    另外用HtmlPage.Window.Eval()是什么结果?

    以及你的silverlight版本...-_-b

    2008年12月9日 11:55
  •  

    查证上面楼主代码没问题,不会引起ie报错...楼主那个程序明天偶再研究下,不是这里的问题
    2008年12月9日 12:25
    版主
  • JS:

            function Close(obj1, obj2) {
                document.getElementById(obj1).style.display = "none";
                document.getElementById(obj2).style.display = "block";        }
       

    C#

     HtmlPage.Window.Invoke("Close", “Main”,"Buoyage”);

    HtmlPage.Window.Invoke("Close", “Buoyage”,"Main”);

    执行以上其中一句,会异常

    现在看下来只要是Close的对象是自己本身的话,也就是display = "none"的对象是自己本身,就会异常。但是在360浏览器中正常

     

    Killmyday 的分析,那应该算C++异常,因为异常时直接把IE关闭了

    Eval函数也是一样的异常。

    SIlverlight 2.0 RTM


    2008年12月10日 5:54
  •  打火机 写:

    JS:

            function Close(obj1, obj2) {
                document.getElementById(obj1).style.display = "none";
                document.getElementById(obj2).style.display = "block";        }
       

    C#

     HtmlPage.Window.Invoke("Close", “Main”,"Buoyage”);

    HtmlPage.Window.Invoke("Close", “Buoyage”,"Main”);

    执行以上其中一句,会异常

    现在看下来只要是Close的对象是自己本身的话,也就是display = "none"的对象是自己本身,就会异常。但是在360浏览器中正常

     

    Killmyday 的分析,那应该算C++异常,因为异常时直接把IE关闭了

    Eval函数也是一样的异常。

    SIlverlight 2.0 RTM


     

    嗯,我以前用HtmlPage.Window.Invoke()操作Flash的时候也会异常,浏览器关闭。

    最好不要对objectid直接操作,可以操作上层的DIV,楼主试试

    2008年12月10日 9:02
    版主
  •  

    我重现了一下你的代码,在我的IE 7.0上不会Crash呀,而且一切工作正常,这是我的重现代码:

     

    Js:
            function Close(obj1, obj2) {
                document.getElementById(obj1).style.display = "none";
                document.getElementById(obj2).style.display = "block";
            }      

     

    Html:


    <div id="silverlightControlHost">
      <object id="Main" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%">
       <param name="source" value="TestSilverlight.xap"/>
       <param name="onerror" value="onSilverlightError" />
       <param name="background" value="white" />
       <param name="minRuntimeVersion" value="2.0.31005.0" />
       <param name="autoUpgrade" value="true" />
       <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
            <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
       </a>
      </object>
      <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
      
      <object id="Buoyage" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%">
       <param name="source" value="TestSilverlight.xap"/>
       <param name="onerror" value="onSilverlightError" />
       <param name="background" value="white" />
       <param name="minRuntimeVersion" value="2.0.31005.0" />
       <param name="autoUpgrade" value="true" />
       <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
            <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
       </a>
      </object>
        </div>

     

    C#:
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                HtmlPage.Window.Invoke("Close", "Main","Buoyage");
            }

     

    XAML:

        <Grid x:Name="LayoutRoot" Background="White">
            <Button Click="Button_Click" />
        </Grid>

     

    我建议你用VS附加到IE上,看看到底是什么问题,方法如下:

    1. 打开IE,并且浏览到你的问题页面
    2. 打开VS 2008, 点击“Tools” --> "Options" --> "Debugging" --> "Symbols",将Symbol Server的路径设置成微软的公开Symbols Server路径:http://msdl.microsoft.com/download/symbols
    3. 当然啦,奉劝你同时设置“Cache symbols from symbol severs to this directory”来缓存从网上下载的Symbol
    4. 最后在VS 2008里面点击“Debug” --> “Attach To Process ...”,你可以手动选择Silverlight,或者Native。由于我怀疑你的问题是IE有其他的插件冲突,因此建议你选择Native来调试IE的C++代码。
    5. 根据需要勾上在异常发生的时候中断程序执行。你可以参考这篇文章来设置:http://blog.csdn.net/Donjuan/archive/2008/12/05/3454650.aspx
    6. 执行你的重现步骤,等VS中断了以后,将“堆栈”窗口里面的内容粘贴过来,让我们看看。

    注意,你的堆栈如果是这种形式的话,对我们的分析是没有意义的:

        user32!68796465

        ieexplorer.exe!54045783

     

    你贴出来的堆栈应该是

        user32!CreateWindowW(...)

        ieexplorer.exe!__main(argc = 1)

     

    如果上面的操作还是不能解决你的问题的话,请参考下面的文章设置验尸调试

    http://blog.csdn.net/Donjuan/archive/2008/12/04/3446670.aspx

     

    然后在Windbg里面(Windbg可以从微软的网站上下载到),执行下面这个命令:

    .dump /ma c:\badbug.dmp

     

    然后将badbug.dmp发给谁去研究一下吧,当然啦,我很怀疑有人愿意去下载这个dmp文件--太大了(好几百M)。

     

    最后,这篇文章说明了Symbol和内存文件的意义:
    http://blog.csdn.net/Donjuan/archive/2008/12/05/3454597.aspx

     

    忘记说了,内存文件我没有加--就是把程序在物理内存所占用的内存中的所有数据保存一个文件当中,然后调试器可以通过读取这个内存文件来重现当时进程的环境。这也就是为什么这种调试叫做验尸调试,Smile

    2008年12月10日 11:30