天天看點

寫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調用代碼如下:

<% 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>
           

  COM在EXE應用開發工具中也可以調用。在寫複雜的COM時,可以用他們來檢測功能。COM注冊後,在VB中的“引用”清單中可以看到。例如下面是VB調用它的代碼:

Private Sub Command1_Click()
    Dim c
    Set c = CreateObject("CheckYear.LeapYear")
    Dim d As Boolean
    d = c.IsLeapYear(2004)
    MsgBox d
End Sub
           
寫COM元件用于ASP/PHP等動态網頁

  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的查詢。查詢IP的網站非常多,百度一下有幾百個,如http://ip.cn/index.php?ip=211.11.85.5,新浪的http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=22.73.22.80等,URLk末尾ip=x.x.x.x即是指查詢該IP的地理位置。要注意字元集問題,如果是GBKakGB2312的則中文無需特别處理,如果是utf-8或其他,則需轉換一下,否則會出現亂碼。

    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。這麼所謂增加安全性?我隻能說:微軟大腦有屎,浪費别人時間就是浪費别人生命。

    全文結束。