2007年10月25日 星期四

簡單快速取出 chm 中的圖片

MSN SpaceGoogle DocGoogle Blog
Chui-Wen Chiu
2007.10.26
關鍵字:chm

測試環境
1. Windows XP SP2
2. HTML Help Control 4.74.9273

不知道你有沒有常看 chm 電子書,有時裡面有些不錯圖片想要取出來,可是 Microsoft HTML Help 程式卻沒有提供按右鍵另存功能。網路有提供 chm 轉檔工具,可是有時只需要裡面的一兩張圖片,實在沒有必要使用這些工具。這裡提供一個簡單的方式,首先打開你的 chm 並找出你想要另存的圖片,按下滑鼠右鍵點選"屬性",如下:


然後在"內容"視窗中,複製網址,如下:

然後打開檔案總管,將網址貼在網址列,然後按右鍵另存即可,是不是很簡單呢 ^^

VS2008 對 Javascript 的支援


MSN SpaceGoogle DocGoogle Blog

Chui-Wen Chiu
2007.10.24
關鍵字:debug, visual studio, javascript, intellisense

前言

今天參加高雄場次的微軟研討會,第一場由曹祖聖主講 VS2008 對 Javascript 的支援,內容提到一些不錯和有待改進的部份整理成本篇文章,由於目前 VS2008 還處於 Beta2 版本,所以未來可能還會進行修改或強化。

Javascript Intellisense

VS2008 採用型別推測(type inference)方式來支援 Javascript 的 Intellisense,透過此一方式可以讓開發人員更容易找到變數/物件的成員,這個方法的缺點是如果無法正常推測初結果,則必須手動輸入,且此一方式需要花額外時間進行推測,所以,Intenllisense 需要一段時間才能夠呈現。除此之外,VS2008 也支援 HTML 中部引入外部的 js 檔,即使外部檔案位在其他網站,也仍然能夠使用(但是需要花一些時間)。如下圖:

圖1、Javascript Intellisense[1]

如果 HTML 中引入多個 js 檔案,為了 js 檔可以顯示其他 js 的 intellisense,必須在 js 檔的最開頭加上下面的相依宣告:
/// <reference
/// path="~/scripts/mylib.js"
/// assembly="System.Web"
/// name="ScriptResourceName.js"
/// />
其中 path 屬性用來定義引用的 js 檔案路徑,如果你使用 .NET 的組件,可透過 assembly 和 name 屬性指定 .NET 組件。如果忽略 assembly 屬性,預設為 System.Web.Extensions。

