2009年4月19日 星期日

在HTA裡listen COM物件的event

找了很久在HTA裡listen COM物件的event 根據再網路上找到的資料 應該只有一個方法
就是利用< object> tag 語法如下:
< object id="myobj" classid="clsid:......">
< /object>

< script language="vbscript" for=myobj event=event_in_myobj>
//your event handler code
< /script>

以這種方式就可以撰寫自己的event handler
但是 因為我想要去操作的是webbrowser control或是internetexplorer object
我成功的listen到了webbroswer control物件的event
但是一但這個webbrowser control物件navigate到某個url之後
因為cross-frame security restrictions的問題 (網址)
就無法再去操作這個物件

沒試過internetexplorer物件 但是我想應該也是一樣的情況
所以想要在HTA裡listen webbrowser物件或是internetexplorer物件的event
又要不斷的讓這個物件navigate到不同的url 應該是沒辦法吧
殘念..

2009年4月17日 星期五

在vbscript中使用winhttprequest物件的小事項

在vbscript中 使用winhttprequest物件時 如果用POST送出request的話 參數一定要大寫, 例如
httpobj.open "POST", "url", false
如果用
httpobj.open "post", "url", false
server是接不到post過去的參數的
而且在send之前不要忘了加上setrequestheader "Content-Type", "application/x-www-form-urlencoded"這一行
不然server也是接不到參數
另外 如果用winhttprequest物件發出request到某個server去 而這個server會設定cookie
則接下來再發出request到同樣的server winhttprequest物件會自動幫你在header裡加上server設定的cookie
(如果沒有重新create出一個winhttprequest物件來用的話)
就像瀏覽器幫你做的事情一樣

一開始我只以為winhttprequest物件只是可以單純用來發出http request而已
沒想到他還這麼貼心的可以自動加cookie上去
真是有趣的發現

2009年4月16日 星期四

Temporary Internet Files

MS IE瀏覽器的Temporary Internet Files資料夾是一個很特別的資料夾
而且 它也許不是一個真正的資料夾
我在vbscript中去存取這個資料夾 發生了一些奇特的現象
例如我找不到它實際的路徑 即使用COM的shell物件拿到Temporary Internet Files的物件
也不能將檔案寫入這個資料夾 也不能用parsename method去拿這個資料夾裡面的檔案
同樣式special folder的desktop資料夾就不會這樣
這讓人還蠻想要去了解它到底是怎樣運作的 能知道怎麼使用Temporary Internet Files的
應該只有IE吧

此外 用filesystemobject物件去拿到的folder物件
以及用com shell物件的namespace拿到的folder物件
是不一樣的東西 雖然都叫做folder物件 但卻有不同的property和method
一開始讓我混淆了一下

HTA與vbscript

MS的vbscript可以在不同的host環境中執行 一般我們寫.vbs副檔名的檔案
通常是在wscript.exe或是cscript.exe這兩個環境中執行
在wscript.exe中執行時 就會有vbscript programmer都很熟悉的Wscript物件可以使用

但是這在HTA中是不行的 因為.hta檔案是在mshta.exe環境中執行
在這個環境中並沒有Wscript可以使用
就是因為這個原因 讓我在最近寫一個HTA文件時遭遇了很大的挫折

要解釋這件事情 得先說說createobject以及wscript.createobject這兩個函式
在vbscript中 這兩個函式可以create出一個COM物件讓programmer使用
但是這兩個函式其實是 不 一 樣 的
作為vbscript內建的createobject function 有兩個參數
第二個參數可以指定你要把這個物件create在哪台電腦上 也就是說可以遠端電腦裡create一個物件
例如 set obj=createobject("someobject", "remote_host_name")
這樣會在remote_host_name這台電腦裡創出一個物件來使用

而作為wscript物件的createobject method 也有兩個參數
第二個參數是作為programmer自己撰寫的event handler的prefix
例如 set obj=wscipt.createobject("internetexplorer.application", "ie_")
則接下來就可以用
sub ie_beforenavigate()
//some code
end sub
去listen internetexplorer物件的beforenavigate event了

這真是十分的好用 但是很可惜的是在HTA裡並沒有Wscript物件
因此也就沒有wcript.createobject可以用了

我想在HTA裡面 也可以用自己的event handler去listen某個COM物件的event
不過至今還沒有找到方法

不過 雖然不在wscript.exe裡面就沒有wscript物件可以用
並不表示以wscript為prefix的物件也不能用
例如wscript.shell物件 這個物件和wscript物件是分開的
即使環境不是在wscript.exe中 也可以用createobject("wscript.shell")去建立這個物件
這有時候是一件很容易讓人困惑的事情

2009年4月11日 星期六

microsoft vbscript與標準javascript的某些不同

microsoft發展的vbscript與標準的javascript有一些不同之處先說用vbscript來操作DOM物件在標準的javascript中要取得一個DOM物件 可以用getElementById、getElementsByName、getElementsByTagName這三個document物件的method不過在vbscript中要取得一個DOM物件就不需要那麼麻煩了只要一個DOM物件有設定id屬性或是name屬性 直接就可以操作他 如以下範例
< html >
< head >
< script language="VBScript">
sub myfunc()
myinput.value="kerker"
end sub
< /script >
< /head >
< body >
< input type="text" name="myinput" >
< input type="button" onclick="myfunc" value="test" >
< /body >
< /html >
在一個網頁裡的DOM物件可以有相同的name屬性值想操作這些物件 標準的作法是用document.getElementByName()來返回一個array去操作但在vbscript中 那個name屬性值就已經是一個array可以讓你操作物件 如下範例
< html >
< head >
< script language="VBScript" >
sub myfunc()
myinput(0).value="kerker"
myinput(1).value="kerker"
end sub
< /script >
< /head >
< body >
< input type="text" name="myinput" >
< input type="text" name="myinput" >
< input type="button" onclick="myfunc" >
< /bdoy >
< /html >
雖然vbscript這麼方便 但是也可以用getElementById來返回DOM物件不過這個method不只會搜尋DOM物件的id屬性 也會搜尋name屬性 若是有同樣name屬性值的DOM物件它只會返回第一個搜尋到DOM物件這在firefox是不會發生的 也許是IE不夠支援標準所致

其他vbscript較與眾不同的地方是 呼叫sub程序時不可以加括號 除非使用call去呼叫sub程序而呼叫function時括號則可加可不加 但是如果要使用function回傳值時則一定要加括號也因為sub不用加括號的關係 所以可以有onclick="myfunc"這種寫法標準的javascript是不行這樣寫的 一定要onclick="myfunc()"才行

2009年4月2日 星期四

vbscript download binary

之前碰到學長想要在windows上寫個程式可以有類似wget的功能
想到的方法是用vbscript去呼叫windows版本的wget
後來上網查了資料 才發現原來vbscript自己就可以做下載檔案的功能
只要用WinHttp.WinHttpRequest.5.1物件發出http request到伺服器
再用adodb.stream物件去接伺服器回傳的檔案就好了 只是似乎有檔案大小的限制
只能下載500MB之內的檔案 我猜這是因為他的作法是先將接到的row data放在heap段
再一次寫到disk中 所以檔案太大時記憶體就爆了

我越來越覺得vbscript很好很強大 尤其是它可以呼叫COM物件來做事
一直很懷疑vbscript是不是只有msgbox inputbox這種陽春的GUI元件可以用
結果當然不是
希望有時間可以研究用vbscript寫出視窗程式 一定會非常有趣