顯示具有 軟體 標籤的文章。 顯示所有文章
顯示具有 軟體 標籤的文章。 顯示所有文章

[程式]VB.Net2.0網頁原始碼取得函式

序言

我因為學術需求,要取得某些網址的網頁原始碼進行分析,因此寫了以下函式,貼出來與大家分享吧~

*2009/10/29 更新函式,加強切割網頁函式、抓網頁標頭。

開發環境

  • VB.Net 2.0 (VS2005)

專案設定

  • 建立專案後預設的專案屬性下,參考的元件如下圖:

  • 下面的程式中會用到【Web】這個物件,所以我們需要加入【System.Web】這個元件:

    點選加入,在.Net分頁下找到【System.Web】這個元件

網頁原始碼函式類別

Imports System.Net
Imports System.io
Imports System.Reflection

Public Class WebPageGenFunc
    Private Shared rd As New Random(Now.Second)
    Private Shared sec As Integer
    Private Shared lastsec As Integer = -1
    Public Shared Function sleepTime(Optional ByVal minimatime As Integer = 2600, Optional ByVal rangeSecond As Integer = 5) As Integer
        sec = (rd.Next Mod rangeSecond) * 1000 + minimatime
        While sec = lastsec
            sec = (rd.Next Mod rangeSecond) * 1000 + minimatime
        End While
        lastsec = sec
        System.Threading.Thread.Sleep(sec)
        Return sec
    End Function


    Private Shared Sub SetAllowUnsafeHeaderParsing20()
        Dim a As New System.Net.Configuration.SettingsSection
        Dim aNetAssembly As System.Reflection.Assembly = Assembly.GetAssembly(a.GetType)
        Dim aSettingsType As Type = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal")
        Dim args As Object() = Nothing
        Dim anInstance As Object = aSettingsType.InvokeMember("Section", BindingFlags.Static Or BindingFlags.GetProperty Or BindingFlags.NonPublic, Nothing, Nothing, args)
        Dim aUseUnsafeHeaderParsing As FieldInfo = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic Or BindingFlags.Instance)
        aUseUnsafeHeaderParsing.SetValue(anInstance, True)
    End Sub


    ''' <summary>
    ''' 使用Get方法取得網頁內容
    ''' </summary>
    ''' <param name="url">網址</param>
    ''' <param name="noCashe">不使用快取</param>
    ''' <returns>網頁的HTML</returns>
    ''' <remarks>使用Get方法取得網頁內容</remarks>
    Public Shared Function getHTMLGet(ByVal url As String, Optional ByVal noCashe As Boolean = False) As String
        getHTMLGet = Nothing
        SetAllowUnsafeHeaderParsing20()
        Dim wRs As HttpWebResponse
        Dim wRq As HttpWebRequest
        ' Create the request using the WebRequestFactory.

        wRq = CType(WebRequest.Create(url), HttpWebRequest)
        With wRq
            .UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
            .ContentType = "application/x-www-form-urlencoded"
            .Headers.Add("Accept-Language", "zh-tw")
            .Method = "GET"
            .Timeout = 10000
            If noCashe Then
                Dim policy As New Cache.HttpRequestCachePolicy(Cache.HttpRequestCacheLevel.NoCacheNoStore)
                .CachePolicy = policy
                .Headers.Add("Cache-Control", "no-cache")
            End If
        End With

        Try
            ' Return the response stream.
            wRs = CType(wRq.GetResponse(), HttpWebResponse)
            Dim streamResponse As Stream = wRs.GetResponseStream()
            Dim streamRead As New StreamReader(streamResponse)
            Dim responseString As String = streamRead.ReadToEnd()
            getHTMLGet = responseString
            ' Close Stream object.
            streamResponse.Close()
            streamRead.Close()
            ' Release the HttpWebResponse.
            wRs.Close()
        Catch ex As Exception
            Console.WriteLine(ex.ToString)
        End Try
    End Function

    ''' <summary>
    ''' 使用Post方法取得網頁內容
    ''' </summary>
    ''' <param name="url">網址</param>
    ''' <param name="postdata">傳遞參數,如a=123&b=456</param>
    ''' <param name="noCashe">不使用快取</param>
    ''' <returns>網頁的HTML</returns>
    ''' <remarks>使用Post方法取得網頁內容</remarks>
    Public Shared Function getHTMLPost(ByVal url As String, Optional ByVal postdata As String = Nothing, Optional ByVal noCashe As Boolean = False) As String
        getHTMLPost = Nothing
        SetAllowUnsafeHeaderParsing20()
        Dim wRs As HttpWebResponse
        Dim wRq As HttpWebRequest
        ' Create the request using the WebRequestFactory.
        wRq = CType(WebRequest.Create(url), HttpWebRequest)
        With wRq
            .UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
            .Headers.Add("Accept-Language", "zh-tw")
            .Method = "POST"
            .Timeout = 10000
            .KeepAlive = False
            If noCashe Then
                Dim policy As New Cache.HttpRequestCachePolicy(Cache.HttpRequestCacheLevel.NoCacheNoStore)
                .CachePolicy = policy
                .Headers.Add("Cache-Control", "no-cache")
            End If
            If Not postdata Is Nothing Then
                .Timeout = 60000
                Dim encoding As New System.Text.ASCIIEncoding()
                Dim byte1 As Byte() = encoding.GetBytes(postdata)
                .ContentType = "application/x-www-form-urlencoded"
                .ContentLength = byte1.Length
                .GetRequestStream().Write(byte1, 0, byte1.Length)
            End If
        End With
        wRq.GetRequestStream().Close()
        Try
            ' Return the response stream.
            wRs = CType(wRq.GetResponse(), HttpWebResponse)
            Dim streamResponse As Stream = wRs.GetResponseStream()
            Dim streamRead As New StreamReader(streamResponse)
            Dim responseString As String = streamRead.ReadToEnd()
            getHTMLPost = responseString
            ' Close Stream object.
            streamResponse.Close()
            streamRead.Close()
            ' Release the HttpWebResponse.
            wRs.Close()

        Catch ex As Exception
            Console.WriteLine(ex.ToString)
        End Try
    End Function
    ''' <summary>
    ''' 使用WebClient取得網頁內容
    ''' </summary>
    ''' <param name="url">網址</param>
    ''' <param name="postdata">傳遞的參數</param>
    ''' <param name="method">使用的方法,預設為POST</param>
    ''' <param name="noCashe">不使用快取</param>
    ''' <returns>網頁的HTML</returns>
    ''' <remarks>使用WebClient取得網頁內容</remarks>
    Public Shared Function getHTMLWebClient(ByVal url As String, ByRef postdata As Specialized.NameValueCollection, Optional ByVal method As String = "POST", Optional ByVal noCashe As Boolean = False) As String
        getHTMLWebClient = Nothing
        Try
            SetAllowUnsafeHeaderParsing20()
            Dim myWebClient As New WebClient()
            If noCashe Then
                Dim policy As New Cache.HttpRequestCachePolicy(Cache.HttpRequestCacheLevel.NoCacheNoStore)
                myWebClient.CachePolicy = policy
                myWebClient.Headers.Add("Cache-Control", "no-cache")
            Else
                Dim rheaders As WebHeaderCollection = myWebClient.ResponseHeaders
                If Not rheaders Is Nothing Then
                    Dim header As String = rheaders("Set-Cookie")
                    If Not header Is Nothing Then
                        myWebClient.Headers.Add("Cookie", header)
                    End If
                End If
            End If
            myWebClient.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)")
            myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded")
            myWebClient.Headers.Add("Accept-Language", "zh-tw")
            If postdata Is Nothing Then postdata = New Specialized.NameValueCollection
            Dim responseArray As Byte() = myWebClient.UploadValues(url, method, postdata)
            Dim encoding As New System.Text.UTF8Encoding
            getHTMLWebClient = encoding.GetString(responseArray)
        Catch ex As Exception
            Console.WriteLine(ex.ToString)
        End Try
    End Function

    ''' <summary>
    ''' 取得網頁的Body區段
    ''' </summary>
    ''' <param name="url">網址</param>
    ''' <param name="postdata">傳遞的參數,若有值會使用getHTMLPost取得</param>
    ''' <param name="postValue">傳遞的參數,若有值會使用getHTMLWebClient取得</param>
    ''' <param name="noCashe">不使用快取</param>
    ''' <returns>網頁的HTML</returns>
    ''' <remarks>取得網頁的Body區段</remarks>
    Public Shared Function getHTMLBody(ByVal url As String, Optional ByVal postdata As String = Nothing, Optional ByVal postValue As Specialized.NameValueCollection = Nothing, Optional ByVal noCashe As Boolean = False, Optional ByVal useWebClient As Boolean = False) As String
        getHTMLBody = Nothing
        Dim html As String
        If Not postValue Is Nothing Then
            html = getHTMLWebClient(url, postValue, , noCashe)
        ElseIf Not postdata Is Nothing Then
            html = getHTMLPost(url, postdata, noCashe)
        Else
            If useWebClient Then
                html = getHTMLWebClient(url, Nothing, "GET", noCashe)
            Else
                html = getHTMLGet(url, noCashe)
            End If

        End If
        If Not html Is Nothing Then
            getHTMLTagContain(html, "body", getHTMLBody)
        End If
    End Function
    ''' <summary>
    ''' 取得HTML中第一個符合的標籤內容的指標,並將取得的標籤內容寫入參數中
    ''' </summary>
    ''' <param name="html">HTML</param>
    ''' <param name="tag">標籤</param>
    ''' <param name="contain">取得的標籤內容</param>
    ''' <param name="indexEnd">此標籤結束於HTML的指標</param>
    ''' <returns>標籤內容的指標</returns>
    ''' <remarks>取得HTML中第一個符合的標籤內容的指標,並將取得的標籤內容寫入參數中</remarks>
    Public Shared Function getHTMLTagContain(ByVal html As String, ByVal tag As String, Optional ByRef contain As String = Nothing, Optional ByRef indexEnd As Integer = -1) As Integer
        tag = tag.ToLower
        contain = Nothing
        indexEnd = -1
        Dim indexBegin As Integer = -1
        Dim indexbBegin As Integer = -1
        If Not html Is Nothing Then
            indexBegin = html.ToLower.IndexOf("<" & tag)
            If indexBegin > -1 Then
                indexbBegin = html.IndexOf(">", indexBegin)
                If indexbBegin > -1 Then
                    indexbBegin += 1
                End If
                Dim findTag As Boolean = False
                indexEnd = indexbBegin
                Dim lastStart As Integer = indexbBegin
                Dim stopLimit2 As Integer = 9999
                Do
                    indexEnd = html.ToLower.IndexOf("</" & tag, indexEnd)
                    If indexEnd > -1 Then
                        If html.Substring(lastStart, indexEnd - lastStart).IndexOf("<" & tag) > -1 Then
                            lastStart = indexEnd
                            indexEnd = indexEnd + ("</" & tag).Length
                            findTag = True
                        Else
                            findTag = False
                        End If
                    Else
                        findTag = False
                    End If
                    stopLimit2 -= 1
                Loop While findTag And stopLimit2 > 0

                If indexEnd > -1 Then
                    contain = html.Substring(indexbBegin, indexEnd - indexbBegin)

                    indexEnd = html.IndexOf(">", indexEnd)
                    If indexEnd > -1 Then
                        indexEnd += 1
                    End If
                End If

            End If
        End If
        Return indexbBegin
    End Function
    ''' <summary>
    ''' 取得HTML中第一個符合的標籤屬性的指標,並將取得的標籤內容與該屬性內容寫入參數中
    ''' </summary>
    ''' <param name="html">HTML</param>
    ''' <param name="tag">標籤</param>
    ''' <param name="attName">屬性名稱</param>
    ''' <param name="att">取得的屬性內容</param>
    ''' <param name="contain">取得的標籤內容</param>
    ''' <param name="indexEnd">此標籤結束於HTML的指標</param>
    ''' <returns></returns>
    ''' <remarks>取得HTML中第一個符合的標籤屬性的指標,並將取得的標籤內容與該屬性內容寫入參數中</remarks>
    Public Shared Function getHTMLTagAtt(ByVal html As String, ByVal tag As String, ByVal attName As String, Optional ByRef att As String = Nothing, Optional ByRef contain As String = Nothing, Optional ByRef indexEnd As Integer = -1) As Integer
        att = Nothing
        contain = Nothing
        tag = tag.ToLower
        attName = attName.ToLower
        indexEnd = -1
        Dim indexBegin As Integer = -1
        Dim indexaBegin As Integer = -1
        Dim indexbEnd As Integer = -1
        Dim findTag As Boolean = False
        Dim sign As String

        If Not html Is Nothing Then
            indexBegin = 0
            Dim stopLimit1 As Integer = 9999
            Do
                indexbEnd = -1
                indexBegin = html.ToLower.IndexOf("<" & tag, indexBegin)
                If indexBegin > -1 Then
                    indexbEnd = html.IndexOf(">", indexBegin)
                    If indexbEnd > -1 Then
                        indexaBegin = html.Substring(0, indexbEnd).Replace("""", "'").ToLower.IndexOf(attName & "='", indexBegin)
                        If indexaBegin > -1 Then
                            sign = html.Substring(indexaBegin + (attName & "=").Length, 1)
                            indexaBegin += (attName & "='").Length
                            Dim indexaEnd As Integer = html.Substring(0, indexbEnd).IndexOf(sign, indexaBegin)
                            If indexaEnd > -1 Then
                                att = html.Substring(indexaBegin, indexaEnd - indexaBegin)
                            End If
                        Else
                            indexBegin = indexbEnd + 1
                            Continue Do
                        End If
                        indexbEnd += 1
                    End If

                    findTag = False
                    indexEnd = indexbEnd
                    Dim lastStart As Integer = indexbEnd

                    Dim stopLimit2 As Integer = 9999
                    Do
                        indexEnd = html.ToLower.IndexOf("</" & tag, indexEnd)
                        If indexEnd > -1 Then
                            If html.Substring(lastStart, indexEnd - lastStart).IndexOf("<" & tag) > -1 Then
                                lastStart = indexEnd
                                indexEnd = indexEnd + ("</" & tag).Length
                                findTag = True
                            Else
                                findTag = False
                            End If
                        Else
                            findTag = False
                        End If
                        stopLimit2 -= 1
                    Loop While findTag And stopLimit2 > 0

                    If indexEnd > -1 Then
                        contain = html.Substring(indexbEnd, indexEnd - indexbEnd)
                        indexEnd = html.IndexOf(">", indexEnd)
                        If indexEnd > -1 Then
                            indexEnd += 1
                        End If
                    End If
                Else
                    Exit Do
                End If
                stopLimit1 -= 1
            Loop While att Is Nothing And stopLimit1 > 0
        End If
        Return indexbEnd
    End Function
    ''' <summary>
    ''' Url參數值編碼
    ''' </summary>
    ''' <param name="value">參數值</param>
    ''' <returns>編碼結果</returns>
    ''' <remarks>Url參數值編碼</remarks>
    Public Shared Function getEncodeStr(ByVal value As String)
        Return Web.HttpUtility.UrlEncode(value)
    End Function
    ''' <summary>
    ''' Url參數值解碼
    ''' </summary>
    ''' <param name="value">參數值</param>
    ''' <returns>解碼結果</returns>
    ''' <remarks>Url參數值解碼</remarks>
    Public Shared Function getDecodeStr(ByVal value As String)
        Return Web.HttpUtility.UrlDecode(value)
    End Function
End Class

使用範例程式

        Dim indexEnd As Integer
        Dim valueAttribute As String
        Dim valueContain As String
        Dim url As String = "http://allen080.blogspot.com/2009/05/vbnet20.html"
        '使用WebRequest的Get方法取得整個網頁的HTML
        'Dim htmlAll As String = WebPageGenFunc.getHTMLGet(url)
        '取得網頁Body的部份
        Dim htmlBody As String = WebPageGenFunc.getHTMLBody(url)
        If Not htmlBody Is Nothing Then
            indexEnd = htmlBody.IndexOf("<span class='item-control blog-admin'>")
            valueAttribute = Nothing
            valueContain = Nothing
            If indexEnd > 0 Then
                htmlBody = htmlBody.Substring(indexEnd)
                '取得a標籤1的內容
                WebPageGenFunc.getHTMLTagContain(htmlBody, "span", valueContain, indexEnd)
                Console.WriteLine("span標籤的內容: " & valueContain)
                'htmlBody = htmlBody.Substring(indexEnd)
                '取得a標籤2的內容與href的屬性
                WebPageGenFunc.getHTMLTagAtt(htmlBody, "a", "onclick", valueAttribute, valueContain, indexEnd)
                Console.WriteLine("a標籤的內容與onclick的屬性: " & valueAttribute & vbTab & ",內容:" & valueContain)
            End If
        End If
        

        '使用WebClient的Post方法取得資料
        url = "http://al080.summerhost.info/invoiceMe/index.php"
        Dim searchStr As String = "123"
        Dim postdata As New Specialized.NameValueCollection
        postdata.Add("ddlYear", "2009")
        postdata.Add("ddlMonth", "7-8")
        postdata.Add("txtInvNO", searchStr)
        postdata.Add("btnMatchInv", "對獎")
        htmlBody = WebPageGenFunc.getHTMLBody(url, , postdata)
        If Not htmlBody Is Nothing Then
            indexEnd = htmlBody.IndexOf("<div class=""DivRight"">")
            If indexEnd > 0 Then
                htmlBody = htmlBody.Substring(indexEnd)
                '取得div標籤的內容
                WebPageGenFunc.getHTMLTagContain(htmlBody, "div", valueContain, indexEnd)
                Console.WriteLine("使用WebClient的Post方法取得資料: " & valueContain)
            End If
        End If
        
        '使用WebRequest的Post方法取得資料
        searchStr = String.Empty
        '在組合參數時要同時編碼
        For i As Integer = 0 To postdata.Count - 1
            searchStr &= "&" & postdata.GetKey(i) & "=" & WebPageGenFunc.getEncodeStr(postdata(i))
        Next
        searchStr = searchStr.Substring(1)
        htmlBody = WebPageGenFunc.getHTMLBody(url, searchStr)
        If Not htmlBody Is Nothing Then
            indexEnd = htmlBody.IndexOf("<div class=""DivRight"">")
            If indexEnd > 0 Then
                htmlBody = htmlBody.Substring(indexEnd)
                '取得div標籤的內容
                WebPageGenFunc.getHTMLTagContain(htmlBody, "div", valueContain, indexEnd)
                Console.WriteLine("使用WebRequest的Post方法取得資料: " & valueContain)
            End If
        End If

執行結果

span標籤的內容:
<a class='quickedit' href='http://www.blogger.com/rearrange?blogID=2698062899592178296&widgetType=HTML&widgetId=HTML1&action=editWidget' onclick='return _WidgetManager._PopupConfig(document.getElementById("HTML1"));' target='configHTML1' title='編輯'>
<img alt='' height='18' src='http://img1.blogblog.com/img/icon18_wrench_allbkg.png' width='18'/>
</a>

a標籤的內容與onclick的屬性: return _WidgetManager._PopupConfig(document.getElementById("HTML1"));    ,內容:
<img alt='' height='18' src='http://img1.blogblog.com/img/icon18_wrench_allbkg.png' width='18'/>

使用WebClient的Post方法取得資料: <span style="font-weight:bold;">對獎結果:</span><br>
                <div class="DivResult">
            無中獎發票...<br>
                </div>
           
使用WebRequest的Post方法取得資料: <span style="font-weight:bold;">對獎結果:</span><br>
                <div class="DivResult">
            無中獎發票...<br>
                </div>

相關連結

[程式]VB.Net2.0資料庫通用存取函式

序言

在VS2005建立VB專案(或Web網站)後,若要進行資料庫存取,我個人比較習慣將連線字串寫在設定檔app.config(或web.config)下。

不過VB專案預設是不會產生這個檔,而且在程式中若要取得連線字串的設定也要對專案的參考進行設定。

以下記錄下我做的設定,並把資料庫存取程式簡化為函式。

開發環境

  • VB.Net 2.0 (VS2005)
  • MSSQL2005 Express

專案設定

  • 建立專案後預設的專案屬性下,參考的元件如下圖:

  • 下面的程式中會用到【ConfigurationManager】這個物件來取得設定檔的連線字串,所以我們需要加入【System.Configuration】這個元件:

    點選加入,在.Net分頁下找到【System.Configuration】這個元件
  • 再來要在專案加入新項目【應用程式組態】,名稱用預設的【app.config】就可以了:

  • 編輯app.config,在【configuration】標籤內加入連線字串的設定如:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    ...
    <connectionStrings>
    <add name="MSSQLDB1"
    connectionString="Data Source=localhost;Initial Catalog=MyTestDB;Integrated Security=True"
    providerName="System.Data.SqlClient" />
    <add name="MSSQLDB2"
    connectionString="Data Source=127.0.0.1;Initial Catalog=MyTestDB;User ID=sa;Password=1234"
    providerName="System.Data.SqlClient" />
    </connectionStrings>
    ...

通用存取函式類別


Imports System.Data.SqlClient
Imports System.Configuration
Public Class DBAccessFunc
    ''' <summary>
    ''' 從ConfigurationManager中的ConnectionStrings找出Initial Catalog
    ''' </summary>
    ''' <param name="ConnName">ConnectionStrings名稱(String)</param>
    ''' <returns>回傳資料庫名稱</returns>
    ''' <remarks>從ConfigurationManager中的ConnectionStrings找出Initial Catalog</remarks>
    Public Shared Function getDBName(ByVal ConnName As String) As String
        Dim val As String = ""
        Dim ConnString As String = ConfigurationManager.ConnectionStrings(ConnName).ConnectionString
        Dim i As Integer = ConnString.IndexOf("Initial Catalog=")
        If i > -1 Then
            val = ConnString.Substring(i + "Initial Catalog=".Length)
            i = val.IndexOf(";")
            If i > -1 Then
                val = val.Substring(0, i)
            End If
        End If
        Return val
    End Function

    Public Shared Function getConnString(ByVal ConnName As String) As String
        Return ConfigurationManager.ConnectionStrings(ConnName).ConnectionString
    End Function


    Public Shared Function getConn(ByVal ConnName As String) As SqlConnection
        Return New SqlConnection(getConnString(ConnName))
    End Function
    ''' <summary>
    ''' 查詢資料庫
    ''' </summary>
    ''' <param name="cn">連線</param>
    ''' <param name="sql">查詢內容</param>
    ''' <returns>回傳查詢結果的DataTable</returns>
    ''' <remarks>查詢資料庫並回傳查詢結果的DataTable</remarks>
    Public Shared Function getTable(ByRef cn As SqlConnection, ByRef sql As String, Optional ByVal isColseConn As Boolean = True) As Data.DataTable
        Dim da As New SqlDataAdapter(sql, cn)
        Dim dt As New Data.DataTable("dt_xml")
        Try
            If cn.State = ConnectionState.Closed Then cn.Open()
            da.SelectCommand.CommandTimeout = 36000000
            da.Fill(dt)
        Catch ex As Exception
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        End Try
        If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        Return dt
    End Function

    ''' <summary>
    ''' 執行命令
    ''' </summary>
    ''' <param name="cn">連線</param>
    ''' <param name="sql">查詢內容</param>
    ''' <returns>回傳受影響的資料筆數</returns>
    ''' <remarks>執行命令並回傳受影響的資料筆數</remarks>
    Public Shared Function doCmd(ByRef cn As SqlConnection, ByRef sql As String, Optional ByRef param() As SqlParameter = Nothing, Optional ByVal isColseConn As Boolean = True) As Integer
        Dim result As Integer = 0
        Dim cmd As New SqlCommand
        Try
            cmd.Connection = cn
            cmd.CommandText = sql
            If Not param Is Nothing Then
                cmd.Parameters.AddRange(param)
            End If
            cmd.CommandTimeout = 36000000
            If cn.State = ConnectionState.Closed Then cn.Open()
            result = cmd.ExecuteNonQuery()
        Catch ex As Exception
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        Finally
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        End Try
        Return result
    End Function


    ''' <summary>
    ''' 取得單一資料
    ''' </summary>
    ''' <param name="cn">連線</param>
    ''' <param name="sql">查詢內容</param>
    ''' <returns>回傳受影響的資料筆數</returns>
    ''' <remarks>執行命令並回傳受影響的資料筆數</remarks>
    Public Shared Function doScalar(ByRef cn As SqlConnection, ByRef sql As String, Optional ByRef param() As SqlParameter = Nothing, Optional ByVal isColseConn As Boolean = True) As Object
        Dim result As Object = Nothing
        Dim cmd As New SqlCommand
        Try
            cmd.Connection = cn
            cmd.CommandText = sql
            If Not param Is Nothing Then
                cmd.Parameters.AddRange(param)
            End If
            cmd.CommandTimeout = 36000000
            If cn.State = ConnectionState.Closed Then cn.Open()
            result = cmd.ExecuteScalar()
        Catch ex As Exception
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        Finally
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        End Try
        Return result
    End Function

    Public Function executeStoredProcedure(ByRef cn As SqlConnection, ByVal procedure As String, Optional ByRef param As SqlParameter() = Nothing, Optional ByRef output As SqlParameter() = Nothing, Optional ByVal isColseConn As Boolean = True) As Integer
        Dim result As Integer = 0
        Dim cmd As New SqlCommand(procedure, cn)
        Try

            cmd.CommandText = procedure
            cmd.CommandTimeout = 36000000
            cmd.CommandType = CommandType.StoredProcedure
            If Not param Is Nothing Then cmd.Parameters.AddRange(param)
            If Not output Is Nothing Then
                For Each o As SqlParameter In output
                    o.Direction = ParameterDirection.Output
                Next
                cmd.Parameters.AddRange(output)
            End If

            '開啟資料庫連線
            If cn.State = ConnectionState.Closed Then cn.Open()
            '設定變數儲存受影響資料列
            result = cmd.ExecuteNonQuery()
        Catch ex As Exception
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
            Throw ex
        Finally
            cmd.Parameters.Clear()
            If isColseConn And cn.State = ConnectionState.Open Then cn.Close()
        End Try
        Return result
    End Function
