七月 20

在SQL Server 2005中建View時如果你是用介面幫你產生的

應該會是像下面的指令碼一樣


SELECT     TOP (100) PERCENT MsgText
FROM         dbo.RouterOS_All
ORDER BY MsgDateTime DESC

當View建好了,也存檔了之後,再把View開起來

你會發現其實這個View並沒有依照我們的意思Order by

而解決問題的方法就是不要使用PERCENT,改用一個數值很大的值


SELECT     TOP (2147483647) MsgText
FROM         dbo.RouterOS_All
ORDER BY MsgDateTime DESC

這樣子就正常了。至於這是不是個Bug,我想就只能問MS了

測試環境:
SQL Server 2005 Express with SP3
Windows 2008 Std with SP1 x86

參考資料:
SQL Server 2005 Ordered View and Inline Function Problems





七月 17

如果你於RouterOS中使用負載平衡時,你會發現要從RapidShare下載檔案有很大的機會失敗

這是因為當你第1次連到RapidShare上的IP,然後等完看廣告的時間之後要下載檔案的IP不一樣所造成的

舉個例來說,假設第1次連上到RapidShare上的IP是123.1.1.1,但是要下載檔案時

因為負載平衡的關係,使得本次連到RapidShare 的已經變成123.1.1.2

這時就會發生無法下載的情況。

最簡單的解決方式就是,把要連到RapidShare上的連線全部走同1條線路

那麼要怎麼判斷那些連線是要到RapidShare的呢

就是看RouterOS DNS快取裡的Doman與IP的對照表

這個時候就需要使用Script來自動把RapidShare相關的IP濾出來,放到Address List供我們使用

相關的Script如下。新增Script的方式為到Winbox裡 System -> Scripts -> 按介面上的 +

把下面這個Script命名為 Update_RapidShare_IP ,後面會用到

# 把DNS快取裡資料全部讀出來
:foreach i in=[/ip dns cache find] do={
    :local bNew "true";
# 檢查DNS快取裡是否有包含rapidshare的關鍵字
    :if ([:find [/ip dns cache get $i name] "rapidshare"] != 0) do={
        :local tmpAddress [/ip dns cache get $i address] ;

# 轉換rapidshare的IP到"/16"的網段
        :local mjesto ([:find $tmpAddress "."]);
        :set mjesto ([:find $tmpAddress "." $mjesto]);
        :local tmpAddress ([:pick $tmpAddress 0 $mjesto]);
        :set tmpAddress ($tmpAddress . ".0.0/16");

#---- 如果address list是空的就不用查檢了(直接把IP加入)
        :if ( [/ip firewall address-list find ] = "") do={
            /ip firewall address-list add address=$tmpAddress list=RapidShare_IP disabled=no;
        } else={
#------- 檢查每一列的值
            :foreach j in=[/ip firewall address-list find ] do={
#---------- 如果IP已經存在address list就不用新增了
                :if ( [/ip firewall address-list get $j address] = $tmpAddress ) do={
                    :set bNew "false";
                }
            }
#------- 如果IP不存在就新增一筆上去address list
            :if ( $bNew = "true" ) do={
                /ip firewall address-list add address=$tmpAddress list=RapidShare_IP disabled=no
            }
        }
    }
}

接下來則是設定每30秒自動執行1次(相關設定如圖所示),隨時更新

System -> Scheduler -> 按介面上的 +

把這個 Scheduler 命名為 Auto_Update_RapidShare_IP

/system script run Update_RapidShare_IP

最後一個步驟就是判斷只要目的位置是在RapidShare_IP這個Address List裡的話

就強迫走單一路由。怎麼設定就因人而異了,不過大方向是不變的

有了RapidShare的相關IP,要針對RapidShare做限速、擋掉....等,都很方便了

相關參考資料:
Fight against P2P on port 80





七月 16

有了LINQ後,要濾出我們想要副檔名的檔案,真的蠻簡單的

花了一些時間寫了一個副程式,有需要的朋友可以拿去使用

如果你需要遞迴尋找的話(即該目錄下的所有子目錄也要找),把第3參數帶True進去即可

程式使用方式請看下面

'使用方式(只找1層)
Dim files As List(Of FileInfo) = _
GetPathFile(txt_batch_patch.Text, New String() {".png", ".jpg"})

lst_filename.Items.Clear()

For Each s As FileInfo In files
    lst_filename.Items.Add(s.Name)
Next

'使用方式(遞迴尋找)
Dim files As List(Of FileInfo) = _
GetPathFile(txt_batch_patch.Text, New String() {".png", ".jpg"}, True)

lst_filename.Items.Clear()

For Each s As FileInfo In files
    lst_filename.Items.Add(s.Name)
Next

.
.

完整的副程式如下

    ''' <summary>
    ''' 取得目錄下副檔名為特定格式的檔案
    ''' </summary>
    ''' <param name="DirPath">起始目錄</param>
    ''' <param name="file_extension">要尋找的副檔名</param>
    ''' <param name="IsRecursive">是否要尋找子目錄(預設值為不尋找子目錄)</param>
    ''' <returns>List(Of FileInfo)</returns>
    ''' <remarks></remarks>
    Private Function GetPathFile(ByVal DirPath As String, _
                                 ByVal file_extension As String(), _
                                 Optional ByVal IsRecursive As Boolean = False) _
                                 As List(Of FileInfo)

        '取得目錄下所有的資料夾
        Dim DirectoryPath As New List(Of String)
        DirectoryPath = My.Computer.FileSystem.GetDirectories(DirPath).ToList
        Dim Files As New List(Of FileInfo)

        If IsRecursive = True Then
            For Each DirName As String In DirectoryPath
                If System.IO.Directory.Exists(DirName) Then
                    '讓程式不要停止回應
                    Application.DoEvents()
                    '如果存在下一層的資料夾就遞迴呼叫
                    Files.AddRange(GetPathFile(DirName, file_extension, IsRecursive))
                End If
            Next
        End If

        DirectoryPath.Add(DirPath)
        For Each DirStr As String In DirectoryPath

            '取得目錄下所有的檔案名稱(String)
            Dim myFiles = From s In My.Computer.FileSystem.GetFiles(DirStr)

            '先把檔案名稱轉成FileInfo
            Dim f As New List(Of FileInfo)
            For Each s As String In myFiles
                f.Add(My.Computer.FileSystem.GetFileInfo(s))
            Next

            '使用LINQ來取出我們要的資料(副檔名包含在ImageExtension()裡面的)
            Dim files_filter As IEnumerable(Of FileInfo) = _
            From s In f _
            Where file_extension.Contains(s.Extension.ToLower)

            Files.AddRange(files_filter.ToList)

        Next

        Return Files

    End Function




七月 07

要產生任意大小的檔案在 Linux 下面有 dd 可以用

如果在 Windows 下面則可以用 fsutil 這個程式達成

這個工具 Windows XP 本身就有附帶了

開始 -> 執行 -> cmd

到文字介面模式後就可以使用了

如果要在 C:\ 產生的一個 1MB 的檔案就使用下面這行指令

fsutil file createnew C:\aa.txx 1024000

要大一點的檔案就自已加大。拿來測試記憶卡有沒有壞很好用