[Silverlight]解决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應用程序的入口對象失效,從而導致無法啟動等情況。
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在調試或者運行的時候會去讀取注冊表中的HKLM\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的對話框)的解決辦法。
摘自:http://msdn.microsoft.com/zh-cn/ff686904.aspx
總結
以上是生活随笔為你收集整理的[Silverlight]解决Silverlight无法…的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java基础JDK的安装和环境变量的配置
- 下一篇: java学习(43):值参数传递