End Class


使用範例程式

Dim connStr1 As String = DBGenFunc.getConnStr("MSSQLDB1")
Dim sourceTable As String() = {"[" & DBGenFunc.getDBName("MSSQLDB1") & "].[dbo].[" & "MyTestTab" & "]", _
"[" & DBGenFunc.getDBName("MSSQLDB1") & "].[dbo].[" & "MyContentTab" & "]"}
Dim param() As SqlClient.SqlParameter = {New SqlClient.SqlParameter("P0", SqlDbType.VarChar)}
Dim sql As String

Dim title As String

Console.WriteLine("doCmdScalar Start:")
sql = "SELECT Title" & vbCrLf & _
" FROM " & sourceTable(0) & "" & vbCrLf & _
" WHERE SN=@P0"
param(0).Value = 1
title = DBGenFunc.doCmdScalar(connStr1, sql, param)
Console.WriteLine("doCmdScalar" & vbTab & title)

Console.WriteLine("getTable Start:")
sql = "SELECT Title" & vbCrLf & _
" FROM " & sourceTable(0) & "" & vbCrLf
Dim dt As DataTable = DBGenFunc.getTable(connStr1, sql)
For Each r As DataRow In dt.Rows
title = r.Item(0)
Console.WriteLine("getTable" & vbTab & title)
Next

