直到今天。才知道。原理可以在VS里面调JS。我晕。
1.在开始部署应用程序时,应该在IDE内部将构建类型设置为"Release"。该设置告诉编译器,以Release模式来构建Silverlight程序集。
对Release模式所作的设置真正起什么作用,取决于相应的编译器。例如,C#编译器可能会执行与VB.NET编译器不同的编译动作。
通过设置此选项,您设置了一个意图标志:告诉编译器希望生成哪种类型的构建。
如果编译器看到已经设置了Release的类型,
它就知道可以自由地优化它所生成的MSIL (Microsoft Intermediate Language)代码,而不需要让代码仍然保持某种比较适合人类阅读的格式。
虽然经常可以注意到,Release程序集的大小要比Debug程序集要小(虽然优化不只是关系到程序集大小),但是此优化过程中实际发生了什么,实在没有必要在这里讨论。
2.这些构建类型之间的另一个区别就是所生成的符号文件(调试文件)。符号文件是扩展名为.pdb的文件(程序数据库),而且所构建的每个程序集都有一个匹配的.pdb文件。
在对应用程序进行故障排查时,符号文件将被传递给调试器。该文件为所构建的程序集和源代码之间提供了联系的线索。
即使在Release构建中,虽然程序集中与源代码有关的信息很少,但构建中也将生成符号文件。被忽略的信息包括源代码行号、路径等。
在调试时符号文件用处很大,但是在托管的环境中它们的地位有些降低,因为现在可以使用反射来找到某些信息,这些信息在非托管的应用程序中通常是无法访问的。
3.在.NET中,描述类、方法和类型(等)的元数据存储在它们所描述的程序集内部。由于元数据和元数据所描述的实际结构保存在一起,因此可以确定它们是同步的。
.NET 框架提供了相应的方法以在运行时查询这些信息,该过程被称为.NET反射。
这个强大的功能使得可以获取那些通常(在非托管环境中)只能在运行时通过使用符号文件才能获得的信息。
正如前面所描述的,在托管的环境中,通过检索元数据没有存储的信息,例如代码行号和路径,符号仍然维护了某些值。
4.在使用符号文件时有几条规则要遵守: 必须将符号文件生成为构建的一部分,以便在后面阶段依靠特定构建进行调试。 即使代码没有改变并且重新构建,仍然应该生成新的符号,因为编译器优化将导致符号与代码的不同步。 不要将调试符号分发给第三方--只分发发布符号。这一点是出于安全考虑,因为分发调试符号可能会暴露没必要让公众了解的信息。
5.符号文件最有用的应用场景之一,是远程用户访问应用程序并发现应用程序中某些方面不起作用。让远程用户在应用程序出现故障点给应用程序内存拍个快照,并让他将此快照发给您,有时候是非常有用的。
此快照被称为内存转储,而符号文件允许在故障点深入查看应用程序。
6.由于Silverlight驻留在浏览器中,所以浏览器也需要符号。微软将"发布的"符号置于公共服务器上,因此需要进入此路径以获取这些符号。 在开发应用程序时,所有手头上相关的调试环境都应该具有Visual Studio的形式。 很多情况下,可能在Web应用程序内部编写客户端脚本以单独运行或补充Silverlight应用程序的功能。
使用Silverlight中的HTML"桥",托管代码可以与浏览器的HTML文档对象模型以及任何JavaScript内容进行通信。
这就意味着,有时候可能需要把一些脚本调试作为故障排查过程的一部分。
在此情况下,Visual Studio环境是一个很好的工具,它可以提供相应的帮助,
7.
但是有几点要注意。首先,不能在同一调试过程中调试托管代码和脚本。(即XAML。cs 和JAVASCRIPT)
这就是说,如果在XAML的隐藏代码中设置一个断点,并且已经打开了Silverlight调试,那么断点将发挥相应的作用。
然而,如果在脚本中也设置了断点,那么在"Silverlight"调试打开时,脚本中的断点将不能起作用。
8.以Internet Explorer为例,应该按照以下步骤来保证能够(让客户端脚本中的断点---禁用Silverlight后台调试。只调试JS)发挥作用:
(1) 在承载Silverlight控件的Web应用程序中,进入Project Properties(项目--属性)窗口并浏览Web选项卡。在Debuggers(调试)部分下面,确认Silverlight框没有被选中,如图15-3所示。
(点击查看大图)图15-3 (2) 下一步是确认浏览器已配置为允许脚本调试。在Internet Explorer情况下,启动浏览器并打开Tools(工具)选项卡,然后进入"Internet Options"(Internet 选项)对话框。
在Advanced(高级--浏览)选项卡上,确认"Disable script debugging (Internet Explorer)(禁用脚本调试)"和"Disable script debugging (Other)")(禁用脚本调试)"复选框未被选中,
如图15-4所示。
(点击查看大图)图15-4 (3) 最后一步,就像对其他任何代码所作的一样,只需在脚本中设置一个断点,并执行应用程序就可以。
这将提供功能丰富调试环境的所有好处,例如可以观察调用堆栈以及查看局部变量的值。
图15-5说明了对于一个简单函数来说该环境的大致情况。 (点击查看大图)图15-5 需要知道的环境问题是应用程序的承载Web服务器。默认情况下,Visual Studio将在Cassini Web服务器中执行Silverlight应用程序。
但是,有时您可能会在整个部署过程中移动应用程序,将应用程序放到一个UAT或Staging环境中。
在这些环境中,将使用大型的Web服务器(例如IIS、Apache)。应该确保Web服务器已经配置了正确的MIME类型以支持Silverlight应用服务。简而言之,
需要在Web服务器中添加一个如下所示的MIME类型映射:File Extension: .xap、MIME Type: application/x-silverlight-app。
Cassini是Visual Studio中承载Web项目的本地Web服务器名称。
该服务器使得在开发时可以不用配置应用程序即可放置在像IIS或者Apache之类比较复杂的服务器环境中。正在使用Cassini作为Web服务器的一个可靠标志是,系统托盘中有一个小图标,该图标的名称为"ASP.NET Development Server"。
也不是总会在调试环境下遇到问题,而且有时候可能足够幸运可以重现此问题,而不需要通过按下[F5]键来执行应用程序,在此情况下,将Visual Studio绑定到现有的浏览器进程中可能就更为方便。
要将Visual Studio作为调试器绑定到另一进程,需要选中Debug工具选项菜单,然后选择"Attach to Process"。
这将给出运行在该系统上的进程列表。有可能您是在自己的用户账户语境中执行浏览器,但是如果不是这样,必须确保选中了"Show processes from all users"和"Show processes from all sessions"选项,以便能发现需要调试的进程。
此节讨论了开始调试应用程序时需要采取的一些步骤。如果在Visual Studio中调试过其他类型的应用程序,将对此比较熟悉。下面要讨论的几个工具可能就不那么熟悉了。这些工具不是微软公司的产品,但是是开发的基本工具,对Web开发而言尤其如此。
解决Silverlight无法调试的问题
在Silverlight开发过程中,经常时不时的会碰到Silverlight无法调试的问题。我就遇到下面几种情况:
1. Web Application+Silverlight,F5进入调试状态之后无法跟进Silverlight程序中下的断点
2. 项目中有两个Silverlight工程,其中一个Silverlight程序中有一个鼠标点击事件会将当前页面导航到另外一个Silverlight程序的承载页面。
第一个Silverlight程序断点正常,但是第二个Silverlight程序中的断点不能自动停下来
3. 无论是在TestPage模式下调试还是在Web工程上调试,只要打开了Silverlight调试开关,
那么启动的时候会提示“Unable to start debugging. Cannot locate Microsoft Internet Explorer”。如果你是直接Ctrl+F5运行,有时候也会出现一样的问题。
单个Silverlight工程无法调试
对于第一个问题,请检查如下设置是否正确: 1. 确认启用了Silverlight调试。双击Asp.Net工程中的属性文件夹打开属性设置页,找到Web一栏,在此页卡的最下面有几个调试选项,如下图所示:
确认最后一项“Silverlight”之前的勾是勾上的。 2. 确保浏览器访问的Xap包是最新的。检查IE是否已经清除了缓存,或者ClientBin中的Xap因为某些原因没能更新(如因配置管理导致无法覆盖)
3. 检查Asp.Net工程是否绑定了Silverlight应用。可以通过asp.net工程的属性面板中的Silverlight Application页卡查看是否绑定成功。如下:
4. 检查Silverlight工程的StartupObject是否设置正确。有时候我们对工程的命名空间进行重命名,会导致Silverlight应用程序的入口对象失效,从而导致无法启动等情况。
2.IE8下无法同时调试多个Silverlight工程?!
IE8和以往的IE不大一样,它的多标签是采用多进程的方式来实现的。整个窗口是一个框架进程,
每个Tab标签页是一个独立的子进程(实际上,IE8会根据内存动态控制Tab进程的数目,因此多个标签页可能会共存于同一个进程之中)。
当你尝试在多个标签页中打开不同的Silverlight应用程序时,例如从SilverlightApplication1中打开新页面到SilverlightApplication2页面,这个时候你会发现,SilverlightApplication2应用程序无法调试。
这是因为,Visual Studio除了启动窗口进程之外,不会自动帮我们Attach其他的包含Silverlight应用程序的进程,
如果我们需要在多个标签页(或者多个窗口)中同时调试不同的Silverlight应用程序,那么我们必须自己手动Attach这些进程。
举个简单的例子,我有两个Silverlight工程,其中SilverlightApplication1中包含链接指向SilverlightApplication2页面,点击链接会在新标签页中打开SilverlightApplication2的承载页面。
为了Attach相应的进程,首先我们需要找到SilverlightApplication2承载页面对应的进程。打开ProcessExplorer,我们可以看到三个进程。
其中的ID为4528的是父进程,也就是框架进程,用于管理不同的标签进程之间的通信等事务。5160和5248分别对应着两个标签页进程。至于哪个对应哪个我们在这里无法根据进程号确定。
我们再打开Visual Studio中的Attach窗口(菜单=>Debug=>Attach to process…)
这里列出了所有系统可用的进程清单,我们可以看到三个IE进程,其中一个是灰色的,这表示了这个进程已经被Attach到Visual Studio的调试器上了。
排除了框架进程4258外,就剩下5248这个进程了,这个进程就是我们要找的SilverlightApplication2对应的承载页面的进程了。选中之后Attach到调试器上,我们发现,SilverlightApplication2中的断点还是显示为空心红圈,依然无法调试。 这是因为我们指定的进程代码类型不正确。我们注意到,上图中最上面有一个Attach to,后面显示的是Automatic,这个代表着Visual Studio的调试器会自动帮我们选择进程的调试类型,例如是托管代码调试,还是脚本调试,等等。我们选中5248这个进程,发现Visual Studio给我们选择的方式是脚本调试。
在Visual Studio中,脚本调试和Silverlight调试是不能共存的,这也就是为什么有时候你按下F5的时候,Visual Studio会提示你,
调试Silverlight程序会暂时关闭脚本调试的功能。
因此在脚本调试下,我们无法跟进Silverlight应用程序的断点。
这里额外说一点,IE8高级选项中的禁用脚本调试设置对Visual Studio一点影响都没有
,因为Visual Studio 2008在调试器启动的时候会自动启用脚本调试(可以通过注册表禁用此特性),
除非在Web Application属性中打开了Silverlight调试。
回到刚才的问题,由于Visual Studio帮我们自动选择的调试类型有误,导致我们无法调试SilverlightApplication2,因此我们需要手动指定Attach类型。点击Attach to后侧的select按钮。
在弹出的选择代码类型窗口中勾选上Silverlight。确定之后再次Attach,我们发现,这一次,断点真的起作用了。 当然,如果这种方式比较麻烦的话,我们也可以通过改变IE8的Tab进程创建方式来让不同标签页共存于一个进程中。
在注册表HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main下面有一个TabProcGrowth键值(DWORD类型),
当其设置为0时, IE框架和Tab工作在一个进程里面,Tab采用线程的方式创建,同时IE的保护模式(Protect Mode)会关闭。
TabProcGrowth=1时IE框架和Tab工作在不同的进程里面。TabProcGrowth>1时,此值将决定IE8最多创建的Tab进程数目。
如果TabProcGrowth 不存在,则会根据可用的物理内存数量决定Tab进程的数量。
调试时无法打开IE窗口的问题
这个问题是我最近才遇到的,我也不知道为什么突然之间,我的Silverlight工程按下F5的时候无法调试,
弹出下面这个对话框:Unable to start debugging. Cannot locate Microsoft Internet Explorer.
如果直接运行,那么能够打开,但是打开之后Visual Studio还是会弹出一样的错误。
这个问题折腾了我半天,我尝试了重启电脑,重装Silverlight Tools,新建干净的测试工程,修改系统和
Visual Studio的默认浏览器(注意,系统和Visual Studio的默认浏览器是独立设置的)均以失败告终。
Google了很久,Silverlight官方论坛上倒是有不少帖子和这个相关的,但我细细看了之后发现没有一个回帖能够解决我的问题的。
有个发帖的家伙问题是解决了,但是不把怎么解决的说一下就跑了,强烈bs一下这种人!
话说回来,我最后是怎么解决这个问题的呢,
是用了Process Monitor这个小工具(微软Sysinternal荣誉出品!)。
之前有一次asp.net网站的GlobalError里头出现了一个“文件不存在”的HTTPException,查了半天没查出来,
后来使用这个工具监视了一下WebDevServ.exe进程之后发现该进程尝试去访问某个不存在的文件。
Process Monitor,可以监控当前系统中所有进程的活动,包括对文件系统的操作,读写注册表,网络访问以及线程活动等等,非常实用的调试维护工具。
我打开这个工具,选择监视进程为devenv.exe。在Visual Studio中F5开始调试,立即弹出出错对话框,OK,把PM暂停一下,否则条目太多了。
但是事件条目还是太多了,所以我把Result为SUCCESS的条目过滤掉,因为我们只关注那些失败的条目。
然后对日志条目进行细致的排查,终于发现了问题根源:
原来Visual Studio在调试或者运行的时候会去读取注册表中的H
KLM\Software\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe项,
然后读取不到,因而才报那个错误。难怪提示Cannot locate Microsoft internet explorer呢。
我打开regedit注册表编辑器,找到这个路径,然后把缺失的项加上去,重新回到Visual Studio中F5,终于可以了,内牛满面~
希望我的解决方法能够给你一些启发,以后遇到类似莫名其妙的问题,可以想到使用PM这个工具去排查问题。 update: 更新了新的症状(F5调试的时候弹出cannot locate microsoft internet explorer的对话框)的解决办法。