2009年5月10日 星期日

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

序言

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

PS.我實際測試下有的網頁用HttpRequest取的到正確的結果,有的則用WebClient才取的到,所以這個函式可能不夠通用,不過還是可以做為參考

開發環境

  • VB.Net 2.0 (VS2005)

專案設定

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

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

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

網頁原始碼函式類別

Imports System.Net
Imports System.io
''' <summary>
''' 網頁原始碼取得函式
''' </summary>
''' <remarks>網頁原始碼取得函式By allen080.blogspot.com</remarks>
Public Class WebPageGenFunc
''' <summary>
''' 使用Get方法取得網頁內容
''' </summary>
''' <param name="url">網址</param>
''' <param name="noCashe">不使用快取</param>
''' <returns>網頁的HTML</returns>
''' <remarks>使用Get方法取得網頁內容By allen080.blogspot.com</remarks>
Public Shared Function getHTMLGet(ByVal url As String, Optional ByVal noCashe As Boolean = False) As String
getHTMLGet = Nothing
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.0b; Windows NT 5.1)"
.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方法取得網頁內容By allen080.blogspot.com</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
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.0b; Windows NT 5.1)"
.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取得網頁內容By allen080.blogspot.com</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
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")
End If
myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded")
myWebClient.Headers.Add("Accept-Language", "zh-tw")
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區段By allen080.blogspot.com</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) 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
html = getHTMLGet(url, noCashe)
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中第一個符合的標籤內容的指標,並將取得的標籤內容寫入參數中By allen080.blogspot.com</remarks>
Public Shared Function getHTMLTagContain(ByRef html As String, ByVal tag As String, Optional ByRef contain As String = Nothing, Optional ByRef indexEnd As Integer = -1) As Integer
contain = Nothing
indexEnd = -1
Dim indexbBegin As Integer = -1
If Not html Is Nothing Then
indexbBegin = html.IndexOf("<" & tag)
If indexbBegin > -1 Then
indexbBegin = html.Substring(indexbBegin).IndexOf(">") + indexbBegin + 1
Dim indexbEnd As Integer = html.Substring(indexbBegin).IndexOf("</" & tag & ">") + indexbBegin
If indexbEnd > -1 + indexbBegin Then
indexEnd = indexbEnd
contain = html.Substring(indexbBegin, indexbEnd - indexbBegin)
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中第一個符合的標籤屬性的指標,並將取得的標籤內容與該屬性內容寫入參數中By allen080.blogspot.com</remarks>
Public Shared Function getHTMLTagAtt(ByRef 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
indexEnd = -1
Dim indexbBegin As Integer = -1
Dim indexaBegin As Integer = -1
If Not html Is Nothing Then
indexbBegin = html.IndexOf("<" & tag)
If indexbBegin > -1 Then
Dim indexbEnd As Integer = html.Substring(indexbBegin).IndexOf(">") + indexbBegin
If indexbEnd > -1 + indexbBegin Then
indexaBegin = html.Substring(indexbBegin, indexbEnd - indexbBegin).Replace("'", """").IndexOf(attName & "=""") + indexbBegin + (attName & "=""").Length
If indexaBegin > -1 + indexbBegin Then
Dim indexaEnd As Integer = html.Substring(indexaBegin).Replace("'", """").IndexOf("""") + indexaBegin
If indexaEnd > -1 + indexaBegin Then
att = html.Substring(indexaBegin, indexaEnd - indexaBegin)
End If
End If
End If
indexbBegin = indexbEnd + 1
indexbEnd = html.Substring(indexbBegin).IndexOf("</" & tag & ">") + indexbBegin
If indexbEnd > -1 + indexbBegin Then
indexEnd = indexbEnd
contain = html.Substring(indexbBegin, indexbEnd - indexbBegin)
End If
End If
End If
Return indexaBegin
End Function
''' <summary>
''' Url參數值編碼
''' </summary>
''' <param name="value">參數值</param>
''' <returns>編碼結果</returns>
''' <remarks>Url參數值編碼By allen080.blogspot.com</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參數值解碼By allen080.blogspot.com</remarks>
Public Shared Function getDecodeStr(ByVal value As String)
Return Web.HttpUtility.UrlDecode(value)
End Function
End Class

使用範例程式

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

'使用WebClient的Post方法取得資料
url = "http://msdn.microsoft.com/zh-tw/library/cc983670.aspx"
Dim searchStr As String = "倫倫3號"
Dim postdata As New Specialized.NameValueCollection
postdata.Add("__EVENTTARGET", "")
postdata.Add("__EVENTARGUMENT", "")
postdata.Add("__VIEWSTATE", "/wEPDwUBMGQYAgUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgYFImN0bDAwJE1hc3RoZWFkMSRjdGwwMCRTZWFyY2hCdXR0b24FImN0bDAwJFdpa2lDb250ZW50JEVkaXRvciRSYWRFZGl0b3IFR2N0bDAwJFdpa2lDb250ZW50JEVkaXRvciRjdGwwMF9XaWtpQ29udGVudF9FZGl0b3JfUmFkRWRpdG9yZGlhbG9nT3BlbmVyBU5jdGwwMCRXaWtpQ29udGVudCRFZGl0b3IkY3RsMDBfV2lraUNvbnRlbnRfRWRpdG9yX1JhZEVkaXRvcmRpYWxvZ09wZW5lcl9XaW5kb3cFI2N0bDAwJFdpa2lDb250ZW50JEVkaXRvciRSYWRUb29sdGlwBR5jdGwwMCRXaWtpQ29udGVudCRFZGl0b3IkY3RsMDAFL2N0bDAwJE1hc3RoZWFkMSRVc2VyUmVjb2duaXRpb25GbHlvdXQkbG9naW5WaWV3Dw9kAgFkTR/9R2uARDjXggFEm6e0WaTZWHE=")
postdata.Add("ctl00$Masthead1$ctl00$SearchTextBox", searchStr)
postdata.Add("ctl00$Masthead1$ctl00$WebButton", "Web")
postdata.Add("go", "true")
htmlBody = WebPageGenFunc.getHTMLBody(url, , postdata)
indexEnd = htmlBody.IndexOf("<span class=""sb_count""")
If indexEnd > 0 Then
htmlBody = htmlBody.Substring(indexEnd)
'取得a標籤1的內容
WebPageGenFunc.getHTMLTagContain(htmlBody, "span", valueContain, indexEnd)
Console.WriteLine("使用WebClient的Post方法取得資料: " & valueContain)
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)
indexEnd = htmlBody.IndexOf("<span class=""sb_count""")
If indexEnd > 0 Then
htmlBody = htmlBody.Substring(indexEnd)
'取得a標籤1的內容
WebPageGenFunc.getHTMLTagContain(htmlBody, "span", valueContain, indexEnd)
Console.WriteLine("使用WebRequest的Post方法取得資料: " & valueContain)
End If

執行結果

a標籤1的內容: [程式]VB.Net2.0資料庫通用存取函式
a標籤2的內容與href的屬性: http://allen080.blogspot.com/2009/04/vbnet20.html ,內容:<abbr class='published' title='2009-04-20T22:25:00-07:00'>下午 10:25</abbr>
使用WebClient的Post方法取得資料: 第 1-9 筆,共 159 筆搜尋結果
使用WebRequest的Post方法取得資料: 第 1-9 筆,共 159 筆搜尋結果

相關連結

2009年4月20日 星期一

[程式]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
''' <summary>
''' 資料庫通用存取函式
''' </summary>
''' <remarks>資料庫通用存取函式By allen080.blogspot.com</remarks>
Public Class DBGenFunc
''' <summary>
''' 由設定檔取得資料庫連結字串
''' </summary>
''' <param name="connName">連結字串名稱</param>
''' <returns>連結字串</returns>
''' <remarks>取得設定檔(app.config)中的連結字串(connectionStrings)By allen080.blogspot.com</remarks>
Public Shared Function getConnStr(ByVal connName As String) As String
Return ConfigurationManager.ConnectionStrings(connName).ConnectionString
End Function
''' <summary>
''' 取得SqlConnection物件
''' </summary>
''' <param name="connName">連結字串名稱</param>
''' <returns>SqlConnection物件</returns>
''' <remarks>以連結字串名稱由設定檔取得資料庫連結字串,建立SqlConnection物件</remarks>
Public Shared Function getConn(ByVal connName As String) As SqlConnection
Return New SqlConnection(getConnStr(connName))
End Function
''' <summary>
''' 取得連結字串中的資料庫名稱
''' </summary>
''' <param name="connName">連結字串名稱</param>
''' <returns>資料庫名稱</returns>
''' <remarks>從連結字串名稱找出Initial Catalog所標示的預設連線資料庫名稱By allen080.blogspot.com</remarks>
Public Shared Function getDBName(ByVal connName As String) As String
getDBName = String.Empty
Dim ConnString As String = getConnStr(connName)
Dim i As Integer = ConnString.IndexOf("Initial Catalog=")
If i > -1 Then
getDBName = ConnString.Substring(i + "Initial Catalog=".Length)
i = getDBName.IndexOf(";")
If i > -1 Then getDBName = getDBName.Substring(0, i)
End If
Return getDBName
End Function
''' <summary>
''' 取得執行SQL後的資料表
''' </summary>
''' <param name="connStr">連結字串</param>
''' <param name="sql">要執行的SQL</param>
''' <param name="param">傳入SQL的參數</param>
''' <returns>資料表</returns>
''' <remarks>取得執行SQL後的資料表By allen080.blogspot.com</remarks>
Public Shared Function getTable(ByVal connStr As String, ByVal sql As String, Optional ByRef param() As SqlParameter = Nothing) As Data.DataTable
Dim cn As New SqlConnection(connStr)
Dim cmd As New SqlCommand
Dim da As New SqlClient.SqlDataAdapter(sql, cn)
Dim ex As Exception = Nothing
If Not param Is Nothing Then da.SelectCommand.Parameters.AddRange(param)
da.SelectCommand.CommandTimeout = 36000000
Dim dt As New Data.DataTable("dt_xml")
Try
cn.Open()
da.Fill(dt)
Catch ex
Console.WriteLine(ex)
Finally
If cn.State = ConnectionState.Open Then cn.Close()
End Try
If Not ex Is Nothing Then Throw ex
Return dt
End Function
''' <summary>
''' 將DataTable的某欄資料輸出為陣列
''' </summary>
''' <typeparam name="TOutput">陣列型別</typeparam>
''' <param name="dt">資料表</param>
''' <param name="cindex">第幾個欄位</param>
''' <returns>陣列</returns>
''' <remarks>將DataTable的某欄資料輸出為陣列</remarks>
Public Shared Function dataTableToArray(Of TOutput)(ByRef dt As DataTable, ByVal cindex As Integer) As TOutput()
Dim dr(dt.Rows.Count - 1) As DataRow
dt.Rows.CopyTo(dr, 0)
cellIndex = cindex
Return Array.ConvertAll(dr, New Converter(Of DataRow, TOutput)(AddressOf DataRow0ToObject))
End Function
Private Shared cellIndex As Integer = 0
Private Shared Function DataRow0ToObject(Of TOutput)(ByVal dr As DataRow) As TOutput
Return dr(cellIndex)
End Function

Private Shared cn As SqlConnection
Private Shared reader As SqlDataReader
''' <summary>
''' 取得執行SQL時的DataReader
''' </summary>
''' <param name="connStr">連結字串</param>
''' <param name="sql">要執行的SQL</param>
''' <param name="param">傳入SQL的參數</param>
''' <returns>執行SQL時的DataReader</returns>
''' <remarks>取得執行SQL時的DataReader,呼叫此函式後使用DataReader完畢必須呼叫closeReader()以關閉連線By allen080.blogspot.com</remarks>
Public Shared Function getReader(ByVal connStr As String, ByVal sql As String, Optional ByRef param() As SqlParameter = Nothing) As SqlDataReader
cn = New SqlConnection(connStr)
Dim cmd As New SqlCommand
Dim ex As Exception = Nothing
cmd.Connection = cn
cmd.CommandText = sql
If Not param Is Nothing Then cmd.Parameters.AddRange(param)
cmd.CommandTimeout = 36000000
Try
If cn.State = ConnectionState.Closed Then cn.Open()
reader = cmd.ExecuteReader()
Catch ex
Console.WriteLine(ex)
End Try
If Not ex Is Nothing Then Throw ex
Return reader
End Function
''' <summary>
''' 搭配getReader()使用,用以關閉連線
''' </summary>
''' <remarks></remarks>
Public Shared Sub closeReader()
If Not cn Is Nothing And Not reader Is Nothing Then
Dim ex As Exception = Nothing
Try
reader.Close()
Catch ex
Console.WriteLine(ex)
Finally
If cn.State = ConnectionState.Open Then cn.Close()
End Try
If Not ex Is Nothing Then Throw ex
End If
End Sub
''' <summary>
''' 執行SQL命令
''' </summary>
''' <param name="connStr">連結字串</param>
''' <param name="sql">要執行的SQL</param>
''' <param name="param">傳入SQL的參數</param>
''' <returns>傳回受影響資料列筆數</returns>
''' <remarks>執行SQL命令,傳回受影響資料列筆數By allen080.blogspot.com</remarks>
Public Shared Function doCmd(ByVal connStr As String, ByVal sql As String, Optional ByRef param() As SqlParameter = Nothing) As Integer
Dim cn As New SqlConnection(connStr)
Dim cmd As New SqlCommand
Dim ex As Exception = Nothing
Dim result As Integer = 0
cmd.Connection = cn
cmd.CommandText = sql
If Not param Is Nothing Then cmd.Parameters.AddRange(param)
cmd.CommandTimeout = 36000000
Try
cn.Open()
result = cmd.ExecuteNonQuery()
Catch ex
Console.WriteLine(ex)
Finally
If cn.State = ConnectionState.Open Then cn.Close()
End Try
If Not ex Is Nothing Then Throw ex
Return result
End Function
''' <summary>
''' 執行SQL取得單一值結果
''' </summary>
''' <param name="connStr">連結字串</param>
''' <param name="sql">要執行的SQL</param>
''' <param name="param">傳入SQL的參數</param>
''' <returns>單一值結果</returns>
''' <remarks>執行SQL命令,傳回單一值結果By allen080.blogspot.com</remarks>
Public Shared Function doCmdScalar(ByVal connStr As String, ByVal sql As String, Optional ByRef param() As SqlParameter = Nothing) As Object
Dim cn As New SqlConnection(connStr)
Dim cmd As New SqlCommand
Dim ex As Exception = Nothing
Dim result As Object = Nothing
cmd.Connection = cn
cmd.CommandText = sql
If Not param Is Nothing Then cmd.Parameters.AddRange(param)
cmd.CommandTimeout = 36000000
Try
cn.Open()
result = cmd.ExecuteScalar()
Catch ex
Console.WriteLine(ex)
Finally
If cn.State = ConnectionState.Open Then cn.Close()
End Try
If Not ex Is Nothing Then Throw ex
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

2009年3月12日 星期四

[筆記]我的FireFox愛用套件

序言

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

清單

  1. FireFox主程式(我都用Portable版不用安裝):
    by OpenOffice.org Portable非公式正體中文版
    by 簡單生活Easylife
  2. Foxmarks官網。書籤同步,可至官網直接登入瀏覽你的書籤。
  3. All-in-One Gestures官網。滑鼠手式(控制上一頁下一頁等)。
  4. Easy DragToGo官網。用拖曳手勢更容易地在新分頁裡打開連結、搜尋文字和儲存圖片。
  5. 新同文堂官網。中文繁簡體互轉工具。
  6. Tab Mix Plus官網。分頁加強版。
  7. Greasemonkey官網。客製化網頁Script功能。搭配以下Script。
  8. FlashGot官網。搭配其他下載工具用。
  9. PCmanfx官網。上BBS。
  10. Profile Manager and Synchronizer :多帳號登入。

2008年12月6日 星期六

[教學]設定MSN防毒為小紅傘

序言

不想廢話(這篇應該是目前我在這個Blog最短的一篇文章),總之這樣設定MSN(Live Messenger)傳檔案時就會用小紅傘(Avira AntiVir)掃毒。

步驟

  1. 於MSN的【工具】→【選項】→【檔案傳輸】勾選【使用下列軟體進行病毒掃描】
  2. 在下面的路徑欄位填上:
    "C:\Program Files\AntiVir PersonalEdition Classic\avscan.exe" /GUIMODE=2 /PATH=%FILE%

2008年10月25日 星期六

[教學]重灌/換主機板超好用技術-MergeIDE

序言

雖然廢話一堆的教學文章是不行的~不過我還是習慣開場說說我研究這個免重灌的原因~

就是當每天都有修不完的電腦~而且還每台都要做差不多的設定與軟體安裝後~

我就開始想找出可以不用每次都重灌的方法~

最終試的結果就是用我下面談的MergeIDE來設定囉~

當然,這個方法也可以用在換電腦時,不過我在下面第一步就回提到換電腦時用這個方法不一定會成功的原因。

工作大綱

  1. 挑電腦來安裝Windows
  2. 將Windows該裝軟體該設定的都弄好
  3. 刪掉不必要的檔案(非必要)
  4. 進裝置管理員變更電腦與匯流排驅動為標準,並刪除不必要裝置
  5. 執行MergeIDE,並覆蓋4個IDE硬體驅動檔
  6. 關機後即可製作Ghost檔(非必要)
  7. 在新電腦開機後,更新第一個標準電腦的驅動再重新開機
  8. 安裝新電腦的驅動
  9. 關機後再製作Ghost檔(非必要)

1.挑電腦來安裝Windows

這時候又要廢話一下了~為什麼要挑電腦勒?

因為根據我手邊供我試驗的很多很多台電腦的使用經驗,

A主機板所安裝的Windows使用MergeIDE法可使轉移到B主機板運作時,

B主機板所安裝的Windows卻不一定能以同樣方式轉移到A主機板~

因此,挑主機板就十分運氣了~

以我為例,我目前挑到相容性最高的主機是HP Compaq dc5750的套裝主機,它內建的是AMD64位元的CPU~

但我建議如果沒有很多主機可以試,也可以試試使用VMWare建立雙CPU的虛擬主機來裝Windows,效果可能也不錯~

2.將Windows該裝軟體該設定的都弄好

這不用說,當然就是裝上各電腦你需要的軟體與設定~

也可以把所有的更新更新完(手動下載更新檔可參考 下載Windows更新檔的工具by EcStart PHP 技術討論論壇)

3.刪掉不必要的檔案(非必要)

因為要減小Ghost後的大小,可以刪除些非必要的檔案:

  • 到【控制台】→【系統】→【系統還原】把系統還原關閉。
  • 清除系統文件保護暫存檔,以命令提示字元執行【sfc.exe /purgecache】

4.進裝置管理員變更電腦與匯流排驅動為標準,並刪除不必要裝置

  • 【開始】→【執行】→輸入【devmgmt.msc】/或至【控制台】→【系統管理工具】→【電腦管理】,開啟【裝置管理員】
  • 展開【IDE ATA/ATAPI控制器】分類,如果裡面的IDE控制器不是【標準的雙通道 PCI IDE控制器】,請更新驅動為標準的雙通道 PCI IDE控制器。以右鍵點選IDE控制器的【更新驅動程式】,在打開的【硬體更新精靈】裡選【從列表或指定位置安裝(進階)】選項,並選【不要搜索,我要自己選擇要安裝的驅動程式】,然後選【雙通道 PCI IDE控制器】。再選【否】不重開機。
  • 展開【電腦】分類,以右鍵點選ACPI選【更新驅動程式】,在打開的【硬體更新精靈】裡選【從列表或指定位置安裝(進階)】選項,並選【不要搜索,我要自己選擇要安裝的驅動程式】,然後選【標準電腦】(Standard PC)
  • 同上述方法將【處理器】分類下的CPU改為【處理器】
  • 刪除其他普通驅動程式,如網絡介面卡,滑鼠右鍵單擊其下的網路設備名稱,在彈出菜單上單擊【解除安裝】選項,再用類似的方法卸載通用序列匯流排控制器、音效視訊遊戲控制器、顯示卡、音效卡等設備驅動程式。這裡要注意的是,如果系統提示需要重新啟動,一定【不要】重啟機器

5.執行MergeIDE,並覆蓋4個IDE硬體驅動檔

將 Windows XP 系統磁片移到另一部電腦之後,收到 Stop 0x0000007B 錯誤(By Microsoft技術支援服務)

這篇文章就可以看到MergeIDE檔的製作方式,網路上也有人用批次檔寫說可以直接將windows裡面的4個IDE硬體驅動檔複製出來用的方法。

而我這邊比較偏好直接用下載後的4個IDE硬體驅動檔來覆蓋,因為有的Windows會找不到這四個檔的原始檔。

我將所有需要的檔案與解壓縮路徑預設好,只要下載Winxpsys執行就可以了。

6.關機後即可製作硬碟映象檔(非必要)

這個映像檔理論上在新電腦就可以用了,不過如同第1部所言,這要看運氣。

7.在新電腦開機後,更新第一個標準電腦的驅動再重新開機

開機後他會開始裝各硬體的驅動程時,如果中間有跳出要求驅動程式的視窗,直接取消不用理他~

因為下一步驟重開後他還是會再重新裝一次驅動程式。

  • 【開始】→【執行】→輸入【devmgmt.msc】,開啟 裝置管理員
  • 展開【電腦】分類,會有兩個標準電腦。以右鍵點選第一個標準電腦,選【更新驅動程式】,依直按下一步讓它安裝適合這台電腦的ACPI
  • 重新開機

8.安裝新電腦的驅動

到裝置管理員移除第二個標準電腦,並且安裝所有這台電腦的驅動後,就完成移機了。

9.關機後再製作硬碟映象檔(非必要)

為什麼之前做過硬碟映象,現在又做一次?

根據我的試驗,這時候的作業系統就變成拿到別台還是能開機來用,所以感覺很像能到處使用,不過我還沒能完整驗證。

所以大家有興趣可以直接拿這個版本的映像檔來玩玩看,就可以再少掉每次到新電腦還要作第7步的動作了。

結論

如前面所言,這是我試過n台電腦後的結果,歡迎大家告訴我更好的做法~

我想這個技術對好人卡收很多的人也有用~哈哈~

相關連結