Console.WriteLine("getTableToArray Start:")
Dim data As String() = DBGenFunc.dataTableToArray(Of String)(dt, 0)
For Each r As String In data
title = r
Console.WriteLine("getTable" & vbTab & title)
Next

Console.WriteLine("doCmd Start:")
sql = "INSERT INTO " & sourceTable(0) & "" & vbCrLf & _
"VALUES(@P0,@P1)"
param = New SqlClient.SqlParameter() {New SqlClient.SqlParameter("P0", SqlDbType.VarChar), _
New SqlClient.SqlParameter("P1", SqlDbType.VarChar)}
param(0).Value = "TNew"
param(1).Value = "SNew"
title = DBGenFunc.doCmd(connStr1, sql, param)
Console.WriteLine("doCmd" & vbTab & title)

Console.WriteLine("getReader Start:")
sql = "SELECT Title, Subject" & vbCrLf & _
" FROM " & sourceTable(0) & "" & vbCrLf
Dim dr As SqlClient.SqlDataReader = DBGenFunc.getReader(connStr1, sql)
While dr.Read()
title = dr.Item(0)
Console.WriteLine("getReader" & vbTab & title & vbTab & dr.Item(1))
End While
DBGenFunc.closeReader()

執行結果

doCmdScalar Start:
doCmdScalar T1
getTable Start:
getTable T1
getTable T2
getTable T3
getTable TNew
getTableToArray Start:
getTable T1
getTable T2
getTable T3
getTable TNew
doCmd Start:
doCmd 1
getReader Start:
getReader T1 S1
getReader T2 S2
getReader T3 S3
getReader TNew SNew
getReader TNew SNew

