寫COM元件用於ASP/PHP等動態網頁
ASP、PHP等動態網頁語言的功能已很強大,但COM能使它如虎添翼。其實我們平時用的ADO、FSO、Jmail等也就是COM。藉助COM,WEB可以呼叫本地應用程式的幾乎所有功能來反饋給頁面。例如,查詢伺服器的各盤使用情況,CPU佔用率等,最後給出一個例子,用COM查詢IP對應的地埋位置。
開發COM的工具也就是開發EXE應用程式的工具,VB、VC、Delphi都可以。但VB具有天生的優勢,幾行程式碼就可以寫出COM來。VB中,COM又叫ActiveX DLL。下面借用一個很簡單的示例 ,判斷年份是否為閏年。
新建一個ActiveX DLL工程,將工程名命為CheckYear,自動生成的類名命為LeapYear。寫下如下程式碼:
Option Explicit
Public Function IsLeapYear(yr As Variant) As Boolean
If yr Mod 4 = 0 And yr Mod 100 <> 0 Then IsLeapYear = True Else IsLeapYear = False
End Function
咳,簡單得有點不適應。就這樣COM做好了,生成DLL即可。然後註冊它。在執行中輸入“regsvr32 H:\checkyear.dll”即可。如果你本機架有IIS或NetBox,可以在ASP網頁上呼叫它了。如果用於伺服器,那麼上面這件事則需要在伺服器上做。ASP呼叫程式碼如下:
COM在EXE應用開發工具中也可以呼叫。在寫複雜的COM時,可以用他們來檢測功能。COM註冊後,在VB中的“引用”列表中可以看到。例如下面是VB呼叫它的程式碼:<% Option Explicit Dim oCheckYear,s Dim Year, isleapYear Year=2004 Set oCheckYear=CreateObject("CheckYear.LeapYear") isleapyear=oCheckYear.IsLeapYear(Year) Set oCheckYear=Nothing %> <body> <% If isleapYear=True Then s="是閏年!" Else s="不是閏年!" %> <%=Year%>年<%=s%> </body>
Private Sub Command1_Click()
Dim c
Set c = CreateObject("CheckYear.LeapYear")
Dim d As Boolean
d = c.IsLeapYear(2004)
MsgBox d
End Sub
COM打開了一扇無限可能的門,下面就是看你發揮了。金蝶、用友等非常擅用此類方法。它們主要是把COM當成標準DLL用(因為VB開發標準DLL不方便啊),利用工作分配豚團隊合作。下面給出一個用COM查詢IP對應的地埋位置的例子。WebService想必大家用過,很多門戶或廠商以免費的WebService的方式提供天氣、股市等資訊。我們在程式中直接用URL就可以訪問它。這裡要說的是一個非公開的、非正式的“服務”,即IP138網站提供的IP資訊查詢頁面,http://iframe.ip138.com/ic.asp,它返回簡單的IP和所在地資訊,如“您的IP是:[17.89.9.11]
來自:廣東省深圳市 電信”。我的程式中就向它請求資訊查詢使用者所在地,這比自己查資料庫省事多了,而且它號稱它的地址永遠是最新的。可是好景不長,這個URL穩定地存在了N年,卻在最近失效了。不過,我們很快可以找到其他頁面。這個也可以用到COM中,之後,我們自己的頁面上只要呼叫COM中提供的方法就可以了。有人要問:這樣豈不總是得到伺服器的地址資訊?事實上,IP138同時也提供對指定IP的查詢
VB中新建ActiveX DLL工程,名為IP2City,建個類名為clsIP,方法名GetCityName,輸入引數是IP字串,輸出為城市名(地理位置)。程式碼如下:
Option Explicit
Public Function GetCityName(vIP As Variant) As String
Dim sUrl As String, sCode As String, sCity As String, c() As String, d() As String
sUrl = "http://ip138.com/ips138.asp?ip=" & vIP
sCode = GetURL(sUrl)
c = Split(sCode, "本站主資料:")
If UBound(c) >= 1 Then
sCity = c(1)
d = Split(sCity, "</li>")
sCity = d(0)
End If
If Len(sCity) > 20 Then sCity = Left(sCity, 20)
GetCityName = sCity
End Function
Public Function GetURL(URL) As String
On Error GoTo a0:
Dim i, j
j = 0
Dim XMLHTTP As Object
Set XMLHTTP = CreateObject("MSXML2.XMLHTTP")
If Not IsObject(XMLHTTP) Then
Set XMLHTTP = CreateObject("Microsoft.XMLHTTP")
If Not IsObject(XMLHTTP) Then Exit Function
End If
XMLHTTP.Open "GET", URL, True
XMLHTTP.setRequestHeader "If-Modified-Since", "0" '使用MSXML2.XMLHTTP和Microsoft.XMLHTTP方法時,這條指令相當於清除快取
XMLHTTP.send
i = Now()
Do 'While XMLHTTP.ReadyState <> 4
DoEvents
Loop Until XMLHTTP.ReadyState = 4 Or j = DateDiff("s", i, Now()) > 4
GetURL = StrConv(XMLHTTP.responseBody, vbUnicode)
Exit Function
a0:
End Function
編譯後,這個COM既可以用於EXE應用程式,也可以用於ASP/PHP等動態頁面。例如下面是ASP中呼叫的程式碼:
<%
'Option Explicit
Dim oIP,sFrom,sCityName
sFrom=request.ServerVariables("REMOTE_ADDR")
Set oIP=CreateObject("IP2City.clsIP")
sCityName=oIP.GetCityName(sFrom)
Set oIP=Nothing
%>
<body>
<center>您的IP是:[<%=sFrom%>] 來自:<%=sCityName%>
</body>
最後提一下COM註冊問題。我的開發機器是Win7 64位,開發、註冊到呼叫都很順利,然而拷到伺服器Win2003上之後ASP卻無法呼叫。顯示“沒有許可權 'Create Object'”錯誤。熱百度上幾乎千篇一律只有一個答案,在控制面板中如何如何,而對自制控制元件不適用。折騰了幾個小時,最終的解決方法是,在DLL檔案的屬性-安全頁中,手工增加使用者EveryOne。這麼所謂增加安全性?我只能說:微軟大腦有屎,浪費別人時間就是浪費別人生命。
全文結束。