為了讓 Intellisense 支援說明,必須在定義的函數、物件或欄位中定義 XML 說明註解(註:註解說明位置和 C# 不同)。如:

function getWelcomeMessage(name){
/// <summary>
/// 這個函數是用來根據使用者姓名,自動產生歡迎文字
/// </summary>
/// <param name="name">使用者姓名</name>
/// <return>string</return>

return "歡迎 " + name;
}

執行結果:

圖2、函數說明提示[1]


圖3、參數說明提示[1]
以下是常用的 XML 註解:
函數參數

<param
name="參數名稱"
mayBeNull="true|false"
optional="true|false"
type="參數型別"
parameterArray="true|false"
integer="true|false"
domElement="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false">

參數說明文字
</param>

在定義數值說明時,可以使用 type, integer, domElement 和 mayBeNull。由於 JavaScript 沒有 integer 型別,只有 number 型別,所以可以將 type 設成 Number,integer 設成 true,來表示整數型別。可省略參數用 optional ="true"。參數如果可以重覆出現可將 parameterArray 設為 "true"。

陣列說明

="_x0000_s1026">

因為 JavaScript 並沒有類似 int[] 這樣的陣列宣告,因此在定義說明時,可以使用 elementType, elementInteger, elementDomElement 和 elementMayBeNull 來定義陣列的說明。

函數回傳值
<returns
type="傳回值型別"
integer="true|false"
domElement="true|false"
mayBeNull="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false">
傳回值說明文字
</returns>
元素和函數參數相同不贅述。

屬性
<value
type="數值型別"
integer="true|false"
domElement="true|false"
mayBeNull="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false"
locid="descriptionID">

屬性說明文字
</value>
元素和函數參數相同不贅述。

欄位
<field
name="欄位名稱"
type="欄位型別"
integer="true|false"
domElement="true|false"
mayBeNull="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false"
locid="descriptionID">欄位說明文字
</field>
元素和函數參數相同不贅述。

AJAX, ASP.NET, Web Service 對 Javascript Intellisense 支援

雖然 ASP.NET 也可直接印入 js 檔,但官方建議透過 ScriptManager 引用,引入之後即可獲得相同支援。如下:

<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/MyLib.js" />
<asp:ScriptReference Path="~/jQuery.js" />
</Scripts>
</asp:ScriptManager>


如果想在引入 Web Services 中的 js,首先,在 Web Service 中必須加入 System.Web.Script.Services.ScriptService Attribute,如下:

[System.Web.Script.Services.ScriptServie()]
[WebService(Namespace="http://tempuri.org")]
public class WebService: System.Web.Services.WebService{
[WebMethod()]
public String Hello(){
return "Hello World";
}
}


接著在 ASP.NET 的 ScriptManager 中加入 Services 即可獲得支援,如下:


<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ScriptReference Path="~/MyLib.asmx" />
</Services>
</asp:ScriptManager>

在 AJAX 上,AJAX Client Behavior, AJAX Client Control 和 AJAX Client Library 使用上也支援 Javascript Intenllisense。


圖4、AJAX 的支援[1]

Javascript 偵錯

VS2008 要對 IE 進行偵錯,必須在 IE 上關閉"停用程式碼除錯"選項(VS2005 或 Visual Script Debugger 相同)。如未關閉可能出現如下提示訊息:

圖5、除錯關閉提示[1]

關閉方式如下圖所示:

圖6、關閉除錯停用選項[1]
語法錯誤提示
當你透過 Visual Studio 編輯 Javascript 時,會即時檢查語法的正確性,如果你用 VS2005 編輯 C# 就會相當熟悉這個通能,他會在語法錯誤之處會標示提醒符號,如下圖:
圖7、語法檢查[1]
中斷點

可在程式中設定中斷點,如同 C# 程式一般,像是條件式中斷、hit count 中斷等,也可在中斷時,透過 Call Stack, 區域視窗, 即時監看視窗, Visualizer 等檢查相關的參數狀態,如下圖:

圖8、中斷點[1]

圖9、各種除錯視窗[1]

圖10、Visualizer [1]

偵測外部網頁

這個功能我覺得是這個主題中相當重要的一部分,這個主要用來偵錯已經在運作中的網頁 Javascript 功能,雖然 VS2005 也有類似的功能,但不像 VS2008 這麼強大,他可將指定的網址相關檔案下載下來,並在 VS 中呈現目前的內容,並且會依據實際情況變更。所以,如果你要研究某個網站的 Javascript 如何撰寫,只要透過這個方式將網頁資料透過 VS 偵測,並利用剛剛說的中斷點和其他除錯視窗,就是一個強大的 Hack 工具。唯一美中不足的是無法動態修改程式碼。希望未來能夠提供此功能。

由於沒有 VS2008 可抓圖展示,就以投影片的內容整理如下:

啟動外部偵錯
1. 使用 IE 瀏覽網頁
2. 使用 Visual Studio 2008 將 IE 的行程 (iexplorer.exe) 附加到偵錯模式下
圖11、VS 附加到指定 IE 行程 [1]
3. VS 會下載相關檔案到 Script Document

圖12、Script document [1]

4. 開啓檔案
4. 設定中斷點
5. 進行偵錯
圖13、Script document [1]

常見問題

1. 是否支援物件的 Intellisense?


2. 是否支援物件的程式碼註解格式?


3. 是否支援 Reference To 到函數或物件的功能?
否,尚未支援

4. VS2008 的 Javascript 註解格式是否可以產生文件?
目前尚未支援

5. 是否可關閉 Intellisense 功能?
否,沒有提供選項設定。

6. 可偵錯 Silverlight 嗎?


7. 現有的 javaDoc 註解格式是否支援 Intellisense 或提供轉換工具?
否,可透過 Open Source 尋找看看

8. 可支援 Firefox 上的偵錯嗎?

參考資料

[1] 曹祖聖, "深入 Visual Studio 2008 Javascript 偵錯技術投影片 "

[2] "Debug JavaScript in JSP or PHP Pages with Visual Studio 2008"




VS2008 對 Javascript 的支援


MSN SpaceGoogle DocGoogle Blog

Chui-Wen Chiu
2007.10.24
關鍵字:debug, visual studio, javascript, intellisense

前言

今天參加高雄場次的微軟研討會,第一場由曹祖聖主講 VS2008 對 Javascript 的支援,內容提到一些不錯和有待改進的部份整理成本篇文章,由於目前 VS2008 還處於 Beta2 版本,所以未來可能還會進行修改或強化。

Javascript Intellisense

VS2008 採用型別推測(type inference)方式來支援 Javascript 的 Intellisense,透過此一方式可以讓開發人員更容易找到變數/物件的成員,這個方法的缺點是如果無法正常推測初結果,則必須手動輸入,且此一方式需要花額外時間進行推測,所以,Intenllisense 需要一段時間才能夠呈現。除此之外,VS2008 也支援 HTML 中部引入外部的 js 檔,即使外部檔案位在其他網站,也仍然能夠使用(但是需要花一些時間)。如下圖:

圖1、Javascript Intellisense[1]

如果 HTML 中引入多個 js 檔案,為了 js 檔可以顯示其他 js 的 intellisense,必須在 js 檔的最開頭加上下面的相依宣告:
/// <reference
/// path="~/scripts/mylib.js"
/// assembly="System.Web"
/// name="ScriptResourceName.js"
/// />
其中 path 屬性用來定義引用的 js 檔案路徑,如果你使用 .NET 的組件,可透過 assembly 和 name 屬性指定 .NET 組件。如果忽略 assembly 屬性,預設為 System.Web.Extensions。

為了讓 Intellisense 支援說明,必須在定義的函數、物件或欄位中定義 XML 說明註解(註:註解說明位置和 C# 不同)。如:

function getWelcomeMessage(name){
/// <summary>
/// 這個函數是用來根據使用者姓名,自動產生歡迎文字
/// </summary>
/// <param name="name">使用者姓名</name>
/// <return>string</return>

return "歡迎 " + name;
}

執行結果:

圖2、函數說明提示[1]


圖3、參數說明提示[1]
以下是常用的 XML 註解:
函數參數

<param
name="參數名稱"
mayBeNull="true|false"
optional="true|false"
type="參數型別"
parameterArray="true|false"
integer="true|false"
domElement="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false">

參數說明文字
</param>

在定義數值說明時,可以使用 type, integer, domElement 和 mayBeNull。由於 JavaScript 沒有 integer 型別,只有 number 型別,所以可以將 type 設成 Number,integer 設成 true,來表示整數型別。可省略參數用 optional ="true"。參數如果可以重覆出現可將 parameterArray 設為 "true"。

陣列說明

="_x0000_s1026">

因為 JavaScript 並沒有類似 int[] 這樣的陣列宣告,因此在定義說明時,可以使用 elementType, elementInteger, elementDomElement 和 elementMayBeNull 來定義陣列的說明。

函數回傳值
<returns
type="傳回值型別"
integer="true|false"
domElement="true|false"
mayBeNull="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false">
傳回值說明文字
</returns>
元素和函數參數相同不贅述。

屬性
<value
type="數值型別"
integer="true|false"
domElement="true|false"
mayBeNull="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false"
locid="descriptionID">

屬性說明文字
</value>
元素和函數參數相同不贅述。

欄位
<field
name="欄位名稱"
type="欄位型別"
integer="true|false"
domElement="true|false"
mayBeNull="true|false"

elementType="陣列元素型別"
elementInteger="true|false"
elementDomElement="true|false"
elementMayBeNull="true|false"
locid="descriptionID">欄位說明文字
</field>
元素和函數參數相同不贅述。

AJAX, ASP.NET, Web Service 對 Javascript Intellisense 支援

雖然 ASP.NET 也可直接印入 js 檔,但官方建議透過 ScriptManager 引用,引入之後即可獲得相同支援。如下:

<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/MyLib.js" />
<asp:ScriptReference Path="~/jQuery.js" />
</Scripts>
</asp:ScriptManager>


如果想在引入 Web Services 中的 js,首先,在 Web Service 中必須加入 System.Web.Script.Services.ScriptService Attribute,如下:

[System.Web.Script.Services.ScriptServie()]
[WebService(Namespace="http://tempuri.org")]
public class WebService: System.Web.Services.WebService{
[WebMethod()]
public String Hello(){
return "Hello World";
}
}


接著在 ASP.NET 的 ScriptManager 中加入 Services 即可獲得支援,如下:


<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ScriptReference Path="~/MyLib.asmx" />
</Services>
</asp:ScriptManager>

在 AJAX 上,AJAX Client Behavior, AJAX Client Control 和 AJAX Client Library 使用上也支援 Javascript Intenllisense。


圖4、AJAX 的支援[1]

Javascript 偵錯

VS2008 要對 IE 進行偵錯,必須在 IE 上關閉"停用程式碼除錯"選項(VS2005 或 Visual Script Debugger 相同)。如未關閉可能出現如下提示訊息:

圖5、除錯關閉提示[1]

關閉方式如下圖所示:

圖6、關閉除錯停用選項[1]
語法錯誤提示
當你透過 Visual Studio 編輯 Javascript 時,會即時檢查語法的正確性,如果你用 VS2005 編輯 C# 就會相當熟悉這個通能,他會在語法錯誤之處會標示提醒符號,如下圖:
圖7、語法檢查[1]
中斷點

可在程式中設定中斷點,如同 C# 程式一般,像是條件式中斷、hit count 中斷等,也可在中斷時,透過 Call Stack, 區域視窗, 即時監看視窗, Visualizer 等檢查相關的參數狀態,如下圖:

圖8、中斷點[1]

圖9、各種除錯視窗[1]

圖10、Visualizer [1]

偵測外部網頁

這個功能我覺得是這個主題中相當重要的一部分,這個主要用來偵錯已經在運作中的網頁 Javascript 功能,雖然 VS2005 也有類似的功能,但不像 VS2008 這麼強大,他可將指定的網址相關檔案下載下來,並在 VS 中呈現目前的內容,並且會依據實際情況變更。所以,如果你要研究某個網站的 Javascript 如何撰寫,只要透過這個方式將網頁資料透過 VS 偵測,並利用剛剛說的中斷點和其他除錯視窗,就是一個強大的 Hack 工具。唯一美中不足的是無法動態修改程式碼。希望未來能夠提供此功能。

由於沒有 VS2008 可抓圖展示,就以投影片的內容整理如下:

啟動外部偵錯
1. 使用 IE 瀏覽網頁
2. 使用 Visual Studio 2008 將 IE 的行程 (iexplorer.exe) 附加到偵錯模式下
圖11、VS 附加到指定 IE 行程 [1]
3. VS 會下載相關檔案到 Script Document

圖12、Script document [1]

4. 開啓檔案
4. 設定中斷點
5. 進行偵錯
圖12、Script document [1]

常見問題

1. 是否支援物件的 Intellisense?


2. 是否支援物件的程式碼註解格式?


3. 是否支援 Reference To 到函數或物件的功能?
否,尚未支援

4. VS2008 的 Javascript 註解格式是否可以產生文件?
目前尚未支援

5. 是否可關閉 Intellisense 功能?
否,沒有提供選項設定。

6. 可偵錯 Silverlight 嗎?


7. 現有的 javaDoc 註解格式是否支援 Intellisense 或提供轉換工具?
否,可透過 Open Source 尋找看看

8. 可支援 Firefox 上的偵錯嗎?

參考資料

[1] 曹祖聖, "深入 Visual Studio 2008 Javascript 偵錯技術投影片 "

[2] "Debug JavaScript in JSP or PHP Pages with Visual Studio 2008"




2007年10月1日 星期一

Vista 的 Session 0 Isolation 問題

MSN SpaceGoogle DocGoogle Blog
Chui-Wen Chiu
2007.10.01

前言

由於我目前還相當排斥 Vista 也無開發環境,所以當初開發時並沒有把 Vista 列入考慮。可是當這個產品漸漸成型,也受到眾多主管的關注,偏偏他們都已經在使用 Vista 作業系統,所以測試發現無法在 Vista 上運作,這針是讓我頭痛的問題。一來我要先借到一台安裝 Vista 的機器,二來在 XP 上熟悉的工具在 Vista 上很多都不相容,尤有甚者 Vista 就直接重開機,最慘的是 Alcohol 120% 1.9.5.3105 在 Vista 上安裝重開機會沒有辦法進入作業系統,真是讓人傻眼,還好系統還原後就正常。總之,最後安裝了最基本的開發工具和除錯套件,由於發生問題的是印表機驅動程式,也就是 Print Processor 部份,這個的用途是當應用程式執行列印命令時,系統的 Print Spooler 服務會依據你選擇的印表機,載入對應的 Driver DLL,並依序喚起 OpenPrintProcessor, PrintDocumentOnPrintProcessor, ClosePrintProcessor 完成列印的工作,我的測試發現 OpenPrintProcessor 在 Vista 上就結束了,所以沒有辦法完成列印。

因為我的程式在列印過程會將資料導入一個 Window,在 OpenPrintProcessor 檢查該 Window Handle 是否存在,居然在 Vista 上的 FindWindow 抓不到該 Window,查了許多的資料後才知道,Vista 基於安全的理由,進行了 Session 0 Isolation,導致程式沒有辦法 FindWindow 和 SendMessage。

何謂 Session 0 Isolation?

在 Windows 2000/XP/2003 和更早期的 Windows 作業系統,所有 Service 都運作在第一個登入用戶的 Session。此 Session 稱為「Session 0」。一般的應用程式也運作在同一個 Session 如圖1 所示。如此程式可透過 Windows API 如: FindWindow, SendMessage 與視窗應用程式互動。
圖1、2000/XP/2003 上的 Session(摘自[7])


可是到了 Vista,基於「Session 0」中同時運作 Service 和視窗應用程式會產生安全風險,因為這些服務以提升的權限運行,因此會成為那些正在伺機提升自身權限級別的惡意代理的目標。因此 Vista 中透過 Session 0 Isolation 使 Service 和視窗應用程式進行隔離,使得 Service 和視窗應用程式沒有辦法透過視窗訊息進行互動,如圖2 所示。

圖2、Vista 上的 Session(摘自[7])

在 Windows Vista 中,只有 System Process 和 Service在「Session 0」運作。第一個使用者登入將到 Session 1,隨後的使用者將登入到後續的 Session (如:Session 2, Session 3, ...)。這表示著 Service 永遠不會與應用程式在相同的 Session 中進行溝通,因此可防止應用程式的攻擊。但是這樣的改變會造成透過 Service 運作的動程式受到影響,如:印表機驅動程式(使用 "Print Spooler" Service)。所以,簡單的說 Session 0 Isolation 機制,讓 Service 和應用程式分屬不同的 Session,避免 Service 遭受應用程式攻擊。

由於 Vista 上述 Session 機制改變,導致我的程式移植到 Vista 上無法正常運作。因為無法使用 SendMessage/PostMessage/PeekMessage 或其他視窗相關的 Windows API。所以,只能透過其他方式來繞過這個限制。官方建議的修改方式是改用 RPC 或命名的 Pipe 與視窗應用程式溝通。

可能解決方式

針對我的問題,因為我的需求很單純,只是透過 SendMessage 通知 Window 資料寫入完成。於是我將 FindWindow 和 SendMessage 用 Pipe 方式改寫,也就是在 Window 端建立一個接收訊息的 Pipe,Driver 端則在必要的時候透過 Pipe 傳送命令過來,如此可規避 Session 0 Isolation 對其他 Session 應用持事互動的遮蔽。

總結

雖然透過 Pipe 方式可以暫時解決問題,不過 Vista 上的 UAC 會使程式作受到些許限制,初期開發我是先關閉 UAC 解決這個問題,未來可能要再考慮 UAC 的情況。真希望 Jeffrey Richter 趕快出一本關於 Vista 底層運作的書,也許我對 Vista 上的開發會得心應手些~

參考資料

[1] 在 Windows Vista 中,嘗試傳送訊息至工作階段 0 的程式可能會停止回應
[2] Impact of Session 0 Isolation on Services and Drivers in Windows Vista
[3] Windows Vista Developer Story:应用程序兼容性集锦
[4] Security, services and the interactive desktop in Windows
[5] Interacting with Services
[6] Services in Windows Vista
[7] Application Compatibility - Session 0 Isolation








搜尋此網誌