[筆記]我的FireFox愛用套件

序言

此篇記下我常用的套件相關連結,方便安裝使用。

清單

  1. FireFox主程式(我都用Portable版不用安裝):
    FireFox Portable by portableapps.com
  2. Foxmarks官網。書籤同步,可至官網直接登入瀏覽你的書籤。
  3. FireGestures:滑鼠手式(控制上一頁下一頁等)。
  4. QuickDrag:用拖曳手勢更容易地在新分頁裡打開連結、搜尋文字和儲存圖片。
  5. 新同文堂官網。中文繁簡體互轉工具。
  6. Tab Mix Plus官網。分頁加強版。
  7. Mozilla Archive Format:MHT (MHTML) 檔案開啟外掛。
  8. Copy Links:方便複製連結。
  9. FacePad:Facebook相簿下載(安裝後於相簿連結點右鍵可以看到功能)。
  10. Greasemonkey官網。客製化網頁Script功能。搭配以下Script。
  11. FlashGot官網。搭配其他下載工具用。
  12. PCmanfx官網。上BBS。
  13. Profile Manager and Synchronizer :多帳號登入。

[教學]Windows初始安裝設定

(此篇文章於2006/11/11首次發表,最後一次修改於2008/10/24)

雖然身為資工人,Windows的安裝簡直是如同喝水一般~

不過我還滿想記下一些我常做的動作,當做提醒自己還有哪些動作忘了做~

PS.常用工具的部分我從這篇分離了

Windows XP安裝過程中

  • 網路上看到了安裝過程的簡介,如果第一次安裝可參考這篇【淺談Windows新安裝
  • 在安裝過程中預設會要求輸入第一個使用者帳號。如果要跳過這個動作,只要按【Shift+F10】就會跳出命令提示字元的視窗。然後輸入【taskmgr】叫出工作管理員,就可以把這個初始設定的程式關掉,讓Windows預設以Administrator帳號進入。
  • 一般而言,如果懂得保養,系統碟給個15~20G就很夠用了,其他的可能分割為備份與資料碟
  • 設定網路通訊協定時,新增【IPX】通訊協定,如此比較容易找到附近的網芳
  • 開啟防火牆

剛安裝完Windows XP

  • 使用Windows Update先更新所有需要更新的修正,以防被病毒攻擊
  • 統一暫存資料夾,方便未來刪除 更改暫存檔儲存目錄,清理磁碟機更容易~ 滑鼠右點〔我的電腦〕→〔內容〕→〔進階〕→〔環境變數〕 將〔用戶名的使用者變數〕及〔系統變數〕中的 〔temp〕及〔tmp〕的變數選〔編輯〕將〔變數值〕統一改為〔%SystemRoot%\Temp〕 日後所有暫存檔將統一存放在 X:\Windows\Temp 的目錄下
  • 安裝防毒軟體,並設定每日更新:檔案→排程更新
  • 移動IE的暫存資料夾 選擇IE的【工具】→【網際網路選項】→Temporary Internet files【設定】→【移動資料夾】→選到【X:\Windows\Temp】
  • 我通常重視效能多過外觀,所以 設定【系統】→【進階】→效能【設定】→【調整成最佳效能】
  • 【控制台】→【新增及移除程式】→【新增/移除Windows元件】→取消勾選【Windows Messenger】
  • 如果常會用記事本開檔,可下載這個,執行後,右鍵點檔案會多個用記事本開啟
  • 移動特殊資料夾 有些資料夾可利用此方式不要放在系統碟。預設的桌面、我的最愛等,放在【%USERPROFILE%】中 。只要在檔案總管選擇這些資料夾,然後選擇【編輯】→【移到資料夾】,然後找個資料碟的資料夾就可以了。

遠端桌面

  • 設定【系統】→【遠端】→【允許使用者遠端連線到這部電腦】
  • 【控制台】→【Windows 防火牆】→【例外】→勾【遠端桌面】
  • 更改遠端連線連接埠:
    1. 【開始】→【執行】輸入【regedit】啟動「登錄編輯程式」。
    2. 找出並按一下下列登錄子機碼: 【HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp\PortNumber】
    3. 在 [編輯] 功能表上,按一下 [修改],再按一下 [十進位]。
    4. 輸入新的連接埠編號(預設是3389),然後按一下 [確定]。
    5. 結束「登錄編輯器」。
    6. 【控制台】→【Windows 防火牆】→【例外】→【新增連接埠】→輸入妳設定的port
  • 如果在比較舊的Windows上沒有遠端連線工具如,Win2000,請參考
  • 連線時如果有改Port,就在IP後加【:port】,如【a.b.c.d:1234】

用XP架IIS與FTP

  • 擴充連線數量
  • 安裝IIS
  • 安裝.Net framework 2.0
  • 【控制台】→【Windows 防火牆】→【例外】→【新增程式】 C:\WINDOWS\system32\inetsrv\inetinfo.exe
  • 安裝SQL 2005 Express
  • 安裝FTP Server(我目前覺得Gene6 FTP Server最好用,可惜不是Freeware)
  • 【控制台】→【Windows 防火牆】→【例外】→【新增程式】 ftp server的路徑
  • 如果是動態IP,可用NO-IP(教學)

參考連結

[心得]Ubuntu初體驗-不得善終


話說資工的學生Linux這麼不熟實在不是件光榮的事~

不過這一切都是跟用到的機率有關~

無論如何~Ubuntu近來因為Google而聲名大噪(可參考癮科技)~

我朋友都忍不住下去玩~我這個資工本科的人在觀望許久終於忍痛把我家電腦大風吹~

弄了台爛爛的NB來灌~但最後仍不得善終~

不過卻從中學到許多Lunux的操作~就把這件事當作做壞的實驗記錄下來吧~

環境

我的NB是NEC的舊機種,對XP它就已經連驅動都不用提供了,因為XP就直接可以驅動所有硬體了~

不過這台NB的最大問題就是它的內建網路卡是完全不能用的,接了線也沒反應。

所以我之前還買了個無線網卡(PLANEX GW-NS54GMZ)接在它的PCMCIA~

而最後的敗筆也敗在這個無線網卡...

我在裝的時候發現這張卡不提供Linux的驅動程式,但網路上有人Post出他成功的安裝過程~

所以我還是嘗試以這張網卡安裝看看~


相信有用Ubuntu的人做的第一件事就是抓張Live CD來看看執行起來會如何~

我使用的是Ubuntu 7.10,下載完後燒成光碟來試用。

安裝

以Live CD開機後,我想我的電腦光碟機真的滿老舊了~

整個運作起來就是慢到不行~

我玩了一陣子後就決定把Ubuntu直接安裝到硬碟了~

不過剛開始安裝我就遇到Lunux與Windows安裝差異的首部曲~

硬碟分割...啊是要怎麼分割?~用什麼格式?~要怎麼分好?~


稍微從網路上爬了一下文~

了解系統最少要給它個4G空間,

初學大致上都用ext2或ext3(ext3是ext2加log的擴充版),

然後要分記憶體空間的2倍大小為swap當虛擬記憶體~

不過我一開始選ext3都會當在磁碟分析的地方~

後來我選ext2就沒這個問題~我也不知為什麼~

驅動

完成安裝後,就要處理我的無線網卡~

這時我就發現一個大問題,Unbuntu上許多套件要使用前要安裝,

但大多數的教學所使用的方法都必須要連上網路然後再下命令安裝~

安裝過程中~有缺的套件它會自己上網抓~

可是我的環境就是在這個網卡安裝完前,沒辦法讓我的Linux上網~

想要從別台下載套件卻也不知要下載哪些套件~還有該如何安裝~


我最終參考了許多人安裝東西的過程,失敗重來好幾次後~

最終步驟如下

  1. 下載Ubuntu Alternate install CDISO
  2. 下載Ndiswrapper套件(如ndiswrapper-1.51.tar.gz)
  3. 將這兩個檔案用隨身碟之類的東西放到Lunix可讀的到的地方
  4. 然後用終端機輸入命令如下,將【ubuntu-7.10-alternate-i386.iso】指到ISO檔
    sudo mount -o loop 【ubuntu-7.10-alternate-i386.iso】 /cdrom/
  5. 然後將此光碟設為更新來源
    sudo apt-cdrom -m add
  6. 安裝build-essential(此套件用來提供GCC的編譯相關套件,Ndiswrapper安裝時會用到)
    sudo apt-get install build-essential
  7. 安裝完成後,就可以安裝Ndiswrapper套件了,先找個目錄做為等一下要放安裝檔的地方,建議放在【/home/帳號/】底下,下命令改變現在所在目錄到該目錄
    cd 【/home/帳號/】
  8. 將【ndiswrapper-1.51.tar.gz】指到ndiswrapper套件壓縮檔所在
    tar vxzf 【ndiswrapper-1.51.tar.gz】
  9. 解壓縮後就會出現對應目錄,進入該目錄
    cd ndiswrapper-1.51
  10. 下面是依照套件安裝的說明做的動作,分別執行這三個動作,如果中間都沒有Error出現,那就是安裝成功了
    make uninstall
    make
    make install
  11. 我試過這張網卡的幾種版本驅動後,最後覺得最可能是WinXP_2K版的(雖然最後還是沒成功)。請確定 INF 檔,SYS 檔全部都在同一個目錄下。現在使用ndiswrapper來安裝,指令如下(【mrv8335.inf】指到該驅動程式所在)
    sudo ndiswrapper -i 【mrv8335.inf】
  12. 你可以使用下面的指令來看看是否有安裝該驅動程式,他會列出他有安裝哪些驅動。
    sudo ndiswrapper -l
  13. 執行下述指令來載入 module,這時網路卡就應該會出現在系統可偵測到的網卡中並名為wlan0了。(如果你要看有沒有錯誤發生,可以到/var/log/syslog去看log檔)
    sudo modprobe ndiswrapper
  14. 儲存ndiswrapper的設定到modprobe
    ndiswrapper -m
  15. 下面這個命令我也不懂功能,是參考別人做的過程下的指令。
    loadndisdriver mrv8335
  16. 如果要在載入時設定網卡去找網路可編輯檔案【/etc/network/interfaces】內容,增加下面這段
    auto wlan0
    iface wlan0 inet dhcp
  17. 編輯完後執行下面的指令它就會依該網路設定執行網路的scan
    sudo ifup wlan0

結果

這些大致上就是我做的步驟,不過最後雖然電腦有找到這張網卡~

從syslog上也會看到這張網卡被抓到了~

不過只要一執行網卡狀態的工具(如iwconfig)就會發現停住了~

應該是它在偵測網路時,會讓電腦不能再執行下去~

就連我要關機都不行,還用終端機下【shutdown now】,然後它就會關到一半然後停住~

讓我強制的用手動方式把電源停止...

真不知問題再哪~希望有人能夠幫幫我~

Linux操作雜記

  • Ctrl+Alt+ F1~F6 終端機
  • Ctrl+Alt+ F7 X-window
  • vim指令:文字編輯器
    • i:進入編輯模式新增文字
    • d:清除
    • Esc:離開編輯模式
    • :q:離開
    • :wq:儲存並離開

Wubi

可在windows安裝後,從windows下執行的Ubuntu安裝程式。

它會虛擬出一個磁碟空間以安裝Ubuntu~

目前能裝Ubuntu 7.10的版本為:Wubi-7.10-alpha-rev386

它會去幫你下載ubuntu-7.10-alternate-i386.isoubuntu-7.10-desktop-i386.iso

我想也可以自己下載後放在安裝檔路徑下的ubuntu-backup資料夾,它好像自己會去抓~

PS.我目前測試的時候改用這個,不過網路上也有人說Wubi對硬體的支援不太好~

相關連結

[記事]Asp.Net讓人有像VB一樣簡單的印象

很久沒在這寫文章了~因為沒碰到什麼特別想寫的題材~

不過這段時間我也沒閒著~

因緣際會下~我用ASP.Net 2.0寫了兩個很簡陋的網站~

一個是免費幫某佛教講堂寫的成績單系統~(這樣有算做功德嗎?)

因為他們裡面其實沒什麼會寫程式的人~

就有人用Access要提供師父能將學員資料還有課程成績輸入進去~

他原本還用Access的一些表單來讓人容易點輸入資料~

可是後來發現沒辦法輸出一個個人歷年成績單的格式~

那時透過我老爸找上了我~

想要我用VB (後來我才知道他應該是在說ASP.Net) 來幫他處理這個問題~


另一個是幫某大學資科的學生寫的網站~(小小收點工本費~)

他說他的指導老師希望他能學個語言~

然後做個完整的系統~

他就開始上網找別人的範例~

結果在藍色小鋪找到我三年多前以VS2003寫的一個網站~

他覺得功能符合他的需求~

但因為他要用VS2005開發~又有點趕時間~

最後找上我這個原始開發者~希望我能用VS2005的控制項做出那個網站的功能~


第二個Case我用三天完成了~

第一個Case因為需求是慢慢增加的~加上我是有空才做~有時要問需求又找不到人~

所以還在弄~


在這兩個Case中~我發現一件事~

從ASP .Net到了ASP .Net 2.0後~

這個網站的開發方式與工具~已經開始讓人有如同VB 6的那種感覺~

【夠簡單~夠直覺】

至少門檻已經降到逐夠讓一個業餘想寫寫小網站的人~

可以在拖拉點選之間做出一個功能還不算太差的東西~


為什麼我會說像VB 6呢~

相信曾經經過VB 6極盛時期~而且玩過VB 6的人~

應該跟我有相同感覺~

【居然可以這麼容易寫出一個視窗程式】

當然~這要看你玩多大啦~

但至少是個門檻夠低的開發工具~


而ASP.Net 2.0能像當初的VB 6一樣~

給連VB怎麼寫的人都不知道的狀況下~居然會在有需求時~

跟我說一句~

【要做這樣東西,好像可以用ASP.Net吧】

或是

【聽說ASP.NET2.0配合2005可以省很多程式碼】

重點除了它真的把做網站搞的很像VB 6的開發模式外~

另外還在後來提供Visual Web Developer 2005 Express這個免費版的開發工具~

讓這件事變的更沒理由不用看看~

我並不是絕對挺微軟或是其他公司~

而我自己也曾與朋友討論過各種語言的開發特性與缺點~

甚至最近也剛碰ROR~

但就一個簡單快速的概念驗證(prove of concept)的網站開發而言~

ASP.Net確實有相當程度的吸引力讓我使用它~

這是我的看法~

換回SharpReader

前陣子寫了一篇比較7個RSS Reader與GreateNews使用教學之後,

我用了GreatNews一個月,

發現它有個嚴重的bug,

就是會掉文章~

也就是明明有的網站有新的文章,

GreatNews確沒顯示出來~

雖然不是每個網站都如此,

但有幾個我常看的網站會這樣~

所以最近我忍不住,又換回SharpReader~

順道一提~

我那時換RSS Reader之一的原因,是SharpReader的官網也掛了~

不過最近開又好了~

可是作者還是沒有新的版本釋放出來...

比較7個RSS Reader與GreateNews使用教學

我個人一直很喜歡用RSS專屬的讀取器訂閱喜歡的內容,

因為它提供我快速且方便的方便得到最新的消息~

不過我最近換了個讀取器,就順手寫篇使用教學~

GreateNews使用教學

GreatNews下載完後,開啟GreatNews,如下圖選擇語系,並勾選新聞列表

其他細部設定可到【工具】→【選項】裡設定,下面附上參考設定內容

然後如果要新增訂閱,就複製RSS的網址,如http://allen080.blogspot.com/feeds/posts/default?alt=rss

然後在新聞頻道點選右鍵,選擇【新增】→【頻道】

貼上頻道網址,然後選下一步

選擇放在哪個群組

完成後就可選擇該訂閱內容觀看囉

順道一提~我當然是直接將原本SharpReader上的訂閱匯出成OPML,再讓GreatNews匯入的,這部份就不再贅述~

談談為什麼我要用GreatNews

最近我最常用的RSS Reader-SharpReader 0.9.7.0出現了一些讓我不太滿意的Bug

像是我關機時如果沒有手動先把SharpReader關起來~

就會出現錯誤警告~

下回開時它的狀態就會回朔到某個時間~

我之前新增的訂閱就可能會消失掉~

有的時候甚至開啟時就會出問題~

或是開某些網頁(由其是某些人的無名網誌),整個程式就會當在那~

等等小問題~

而我一直忍著希望它的下個版本會更好~

沒想到最近去它的官方網站,居然變成了一個奇怪的購物網~或是進不去~

作者的部落格從去年之後也沒再更新了

所以我就開始尋找有沒有好的RSS Reader...

各RSS Reader使用感

還是先從SharpReader談起,作為基本比較。

  • SharpReader 0.9.7.0
    • 環境簡潔,操作自然
    • 頻道與文章切換速度都算不錯
    • 提供文章文字內容(不直接顯示原始網頁)
    • 各種Feed的資訊顯示完整(有網站縮圖與Comment數量會顯示)
    • 有些Bug

GreatNews是我目前覺得可取代SharpReader,可惜沒有網站縮圖與Comment數量

  • GreatNews 1.0 Beta
    • 環境簡潔,功能齊全
    • 頻道與文章切換速度快
    • 提供文章文字內容(不直接顯示原始網頁)
    • 預設了一些特殊功能,整合Bloglines,且可以外加一些命令,藉此整合一些書籤網站與部落格
    • 可以標簽為文章分類
    • 含中文語系
    • 有免安裝的版本
    • 沒有網站縮圖與Comment數量
    • 只支援單層分類
    • 讀過的文章會先隱藏,要點一下顯示才會顯示(我個人不需這樣的功能,可是沒有選項取消)(把過濾的設定調成全部就沒這個問題了)

RSSOwl則是另一個我覺得不錯的,不過要稍微多調整一下才會符合習慣,且它的分頁有點分過頭了

  • RSSOwl 1.2.3
    • 環境簡潔,功能齊全
    • 頻道與文章切換速度快
    • 提供文章文字內容(不直接顯示原始網頁)
    • 含中文語系
    • 提供分頁瀏覽
    • 有免安裝的版本
    • 沒有網站縮圖與Comment數量
    • 剛啟動時會先花一小段時間載入文章

RSS Bandit其實功能還不錯,還提供遠端儲存功能,可惜效能太差了,連切換速度都不好,還常搞爛我的電腦

  • RSS Bandit
    • 提供遠端儲存,讓多部機器能統一訂閱
    • 環境漂亮,功能齊全
    • 各種Feed的資訊顯示完整(有網站縮圖與Comment數量會顯示)
    • 效能不高,頻道與文章切換速度慢
    • 提供文章文字內容(不直接顯示原始網頁)
  • RSSReader

匯入OPML效能不好...有的文章讀不到內容~淘汰

  • Sauce Reader

不能提供文章文字內容...直接淘汰

  • FeedReader

會有無法解譯的來源,功能也太陽春了~

這兩個都是以郵件為主,附加RSS訂閱,其中Thunderbird在訂閱時,日期的部份有問題,而且介面不夠友善。而Outlook對我而言有點太大了~

總結

用過各家RSS Reader後,雖然最後的結論是GreatNews,

不過它仍然還有加強的空間,

像是支援網站縮圖與Comment數量~

如果可支援遠端儲存會更好等~

我盡我可能試試我有看到的RSS Reader,當然歡迎大家提供更好的選擇給我~

相關連結

帳號整合開發工具-IDI

最近在研究IBM的Tivoli Directory Integrator (有看到的簡稱為ITDI、TDI或IDI,以下稱IDI),我只能說這個軟體的概念真的很不錯,所以才值得我介紹,但我覺得還有一些問題是實際開發及上線用時才會發現的問題。

另外,其實我研究的主軸是 Tivoli Identity Manager (用來做帳號整合管理的系統),IDI只是它的輔助工具,不過TIM很多功能其實是依賴IDI才能存在,所以先從IDI講起。

姑且暫時不把缺點拿上來談,我試著把我所知道的寫出來看看為什麼我說它是概念不錯的軟體。

老話一句,我不是IBM的員工,所以有些東西不太清楚。

IDI是啥

我引述來自IBM案例網站中的一句話

IBM Directory Integrator(IDI)就是一個基於100% Java技術的目錄元件系統,不但可以跨平台執行,而且其Assembly Line工作模式可以在不匯入一個集中用戶存儲的資料庫的情況下就實現分散式的用戶訊息同步和複雜操作。

可能看完這段話沒什麼感覺,簡單的說IDI可以提供一個開發與運作的工具,讓多個不同平台的使用者資料庫同步或是轉換一個介面讓另一個系統控制。

也就是說,今天無論我原本的系統是用哪家的系統開發,只要是IDI可以連接的對象(relational databases, mail systems, file formats, message queues, web services and a host of other data sources),IDI都要讓你可以與它整合。

圖片引用自Developing a custom TIM agent with TDI

關鍵技術

那麼IDI到底做了什麼事簡化我們的工作呢?

  • 對於現有帳號資料來源:提供各式各樣的連接器(Connector) ,方便存取資料,且設定完的連接器還可再被當父連接器繼承設定,不用寫一堆程式連線唷
    置中
  • 提供了幾種方式讓其他系統能整合:使得我的系統在存取資料來源時,有個固定的介面,而且瑣碎的工作也可交由IDI達成
  • 透過簡單的介面編輯處理流程(Assembly Line):針對取得的資料做名稱的對應與進一步呼叫其他連接器處理
  • 也可以用Javascript撰寫程式,進行資料處理或呼叫其他流程(Assembly Line)

總結

IDI是個中介處理程序的開發工具,不過我不是來賣產品的,只是跟大家說有這樣的東西,概念不錯。

開頭我就有講到但書,這個工具既然屬於開發工具,它的介面也算OK,不過缺點也不少,像是以JavaScript做為程式語言的部份,就充分展現了Javascript沒有編輯時的輔助,一切都要靠經驗與資料才知道怎麼寫才對,偵錯、除錯也很困難。

再者,雖然安裝後有許多小範例,可惜這些範例的解釋資訊不足,基本上要了解不是很簡單,而且我還有遇到範例是有問題的(像是WebService的部份),感覺像是拿前幾個版本的IDI開發範例直接放到新的IDI,不知是不是我自己搞錯了~

另外還有效能與資料來源過大等問題~

與TIM這個主產品整合時,開發要注意的事就更多了~這真是IBM產品的特色呀

相關連結

Tweak UI:讓2003與XP都可自動登入

我之前曾在MS-DOS commands與磁碟定期重組這篇中談到XP懶人開機法,就是能在XP開機時,不用輸入帳號密碼,就能自動登入的方法。

我最近發現連Windows 2003都可以設定自動登入,而最簡單的設定方法就是使用MS自家提供的小工具:Tweak UI

軟體

Tweak UI

  • Version 2.10
  • Windows XP or Windows Server 2003.

方法

  • 首先,到Microsoft PowerToys for Windows XP下載Tweak UI(安裝檔連結)
  • 安裝後,選開始→執行→輸入【Tweakui】
  • 然後會出現如下視窗
  • 選擇Logon→AutoLogon→勾選【Log on automatically at system startup】,並輸入要登入的帳號,點選【Set Password】輸入登入的密碼

  • 點選【Apply】套用設定,這樣就完成了

結論

自動登入是很方便,不過基於安全性考量,如果你的電腦怕被別人碰還是乖乖輸入密碼會比較好~

這個工具XP或2003都可適用,當然XP直接用MS-DOS commands與磁碟定期重組這篇中談到XP懶人開機法就可了。

此外,這個工具也提供了一些原本隱藏的設定讓我們能控制Windows的效果,有興建的人可玩玩看。

相關連結

VMWare與Virtual PC的硬碟減肥法

前陣子看到一本雜誌提到,最近許多企業關注的兩個技術:虛擬化與SOA,

其中的虛擬化指的就是使用虛擬機器來減少設備、管理的成本,而其中我較常聽到的就是VMWareVirtual PC了~

我用VMWare比較多,Virtual PC也是一年前第一次使用,當時因為做教材的關係,花在這上面不少時間,

就發現明明虛擬機器系統中的硬碟就只有幾G,外面實體確是2~3倍,甚至越用越大,這時我才發現不對,於是找半天,總算看到有文章談到了這部份的解決方法。

網路上來找的到很多人談到其他方式,但實際上最正統有用的就只有以下的方法~

VMWare

關於VMWare的硬碟減肥請先參考Vmware磁盤減肥方法

其中的要點如下

  • 打開VMWare,並啟動作業系統
  • 先確定你的虛擬機器的作業系統有沒有裝VMWare Tools(如果還沒裝,相信你應該是新手,請在選單選VM→Install VMWare Tools...)
  • 將系統裡的垃圾文件清理乾淨,然後關閉系統
  • 選擇你的虛擬機器選項下的〞Virtual Machine Settings〞,在跳出視窗的〞Hardware〞,選擇要處理的硬碟(Hard Disk),再點右邊的〞Defragment〞進行碎片整理
  • 碎片整理完成後啟動作業系統
  • 進入系統後點右下角的VMWare Tools圖標會彈出對話框
  • 選點「shrink」
  • 選擇要處理的硬碟,然後就選是,讓它開始處理,中間跳出視窗也選確定,直到它說完成,就可以關閉虛擬的OS

處理會花點時間,不過這樣過後就會減去多餘的部份

Virtual PC

關於Virtual PC的硬碟減肥請先參考如何有效的壓縮虛擬磁盤

其中的要點如下

  • 打開Virtual PC,並啟動作業系統
  • 將系統裡的垃圾文件清理乾淨,並進行磁碟重組
  • 點選Virtual PC選單的CD→Capture ISO Image
  • 選擇Virtual PC安裝路徑下(預設在C:\Program Files\Microsoft Virtual PC)的Virtual Machine Additions子目錄下的Virtual Disk Precompactor.iso
  • 如果沒有自動開啟光碟內容,可到光碟機內選擇開啟precompact.exe
  • 選擇是,開始處理
  • 完成後關閉虛擬的OS,選擇"File"→"Virtual Disk Wizard"
  • 在歡迎話面選Next,然後選"Edit an existing virtual disk", 選Next
  • 然後選擇要處理的硬碟檔案位置
  • 選擇"Compact it"選Next
  • 這時可選擇覆蓋原本的硬碟還是存成新檔
  • 選Next,開始處理

PS.對虛擬硬碟進行壓縮過程中需要保證具有足夠的暫存硬碟空間(大約為兩倍虛擬硬碟文件的大小),否則可能會因為暫存空間不足導致壓縮失敗

總結

這兩個虛擬機器各有千秋,不過就我所知學術界還是用VMWare的人比較多,雖然它要錢,不過支援的環境比較多,但效能或操作性上其實差異不大

我個人最多同時在一台電腦跑兩個虛擬機器就顯得有些吃力了

建議如果你的開發過程常會搞爛作業系統的人,一定要試試這樣的東西,不過前提是你最好有個強力的電腦

相關連結

透過網路讓鍵盤滑鼠在電腦間游走(W2XW與Synergy)

今天在網路上看到有人問(一鼠事二君)他在網路上看到一個影片,看到能夠用一組滑鼠鍵盤在兩台電腦(Windows與Mac)之間游移,如同使用雙螢幕一般。

一鼠事二君下面的回應,還有剛好我學弟玩到的,分別找到兩個軟體(W2XWSynergy),介紹給大家

差異

先說差異,讓大家挑選要先玩哪個(由於我在Windows下試,所以就我使用的感覺而言)

首先就安裝而言,在Synergy需要安裝,而W2XW只要解壓縮就能執行

就設定,Synergy設定步驟較多,也比較麻煩,而W2XW只要設定一兩個東西,就能啟動了

就功能而言,Synergy功能較多,可以設定較多台電腦(按它的設定法,你可以讓電腦把你圍起來操作應該不成問題),而W2XW則比較陽春,但我想一般人用到這樣就夠了

穩定度而言,我沒有詳細測過,但我學弟用W2XW的反應是有些不穩,有Bug

W2XW的設定雖然好設定,不過我懷疑它的安全性,好像很容易讓另一個人控制你的電腦,所以沒在用電腦時建議關掉他

總結而言,如果你第一次完,可以先試W2XW,如果不能用或不滿意穩定度,再試試Synergy

W2XW使用

  • 分別下載軟體到兩台電腦(我下載時的網址是:http://www.h7.dion.ne.jp/~umiumi/w2xw17a.zip),
  • 然後解開來,連接控制的鍵盤滑鼠的主電腦執行"w2xwM.exe"
  • 被控制的電腦執行"W2xwS.exe"
  • 主電腦程式會開啟一個設定視窗,設定如下
    • Switching(hot key)代表在控制時想切掉控制,讓鍵盤回到原電腦的按鈕(程式沒反應時使用),預設是Shift+Alt+Q
    • Switching(mouse)代表被控制的電腦在哪,像我放在右邊,IP是192.168.1.2,就勾Right,並填上IP
    • ClipboardShared代表剪貼簿共用,這樣就能複製文字到令一台電腦了
    • 還有兩個選項我沒試過
  • 完成後,你就可能把滑鼠從主電腦滑到令一台電腦了

Synergy使用

  • 下載安裝檔(我下載時的網址是:http://sourceforge.net/...)
  • 分別在兩台電腦安裝,要知道兩台電腦的名稱,預設是電腦名稱(例如我的主電腦是ALPC被控制電腦是ALNB)
  • 連接控制的鍵盤滑鼠的主電腦ALPC的設定

    • 選擇Share this computer's keyboard and mouse (server)
    • 點選Configure,設定電腦與電腦的關係
      • Screens中,點+,加入兩台電腦的名稱ALPC與ALNB,其他是預設就可
      • Links中,點+,加入兩台電腦的關係,我的ALPC在ALNB左邊的話,要加入2項,加法如下

        • 0 to 100% of the right of ALPC goes to 0 to 100% of ALNB:表示在ALPC中,滑到最右邊就會跑到ALNB
        • 0 to 100% of the left of ALNB goes to 0 to 100% of ALPC:表示在ALNB中,滑到最左邊就會跑到ALPC
    • 點選Hot Keys,設定一個可以讓鍵盤回到原電腦的按鈕
      • Hot Keys,點+,輸入Shift+Alt+Q
      • Actions,點+,選Switch to Screen,然後選主電腦ALPC
    • 點Start,啟動服務
  • 被控制電腦ALNB的設定

    • Use another computer's shared keyboard and mouse (client)
    • 然後輸入另一台電腦的名稱ALPC
    • 你可以用Test測試一下連不連的到
    • 選Start起動
  • 完成後,你就可能把滑鼠從主電腦滑到令一台電腦了

結論

強烈建議重視安全的人使用Synergy,反正麻煩一下而已,但說真的,W2XW比較有小巧易用的感覺

我還滿喜歡這樣的功能的,所以才會寫這篇,如果有問題或建議再跟我說吧~

參考資料

用 Psiphon 突破網站封鎖

有個來自對岸的聲音問我,他們那裡沒辦法連到一些特定的網站,例如維基百科...等網站

所以我那天看到這個軟體就當場跟對岸的聲音試了一下

PS.除了自己架,網路上也有些網站提供類似服務,請參考最後的相關連結,如果大家有類似的東西也請回應給我

軟體簡介

簡單來說,就是在一個可以存取特定網站的電腦,執行這個軟體,他會架起一個網頁伺服器,讓想上網站的人登入後,可以將特定網站的內容再交給登入的人。

使用方法

  • 安裝軟體後,啟動程式,他會先測試預設的https網站要用的port:443是否被使用中(如果有架網頁伺服器就可能會在使用中)
  • 點選Setup可以設定使用的Port,不過被封鎖的電腦通常也只有公用的port能存取,所以建議還是盡量使用443
  • 點選add,設定帳號密碼以供使用者登入,使用者可以透過網站自己修改密碼
  • 要進入網站的網址可以在Setup中複製,如https://127.0.0.1:443/login/
  • 點選Start,則視窗名稱會顯示狀態為ON,表示服務已啟動
  • 使用者進到網站登入後,可以看到網站顯示了一個可以輸入網址的對話框,在那輸入你想去的網站就行了

參考資料

安裝WBMonitor 6.0.1

老話~我不是IBM官方人員,所以只能從"多"次失敗經驗中,找出結果~

目前本篇還在修訂中~

WebSphere Business Monitor是IBM BDD Solution中的一環,用來監控、收集SOA的Process執行結果,藉此資料做為Process改進的資訊

我前目前是採用information center中的第二種安裝架構(Second scenario),不過我發現如果要符合某些範例,最好把Monitor Server與DB Server放在一起,方便練習

安裝環境

根據IBM的說明,要安裝在Windows Server上,所以我用Windows 2000 Advance Server

我後來又試了用XP安裝,他會警告你這樣安裝只能測試,不足以當真正的產品服務,我要試試才能知道會有什麼結果

注意事項

使用Monitor的 Launchpad 安裝,所以有些設定必須按照它的規定

  • 安裝時,各個需安裝的元件必需放在指定資料夾(請參考)
  • Windows的電腦名稱必須不大於8個字,至 控制台→系統→網路識別→內容 修改
  • 用 Launchpad 安裝 DB2 前系統中不能有db2admin的帳號,否則會安裝失敗
  • DB2安裝後要關掉所有的視窗,然後再重新啟動Launchpad

安裝過程摘要記錄

Monitor DB Server(請參考)&Monitor Server(請參考)

  • 電腦名稱:WBMS1
  • 安裝J2RE 1.4.2
  • 執行Monitor Launchpad,選擇【建立資料庫】
  • 安裝DB2 8.2.1,後關掉Monitor Launchpad,執行"db2start"指令
  • 執行Monitor Launchpad
  • 安裝Cube View 8.2.1
  • 安裝Monitor DB-State、Repository、Runtime、Historical 安裝完DB Server的所有東西大約花了我一個半小時(不含作業系統)
  • 選擇【安裝產品】→【監控伺服器】
  • 安裝Process Server 6.0.0,此時會要求輸入CEI資料庫的帳戶資料,用DB2的帳號密碼 這個動作大約會花45分鐘
  • (如果要分開安裝DB與監視伺服器,要先設定DB2 Control Center,加入 WBMDB1中的DB到資料庫伺服器清單中,方法下面會有)
  • 安裝監控伺服器 雖然文件上說這步只要安裝45分鐘,但我安裝了約一個半小時

Monitor Server安裝驗證

文件中有些驗證步驟,我有空再補上

Monitor Dashboard Client(請參考)

  • 電腦名稱:WBMD1
  • 安裝J2RE 1.4.2
  • 執行Monitor Launchpad,選擇【安裝產品】→【監視儀表】
  • 安裝DB2 8.2.1,後關掉Monitor Launchpad,執行"db2start"指令
  • 執行Monitor Launchpad
  • 安裝Cube View 8.2.1
  • 安裝WAS 6.0.2.3
  • 安裝Portal 5.1.0.2
  • 安裝DB2 Alphablox 8.3
  • 使用DB2 Control Center,加入 WBMDB1到資料庫伺服器清單中
    • 在DB2 Control Center中,右鍵選擇【All Databases】→【Add】
    • 輸入Hostname:WBMS1
    • 點選Search後,下方會列出資料庫有哪些
    • 分別選擇 Repository、Runtime、Historical,點選【Apply】就會加入到資料庫伺服器清單中
  • 安裝儀表板客戶端
    • 這裡還要輸入許多Portal還有Process server的資訊 整個Dashboard Client的安裝相當耗時間,大約要7小時以上吧(我已經等到懶得仔細算了,要不是有人逼我,我大概灌一次失敗就放棄了...)

Monitor Dashboard Client安裝驗證

文件中有些驗證步驟,我有空再補上

Monitor Server 與Process Server的SIB連結設定

文件中有些ㄕ步驟,我有空再補上

參考資料

安裝完Windows後常用工具整理

系統與文書

  • MS-Office 雖然想用用看open的,不過學校還是以此為主,加上沒時間學,所以不得不用這個
  • UltraEdit 老牌編輯工具,要註冊,但好用
  • ConvertZ 簡體繁體轉換工具,可以轉換檔名、檔案內容、剪貼簿...等
  • WinRAR 壓縮軟體
  • Unlocker(英文軟體) 有時刪檔刪不了,又不知啥程式開著它,就用這軟體試試吧(教學)
  • Process Explorer 進階版工作管理員,它允許使用者在所提供的視窗中觀看每一個程序的原始所在位址、佔用記憶...找出有沒有後門程式
  • Adobe Acrobat 雖然曾經用過一個免費的PDF讀取工具叫Foxit PDF Reader,不過我上次用時,覺得開的快,有些功能卻有問題,例如複製、搜尋等~所以還是用這個
  • Daemon Tools(英文軟體有中文化) 不能產生光碟的映像檔,但能讀取的免費軟體,很多人都用這個唷(Daemon Tools 的使用教學)
  • FastCopy(英文軟體有中文化) 我個人常用的複製檔案軟體,有人問我真的快嗎?我也不知,不過有一點可以肯定的~他能幫我做到輕鬆的排程複製,這樣硬碟磁頭就不會跳來跳去了
  • Total Copy(英文軟體有中文化) 說到複製,另一個能夠續傳、限制速度的複製軟體就是這個了,區網複製時很好用
  • MDIE(英文軟體有中文化版) 瀏覽器與檔案總管工具,可取代Windows內建檔案總管,重點是支援分頁與滑鼠手勢(中文版下載網址)
  • freeCommander(英文軟體有官方中文語言檔) 管理檔案用的,一次處理兩個資料夾(可同步),可惜只支援電腦內的磁碟機,不能用網芳
  • Nero 燒錄軟體,雖然要買,不過很多燒錄器會附上
  • FinalBurner (英文軟體) 免費的燒錄軟體,功能還算完整,可燒CD、DVD、音樂、影片...等,我最近才看到,還沒有仔細研究,這家軟體公司還有出了其他免費的相關軟體
  • Ignition 燒錄檔案不浪費,能夠幫使用者最佳化光碟儲存的工具軟體,不過要燒時要搭配他們家的付費軟體,所以我當計算軟體用
  • CD Index CD內容管理,幫你建你的CD索引庫
  • ATnotes 桌面便利貼,可定時提醒唷
  • Birthday(英文軟體) 生日提醒器,管理我朋友的生日

影音相關

網路工具

  • Firefox & KKFox Firefox是由Mozilla所提供免錢的瀏覽器,同時也提供很多聰明且方便的擴充套件;KKFox以FireFox為核心,把常會用到的外掛都放上去了
  • Windows Live Messenger 我想不用多做說明吧
  • SharpReader(英文) & GreatNews(多國含中文) & RSSOwl(多國含中文)

    RSS 的讀取器。(請參考 比較7個RSS Reader與GreateNews使用教學)

  • FlashGet 越做功能越多的下載軟體,以前收費,現在也變免費軟體了,最新版還支援BT下載。
  • BitComet BT的下載工具,還滿容易用的
  • eMule P2P軟體
  • CuteFTP & FileZilla CuteFTP是要付錢的FTP Client,但牌子老,功能完整。也可以用不用錢的FileZilla,也還滿好用的
  • POP Peeper 新郵件來系統列就會有圖示改變, 除了支援POP3外,還囊括了較知名的 Hotmail 、 MSN 、 Yahoo 、 Gmail 等
  • TCPView 微軟旗下某部門提供的工具,幫你看看你電腦有哪些人與你連線,架站的人一定要試試
  • NetSetMan(英文軟體) 切換網路設定,將網路設定值儲存起來,再在需要的時候,再呼叫出某一特定已儲存的網路設定值
  • VDownloader(英文軟體) 可以針對Google VideoYoutubeDailyMotio 等網站的FLV影片,下載與轉檔(AVI或Mpg),一次搞定。
  • RapGet 能夠下載存放於 RapidShare 、 mytemp 、 turboupload...等數十個知名的免費空間上的檔案
  • JWGet 抓圖機,無名、Xuite、PCHOME、YAHOO正妹相簿一次抓下來
  • PicaLoader 更進階的抓圖機,不過要錢唷

安裝IBM BDD開發環境

我不是IBM官方人員,所以只能從"多"次失敗經驗中,找出結果~

目前本篇還在修訂中~

歡迎有興趣的人可以一起討論。

BDD簡介

BDD(Business Driven Development)是IBM提出的一套為SOA系統而定的開發流程

所有工具中,與實作有直接關聯的包括

  • WBM(WebSphere Business Modeler)
  • RSA(Rational Software Architect)
  • WID(WebSphere Integration Developer)

PS. 其實還有RAD,但RSA已包含RAD的功能,所以不再安裝RAD

安裝重點

我以我手頭拿到的版本為例 (IBM的東西,版本是重點)

我現在手頭有

  • WBM 6.0.1 Advance
  • RSA 6.0
  • WID 6.0.1

步驟

  • 先安裝RSA:因為它是6.0,其他兩個是6.0.1,所以要先安裝它,路徑盡量短,而且不要有空白(這是IBM工具安裝原則)
  • 升級RSA到6.0.1.1:如果已下載更新檔,可開啟Rational Product Updater→喜好設定→更新網站,然後找到你下載的更新描述檔,會比較快完成,但還是要連上網路唷
  • 完成後請確定WAS6.0測試環境是否能啟動,不能啟動就是安裝失敗,有種原因可能是安裝來源檔有問題
  • PS(先不要上fix,我目前看到已經出到fix003,但上fix對WID的安裝可能會有影響)
  • 安裝WID:這裡是重點,路徑不可與RSA重覆(預設是相同的路徑)
  • 更新WID到6.0.1.2
  • 完成後請確定WPS6.0測試環境是否能啟動,不能啟動就是安裝失敗,有種原因可能是安裝來源檔有問題
  • 安裝WBM

如果你想要直接用RSA開發WBM的部份,按照Information center中描述我沒辦法用,但我找出了其他方式

以下是方法

  • 開啟WID或RSA
  • 按一下說明 > 軟體更新 > 搜尋並安裝 此時會開啟「安裝」精靈。
  • 選取搜尋要安裝的新功能,然後按下一步。
  • 在「更新要造訪的站台」頁面,按一下新的本端站台。 此時會開啟「瀏覽資料夾」視窗。
  • 在「瀏覽資料夾」視窗中,找到你安裝WBM的路徑
  • 選擇其中的eclipse資料夾
  • 選取您剛才新增的站台,然後按下一步。
  • 在「搜尋結果」頁面,選取跟Modeler相關的功能(如果有衝突的部份就不要選)。
  • 按下一步。
  • 在「功能授權」頁面,閱讀您要安裝之每個功能的授權合約。讀完後按一下我接受授權合約中的條款以接受合約,然後按下一步。
  • 在「安裝位置」頁面,針對您要安裝的每個功能選取一個資料夾作為目標站台。 建議您建立一個新資料夾來存放 WebSphere Integration Developer 功能。
  • 按一下新增站台。 此時會開啟「瀏覽資料夾」視窗。
  • 瀏覽至安裝 WebSphere Integration Developer 的資料夾,然後按一下新增資料夾。
  • 建立新資料夾後,將其名稱變更為 modeler。
  • 請確定已選取新資料夾,然後按一下確定返回精靈。 新資料夾會顯示為可用的站台清單中的一個選項。
  • 為要安裝的功能清單中的每個功能指定新站台後,按一下完成。
  • 註: 您必須分別指定每個功能的目的地,方法是按一下該功能,然後指定目的地站台。
  • 安裝期間會開啟「Jar 驗證」視窗。按一下安裝以繼續安裝未經數位簽章的功能。
  • 當詢問您是否想要重新啟動工作台以讓變更生效時,請按一下是。

參考資料

這裡是關於技術的手札~

也歡迎大家到

倫與貓的足跡



到噗浪來

關心一下我唷!
by 倫
 
Copyright 2009 倫倫3號Beta-Log All rights reserved.
Blogger Templates created by Deluxe Templates
Wordpress Theme by EZwpthemes