2007年8月24日

          組策略對象(GPO)是基于活動目錄(AD)的對象,用戶可以通過它集中地對Win2K臺式機和服務器系統進行配置,它的功能包括從NT 4.0臺式機的鎖定到安全性配置和軟件安裝等。

          這篇文章主要講述組策略是如何對系統起作用的、系統內部的工作原理以及在Win2K環境中采用這一技術時應該注意的問題。

          一、組策略是什么?
          GPO是一種與域、地址或組織單元相聯系的物理策略。在NT 4.0系統中,一個單一的系統策略文件(例如ntconfig.pol)包括所有的可以執行的策略功能,但它依賴于用戶計算機中的系統注冊表的設置。在Win2K中,GPO包括文件和AD對象。通過組策略,可以指定基于注冊表的設置、使用NT 4.0格式.adm模板文件的運行Win2K的本地計算機、域的安全設置和使用Windows安裝程序的網絡軟件安裝,這樣在安裝軟件時就可以對文件夾進行重定向。

          微軟管理控制臺(MMC)中的組策略編輯器(GPE)插件與NT 4.0中的系統策略編輯器poledit.exe相當。在GPE中的每個功能節點(例如軟件設置、Windows 設置、管理模塊等)都是MMC插件擴展,在MMC插件中擴展是可選的管理工具,如果你是應用程序開發者,可以通過定制的擴展拓展GPO的功能,從而針對你的應用程序提供附加的策略控制。

          只有運行Win2K的系統可以執行組策略,運行NT 4.0和Windows 9x的客戶機則無法識別到或運行具有AD架構的GPO。

          二、組策略和AD
          要充分發揮GPO的功能,需要有AD域架構的支持,利用AD可以定義一個集中的策略,所有的Win2K服務器和工作站都可以采用它。然而,每臺運行Win2K的計算機都有一個本地GPO(駐留在本地計算機文件系統上的GPO),通過本地GPO,可以為每臺工作站指定一個策略,它在AD域中不起作用。例如,出于安全原因,你不會在AD域中配置公用的計算機。利用本地GPO,可以通過修改本地策略來得到安全性和對臺式機的限制使用而無需利用基于AD域的GPO。訪問本地GPO的方法有2種,第1種方法,在需要修改GPO的計算機的“開始”菜單上選擇“運行”,然后鍵入:gpedit.msc。

          這個操作的作用與NT 4.0中的poledit.exe相同,可以打開本地策略文件。第2種方法,可以通過在MMC控制臺中選擇GPE插件,并選擇本地或遠程計算機來人工地編輯本地GPO。

          本地GPO支持除軟件安裝和文件夾重定向之外的所有缺省擴展,因此,只利用本地GPO你不能完成這些工作,如果想充分發揮GPO的功能,還是需要AD的支持。

          三、GPO的多樣性和繼承
          在AD中,可以在域、組織單位(OU)或地址三個不同的層次上定義GPO。OU是AD中的一個容器,可以指派它對用戶、組、計算機等對象進行管理,地址是網絡上子網的集合,地址形成了AD的復制分界線。GPO的名字空間被劃分為計算機配置和用戶配置兩個大類,只有用戶和計算機可以使用GPO,象打印機對象甚至用戶組都不能應用GPO。

          在一個域或組織單位(OU)中編輯策略的途徑有幾種。在活動目錄用戶或計算機MMC插件中,右擊一個域或組織單位(OU),在菜單中選擇“屬性”,然后選擇“組策略”標簽。在編輯地址中的策略時,需要右擊“活動目錄地址和服務”插件,然后右擊需要的地址得到其GPO。此外,還可以從“開始”菜單,選擇“運行”,然后鍵入: mmc.exe 啟動MMC,選擇“控制臺”,“增加/刪除”插件,然后選擇“組策略”插件、“瀏覽”,在AD域內的GPO就會顯示出來,可以選擇一個GPO進行編輯。

          根據GPO在AD名字空間中的不同位置,可以有幾個GPO對用戶對象或計算機對象起作用。只有域中的其他對象是通過繼承生成時GPO才是通過繼承生成的。Win2K通過下面的方式執行GPO,首先,操作系統執行現有的本地系統上的策略,然后,Win2K執行定義的地址級的GPO、域一級的GPO和基于OU的GPO,微軟把這一優先順序取其首個字母縮寫為LSDOU(執行的順序依次是本地、地址、域、OU層次的GPO),用戶可以在這個鏈上的許多層次上定義GPO。我們以pilot域為例說明如何察看一個系統中的GPO,啟動“活動目錄用戶和計算機MMC”工具,右擊pilot域名,從菜單中選擇“屬性”項,然后選擇組策略標簽。在這個列表頂端的GPO(例如域范圍的安全策略)有最高的優先權,因此,Win2K最后才會執行它。除了本地系統外,可以在每個層次上定義幾個GPO,因此如果不能嚴格地管理GPO,就會出現不必要的問題。

          GPO的繼承模型與Novell公司的Zenworks策略方式截然不同。在Zenworks中,如果在Novell目錄服務(NDS)樹上的不同點使用多個策略包,只有距離用戶對象最近的策略包才起作用。在Win2K中,如果在AD的不同層次上定義四個GPO,操作系統使用“LSDOU”優先順序來執行這些策略,對計算機或用戶的作用是這四個策略執行的“和”。此外,有時在一個GPO中的設置會被其他GPO中的設置抵銷。通過AD級GPO,用戶可以擁有更多的策略控制委托,例如,公司的安全部門負責在域一級上設計用于所有系統設備的安全GPO。通過使用GPO,可以讓某個OU的系統管理員擁有在OU上安裝軟件的權利。在Zenworks模型中,必須在希望使用策略的所有層次上復制這些策略,而且策略對用戶或計算機對象的作用并非是所有策略的“和”。

          為了進一步地控制GPO,微軟提供了三種設置來限制GPO繼承的復雜性。在地址、域、OU三個層次上用戶都可以通過選擇一個檢查框阻止從更高一個層次上進行繼承,同樣,在每一個層次上,用戶可以選擇缺省的域策略選項,方法是打開“活動目錄用戶和計算機”插件,右擊GPO所在的域或OU,從菜單中選擇“屬性”,然后選擇“組策略”標簽。讓你希望修改的項目變亮,然后選擇“選項”按鈕,可供選擇的選項有“不覆蓋”或“禁止”。如果選擇了“不覆蓋”選項,即使選擇了不能繼承的檢查框,該GPO還是會起作用。如果想在任何一個地方執行一個GPO時,這一功能就很有用處。如果一個OU的管理員試圖阻止對安全策略的繼承,包含安全策略的GPO仍然會被系統執行。“禁止”檢查框可以完全禁止一個GPO執行,這一功能在你對一個GPO進行編輯而不想讓其他的用戶執行它時特別有效。

          四、GPO的執行和過濾
          只有用戶和計算機對象才能執行組策略。在計算機的啟動和關閉時,Win2K執行在GPO的計算機配置部分定義的策略,在用戶登錄和注銷時,Win2K執行在GPO中用戶配置部分定義的策略。事實上,在用戶登錄時可以通過手動方式執行一些的策略,例如可以在命令行方式下運行secedit.exe程序執行安全策略應用程序。此外,通過管理員模塊策略可以定期地對用戶和計算機的GPO設置進行刷新,缺省情況下,這種刷新每90分鐘進行一次,這種刷新可以使其他用戶不容易修改通過組策略定義的策略。但是,軟件安裝策略是不會刷新的,因為沒有人希望周期性地改變策略引起軟件的“?載”,尤其是有其他用戶在使用時,就更是這樣了。計算機、用戶對象只有在計算機啟動或用戶登錄時才會軟件安裝策略。

          盡管只有AD中的計算機和用戶對象才能執行GPO,但我們可以過濾GPO的效果。使用Win2K中的安全組、應用組策略━━這是Win2K中的一項新的安全特性,可以使特定的用戶組不能執行某一個GPO。右擊MMC中GPO的名字,選擇“屬性”,然后再選擇“安全”,就可以看到GPO目前的安全設置。認證用戶組具有應用組策略權利,從而附屬這一GPO的所有用戶可以執行它。在Win2K中,安全組可以包括用戶和計算機對象。因此,利用安全組可以仔細地調整用戶、計算機對象如何執行一個GPO。你還可以對個別的應用程序應用安全組,可以指派一個GPO的軟件安裝部分。例如,假設你在一個GPO中發布10個應用程序,可以指定只讓金融用戶用戶組訪問其中的5個,其他用戶登錄到這個域時,它們也不會發現這5個應用程序。

          五、GPO的內部構成
          一個GPO是由兩部分組成的:組策略容器(GPC)和組策略模板(GPT)。GPC是GPO在AD中的一個實例,在一個特殊的被稱作系統的容器內有一個128位的全球唯一的ID碼(GUID)。在“活動用戶目錄用戶和計算機”插件中選擇“瀏覽”,從MMC菜單中選擇“高級屬性”,就可以看到“系統”容器。GPT是組策略在Win2K文件系統中的表現,與一個GPO有關的所有文件依賴于GPT。

          六、GPO帶來的難題
          雖然GPO的功能很強大,但要掌握它可不容易。最難掌握的是如何判斷一條有效的策略如何對域中的計算機或用戶起作用,由于GPO可以存在于AD鏈中不同的層次上,這種判斷就特別困難。同時,由于可以指派一個GPO的控制,因此不大容易清楚其他的GPO是否會對你沒有控制權的容器中的GPO有影響。因此,計算一個計算機或用戶對象接收的“策略的結果集”(RSoP)是相當困難的。盡管微軟還沒有提供計算RSoP的工具,但已經有第三方廠商提供了相應的計算RSoP的工具。

          另一個難題是策略的執行。如果在AD鏈上的許多層次上都存在有GPO,在用戶每次登錄或系統啟動時都會執行所有的GPO。在Win2K系統中,微軟推出了一些新的功能來優化系統的性能。首先,GPO的版本信息依賴于工作站和GPO,如果GPO沒有變化,系統就不會執行它。另外,在GPE的屬性頁上,可以禁止用戶或計算機對GPO的執行。如果建立一個GPO用來分發關閉系統或啟動系統時的腳本,禁用GPO的用戶配置部分,這樣會使工作站不能解析GPO并判斷它是否已經發生了什么變化。

          最后的一個難題起源于GPC和GPT是兩個單獨的實體。GPC是AD中的一個對象,它與GPT中包含的文件的復制不同步,這意味著創建一個GPO時,在GPT開始向域控制器上的Sysvol復制文件之前GPC可能已經開始進行復制了。

          所有問題的起源都是由于AD使用了一種多主體的復制模式。理論上,當另一個系統管理員在一個域控制器上編輯一個GPO時,你也可以在某個域上對它進行編輯。因此,當建立一個GPE時,缺省狀態下指的是在“操作主體”中充當PDC的域控制器。(“操作主體”是AD基礎結構中的一系列托管功能,用作PDC的服務器可以兼容運行NT和Win9x的工作站。)一般情況下,可以通過只向少數的系統管理員授予編輯GPO的權利來避免這種情況的發生,并保證如果有人在編輯GPO時,讓其他的人都知道。此外,需要注意的是,在對一個GPO進行編輯時,要“禁止”它,修改結束后重新使能。

          posted @ 2007-08-24 13:39 siwei 閱讀(322) | 評論 (0)編輯 收藏

          2007年8月21日

          概要
          Resource Kit實際上是Microsoft為管理員提供的一套額外的工具集,包括了超過400個各種工具,vbs,dll,msc,涵蓋了管理TCP/IP,網絡,注冊表,安全,遠程管理,配置,Batch文件,以及操作系統的其他方面。可以讓你更容易的管理一個NT系統。不得不承認這是一個非常龐大的工具集,包括到了已經被人們所遺忘2K所應該具有的功能。當你了解到了里面一些工具的性能以后,你將會知道即使僅僅只是一個C2級的操作系統也具有相當的安全性,對于細心配置的系統,攻擊也只能傷其表面。但是,但是任何東西都有他的兩面性,ResKit就非常具有代表性,在Hacker群體中大家習慣把這個玩意叫做“Hacker的工具箱”。當然如果你想當一個Hacker你得掌握里面的東西,而想當一個好的administrator你也得掌握里面的東西。希望大家都可以好好看看。

          第一部分:管理你的計算機

          1. Appsec.exe (Application Security)

          Appsec.exe是一個基于GUI的應用程序,它允許管理員在一個多用戶環境下限制普通用戶訪問一組網絡上經預訂的應用程序。啟用這種應用程序安全性,將會導致系統拒絕普通用戶執行或使用一個未經許可的應用程序。大家 看這是不是一個很有用的工具呢?對某些特定的程序進行限制以后,可以減少一些Hacker入侵的可能,下面我們 繼續討論。

          對于2000來說一個顯著的特點就是引入了GPO(Group Policy)這種東西,實際上就是一個界面化了的注冊表編輯器,但是因為GPO的存在2000大大提高了他的安全性。一般來說,我們可以通過配置GPO從啟動菜單和桌面 上隱藏一個應用程序,但是不能禁止用戶用其它手段訪問它,Appsec增加了這種安全性,可以禁止用戶執行應用 程序甚至是從命令行模式或者使用其他的應用程序。Microsoft的建議是和GPO一起使用,放在Terminal Server上運行或者說是在應用程序運行的機器上使用。Appsec對于應用程序的限制還算嚴格,除了應用程序的名稱以外還要包括該應用程序的全路徑,只有二者都附和才能夠運行。

          下面提幾點注意:
          a. 只有管理員或管理員組的成員可以運行所有程序,用戶(包括PowerUser組)只能運行列表中的應用程序。
          b. Appsec第一次啟用時,Terminal Server的會話必須中斷,否則Appsec將不能在本次會話中啟用。
          c. 實際上Appsec只能限制調用CreateProcess方法的應用程序,不能限制使用NTCreateProcess方法的程序,但是這種程序非常的少見。
          d. Appsec只能限制32位的程序,但是在默認情況下,一旦啟用appsec任何對16位程序的訪問都是禁止的,但 是可以添加ntvdm.exe來使16位程序可以被訪問。
          e. 我想這個也是Appsec最大的缺點,Appsec并不對程序本身進行檢查,也就是所如果將該有效程序進行替換 的話,Appsec不會發現。所以說我們必須禁止用戶替換和重命名應用程序,這可以用Security Template來做。
          f. 還有Appsec只可限制可執行文件,不可以是DLLs。
          g. Appsec的使用是對于計算機的,也就是說一經啟用使用本機的用戶都要受到限制。

          另外,應該要提到的一點是,按照Microsoft的要求,Appsec的列表中至少應該有:
          \Wtsrv\explorer.exe
          \Wtsrv\system32\cmd.exe
          \Wtsrv\system32\net.exe
          \Wtsrv\system32\regini.exe
          \Wtsrv\system32\subst.exe
          \Wtsrv\system32\systray.exe
          \Wtsrv\system32\xcopy.exe
          這么幾項。

          當然啦!你去掉也是可以的,但是會造成用戶難以正常使用。嗯,以我個人的建議,如果你想防止Hacker入侵去掉net.exe會有意想不到的收獲,呵呵!cmd.exe也是不錯的選擇,如果不想管理員以外的任何人訪問就統統去掉就好,后果你們試試就知道了。

          p.s. 這個程序所需要的文件Appsec.exe(這個倒是在),Appsec.hlp(這個也在),但是Appsec.dll,
          psec.cnt,Instappsec.exe并沒有包括在Resource Kit里面,要去網站上自己下載!!這簡直是搞笑嘛!也
          只有Microsoft干得出來。你可以在這個地方下載這個hotfix:
          http://download.microsoft.com/download/win2000platform/Appsec/1.0/NT5/EN-US/appsec_hot
          fix.exe,

          安裝以后就可以用了。 啟用以后,換個用戶(不是管理員組)登陸本機隨便點個應用程序,你就可以看到Access to specified device, path or file is denied的警告,很厲害的,哈哈!

          2. Cachemov.exe (Offline Files Cache Mover)

          Cachemov.exe一個有趣的東東,用來移動離線文件的緩存(默認保存在根卷下),如果你覺得那東西在那個地方礙的你事的話,把它挪個地方也沒有什么問題。這個工具比較簡單就不再多說什么了,就一個GUI,然后選擇 一個卷,它就自動幫你做完了,很簡單。你也可以使用無人值守模式 cachemov -unattend x:\ 電腦自己搞 定,此時需要(Cchmvmsg.dll)。所有的結果會保存至應用程序日志。 只是注意一下,運行時需要管理員的身份,還有就是不能夠移動到網絡驅動器和可移動驅動器上去。移動以后不要改letter,不然你會有麻煩的!

          3. Defptr.exe (Default Printer)

          如果你閑著沒有事的話,可以用用這個東西。它允許你隨意改變你的默認打印機,可以在可用的網絡和本地打印機間交換,一旦運行以后會在右下角有個小圖標(如果不想看到圖標可以使用defptr -i), 這個東西可能對漫游用戶會有一點好處吧!

          4. Delprof.exe(User Profile Deletion Utility)

          刪除用戶的Profile時用的工具,本來這個是可以在System Properties里面做的。而這個工具可以在本地或
          是遠程運行,看起來的好處就是可以指定多長時間不使用就刪除,在處理比較多的用戶的時候才顯得出好處來,就那么個把的話,就自己做好了。稍微介紹一下語法好了。

          delprof /q /i /p /c:\\computername /days /?

          /q 后臺悄悄執行,不用確認。
          /i 忽略錯誤繼續刪除。
          /p 在刪除前提示確認。
          /c:\\computername 這個不用解釋了吧?
          /days 指定多少天不使用的Profile就刪除,days用整數。
          /? 出現上面這些東東。

          5. DelSrv.exe (Delete Service)

          一個拿來刪除服務用的工具,使用起來非常簡單,只要delsrv servicename就可以了。沒有什么好說的。

          6. Dureg.exe (Registry Size Estimator)

          這是一個用來評估你的注冊表儲存了多少數據的工具,

          可以從任何一個hive,subtree和subkey中讀出。另外

          ,這個工具還可以用來搜索注冊表中的text字符串,這種搜索還可以具體到某個subtree中。
          這個工具主要用于得出注冊表具體占用空間,對于開發人員和管理員來說都是一個非常有用的工具。雖然我們可以使用控制面板中的System選項和系統監視器中的Registry Quota in Use來監視注冊表,但是如果你只想知道某個單獨的Key或者是Subkey所占用的空間,上面這些工具就無能為力了。

          語法:

          dureg /cr /cu /u /lm /a /s│/d "registry_path" "string to search"

          /a
          表示查找整個注冊表的大小。

          dureg /a
          Size of HKEY_CLASSES_ROOT : 7740324
          Size of HKEY_USERS : 995732
          Size of HKEY_LOCAL_MACHINE : 17265663

          Total Registry data size: 26001719

          /cr "registry_path"
          默認情況下,返回的是HKEY_CLASSES_ROOT的大小。

          /cu "registry_path"
          默認情況下,返回的是HKEY_CURRENT_USER的大小。

          /lm "registry_path"
          默認情況下,返回的是HKEY_LOCAL_MACHINE的大小。

          /u "registry_path"
          默認情況下,返回的是HKEY_USERS的大小。

          以上四個選項都可以在 "registry_path"中填入該Subkey下的任意key。比如:
          dureg /lm "software\microsoft",查找HKEY_LOCAL_MACHINE\Software\Microsoft key的大小。

          /s "string"
          在注冊表中搜索該字符串。比如:
          dureg /s "run" 尋找和run相關的字符串。當然你也可以和/cr等這幾個參數一起使用,比如:dureg /cr

          /s "run"。
          會看到一大串顯示,這里就不寫出來了。

          7. Elogdmp.exe (Event Log Query Tool)

          一個命令行工具用來導出選定的日志中的信息。這是在屏幕上進行顯示,最好和Find或者是Findstr這樣的工具

          一起使用,不然太難找到了。

          語法:

          elogdmp -? computername eventlogtype

          eventlogtype有Application, Security,System三種。

          比如: elogdmp hello application

          這個工具可以遠程使用,但是需要域管理員組或者是本地管理員組的成員才可以使用。

          8. Instsrv.exe (Service Installer)

          嗯,Instsrv.exe一個命令行工具可以用來安裝或者是刪除可執行服務(.exe),當然也可以給它們分配名字的
          語法:

          instsrv Servicename pathtoexecuteable -a accountname -p accountpassword or Servicename remove

          ServiceName
          用來顯示的名字,比如Alerter。

          PathToExecuteable
          要安裝服務文件的全路徑,包括盤符在內。

          -a accountname
          指定服務運行的帳戶。

          -p accountpassword
          帳戶的密碼。

          servicename remove
          指定你想移出的服務。

          比如:你想安裝一個bbb.exe作為一個bbb的服務。
          instsrv bbb "c:\program files\bbb.exe"
          默認情況下,我們安裝的服務是沒有啟動的,需要啟動。而有些時候需要插入相應的注冊表項。

          如果想指定這個服務在某個用戶下運行:
          instsrv bbb "c:\program files\bbb.exe -a hello\bbb -p xxx"
          that's OK!

          如果要卸在的話: instsrv bbb Remove,注意刪除之前要先Stop。

          這里我們再提到一個工具Srvinstw.exe,這是一個GUI模式的工具,所以用起來非常的簡單,照著提示一步步做就可以了。它和Instsrv.exe的區別是這個東東可以在遠程計算機上安裝服務。它們都需要administrator 的特權,請記住。

          9. intfiltr.exe (Interrupt Filter)

          這是一個在多CPU環境下用來調整CPU之間中斷關系的工具,可以用來測試最優化的方案。我沒有2個這種東西,這個程序就沒有進行測試了!那個有的話,幫我試試,告訴我結果。我把它補全。

          10. Inuse.exe (File-In-Use Replace Utility)

          一個命令行工具可以用來替換被鎖定的操作系統文件,比如一些重要的DLL文件。這些文件會在下一次啟動的時候被替換,根據微軟的說法,這種替換會在下一次啟動的Autochk完成之后,創建Paging Files之前。基本上來說,這個一個調試用的工具。該程序需要管理員身份運行。

          語法:

          insuse -? source destinaion /y

          source
          你想用來替換的文件。可以使用完整的物理路徑或者是UNC路徑。

          destination
          你要替換的文件。

          /y
          表示確定。

          如果你想用一個遠程文件來替換一個本地存在的文件可以使用下面的方法。
          inuse \\hello\winnt\abc.dll c:\winnt\abc.dll /y

          11. Javareg.exe (Java/COM Registration Utility)

          命令行工具可以用來注冊Java classes,鄙人不懂Java這種高深的東西,連什么是classes都不知道,沒有辦
          法了,這一塊就只好%¥&………了,不好意思。有懂的人幫一下忙好了,呵呵!!

          12. Netsvc.exe (Command-line Service Controller)

          一個命令行工具,用來控制服務,和SC比較類似,但是在功能上要比后者少很多!用這個工具基本上可以進行遠程啟動,停止,暫停,繼續服務或者查詢一個服務的狀態。基本上只要你是一個普通用戶就可以執行這個命令, 當然如果要啟動和停止的話,就需要相應的權限了。 當然和SC相比Netsvc有很大的局限性,所以在這里我多說一點和服務有關的東西。在Win2k雖然你可以對各種服務進行查詢,但是并不是所有的服務都可以直接關閉,比如Workstation這個服務,但奇怪的是Workstation這個服務有些時候會莫名其妙的丟失,

          至今我還不知道原因,一旦丟失以后基本上就 需要重裝了。我們繼續話題,當一個用戶有許多活動的連接存在的時候,你只可以查詢或者是暫停該服務,而不能遠程強迫服務停止。而如果有服務依靠別的服務才能運行的時候,我們也不能直接停止該服務。舉一個簡單的例子,Clipbook服務需要Network DDE服務才能運行,我們必須先停止CilpBook才能停止Network DDE。

          這里還要提到另外一種狀況,就是當你停止一個不可以停止的服務的時候Netsvc會報告Service is running ,而該服務不能停止的原因有很多種,但是Netsvc并不會報告給你,太慘了!!此外,當一個服務不能被暫停的時候,這個鬼東西仍然會報告給你說Service is running,唉!所以說最好使用SC。

          語法:

          netsvc command servicename \\computername /?│/help

          command可以是以下幾個命令:
          /list
          列出已經安裝的服務,這個時候不使用servicename。

          /query
          查詢一個服務的狀態。

          /start, /stop, /stop, /continue
          這幾個命令就不用解釋了吧?字面意義都已經很清楚了。

          最后舉兩個例子吧!如:
          netsvc /list \\hello

          netsvc /query \\hello "Alerter"

          netsvc Alerter \\hello /pause

          更進一步具體的內容可以在SC那里看到,

          這里不再多說。

          13. Now.exe

          Reskit里面比較無聊的命令之一,可以在STDOUT(Standard output)上輸出一個帶時間戳的東東。有點像
          ECHO命令。舉例說明算了:

          當我們打入ECHO bbb的時候,屏幕會顯示bbb
          C:\>echo bbb
          bbb

          但是當我們用Now bbb的時候,會輸出:
          C:\>now bbb

          Sat Feb 16 22:31:34 2002 -- bbb
          這種東西,不知道有什么用,呵呵!

          14. Pathman.exe

          一個命令行工具可以修改系統路徑和用戶路徑,當然這個工具還可以用來檢查路徑中的錯誤,有多余的頭部分號,尾部分號,多個連接得分號,重復的添加和刪除,增加重復的路徑或是移出一個不存在的路徑等等,但是不檢查路徑的有效性。 2K保留了兩套路徑,一個是統一的全局系統路徑,另一組是每個用戶個別的用戶路徑,當然為了保證兼容性,2000仍然保留了從Autoexec.bat裝入路徑。每個用戶可以修改自己的用戶路徑,

          JA管HIGD$*O@專_8y3網%中

          而只有管理員可以修改系統路徑,為了方便操作,微軟就搞出了這個Pathman。

          語法:

          pathman /as /au /rs /ru path

          /as
          增加分號隔開的系統路徑。

          /au
          增加分號隔開的用戶路徑。

          /rs
          刪除分號隔開的系統路徑。

          /ru
          刪除分號隔開的用戶路徑。

          當修改完成以后,Pathman會廣播信息給所有的頂端窗口提醒它們環境被改變了,這將會導致應用程序升級它們的環境,獲得經修改的路徑。

          舉例說明:

          添加c:\temp;C:\users\name;d:\utils為用戶路徑, 當然, 只是在它們不存在的時侯才添加。這個結果你可
          以在System properties的Environment Variable中看到。上面一欄是user的變量,下面是系統變量。
          實際上這個工具也有個好處就是添加和刪除可以同時操作,你可以:
          pathman /au C:\users\name /ru c:\users\name 呵呵!不過沒有什么意思!

          15. Ptree.exe(Process Tree)

          該程序可以允許你在本地或者是遠程查詢進程樹,同樣也可以Kill它們。2000默認情況下,允許Local
          Administrators, Power Users, Users查詢這些樹,但是只有Local Administrators和Power Users可

          以Kill進程。

          就這個工具而言,它有這么幾部分組成ptreedrv.sys(kernel-mode驅動程序),ptreesvc.exe和
          ptreesvcps.dll(2000的服務的程序,就是所ptree是需要在該計算機上安裝一個服務),
          Ptreesvr.dll(COM+服務端),ptree.exe(控制臺客戶端),Ptreeg.exe(GUI客戶端,推薦使用這個,在
          DOS底下看到的東西太少,也不好看,還是GUI爽!而且還可以同時管理多臺計算,不錯吧!我是挺喜歡的,比Ctrl+Alt+Del出來的那個東西要好得多!)

          這個程序并沒有和Reskit一起安裝,而實在Reskit的目錄下生成一個名為Ptree的目錄,底下有個ptree.msi
          ,要點擊安裝。同時由于這是一個基于COM+的程序,而安裝ptreeCOM的時侯,需要MSDTC服務,注意不要把它關了,不然會導致ptree不能正常運行,而且只會提示不能找到服務,后來是查了錯誤日志才發現的,微軟坑人 !。我就因為這個弄了好一陣子,呵呵! 使用嘛,很簡單,GUI就不用說了,都有提示,說一下命令行模式吧!

          ptree -c computer -k│-kt process -?│/?

          -c computer
          當要管理的是遠程主機的時侯才需要用的這個參數,如果是本機就不要啦,直接ptree就可以了。

          -k process
          干掉后面指定的進程。
          這里的process可以是進程的名字也可以是PID。
          -kt process
          可以干掉整整一棵樹。

          舉例: ptree -c hello 然后出來一大串東西,自己看吧!

          16. pulist.exe

          命令行工具,和上面那個東西有點類似,和Tlist也有一點像(這東西在Support Tools里面)但是
          pulist.exe多一點點好處,可以顯示出進程和用戶之間的關系。比如:
          C:\>pulist

          Process PID User
          Idle 0
          System 8
          smss.exe 156 NT AUTHORITY\SYSTEM
          csrss.exe 176 NT AUTHORITY\SYSTEM
          winlogon.exe 172 NT AUTHORITY\SYSTEM
          services.exe 228 NT AUTHORITY\SYSTEM
          lsass.exe 240 NT AUTHORITY\SYSTEM
          svchost.exe 428 NT AUTHORITY\SYSTEM
          spoolsv.exe 452 NT AUTHORITY\SYSTEM
          msdtc.exe 480 NT AUTHORITY\SYSTEM
          tcpsvcs.exe 604 NT AUTHORITY\SYSTEM
          svchost.exe 620 NT AUTHORITY\SYSTEM
          llssrv.exe 644 NT AUTHORITY\SYSTEM
          nspmon.exe 712 USER1-COMPUTER1\NetShowServices
          nscm.exe 724 USER1-COMPUTER1\NetShowServices

          當你的計算機有多個處理器時,需要判斷安全上下關系的時侯這個工具的用處就體現出來了!如果是遠程操作的 時候就多加一個pulist \\server就可以了。而且可以順序顯示多個站點pulist \\server \\server………,
          但是這個時侯會不顯示User。

          當你需要專門查找一個已知的進程的時候,可以用這樣的方法來簡化查找:
          pulist │ find "string"

          比如,過去老的pwdump2需要知道LSASS的PID,我們可以這樣做:

          c:\>pulist │ find "LSASS"
          LSASS.EXE 252 NT AUTHORITY\SYSTEM
          然后使用252來運行pwdump2………

          17. Reducer.exe (Reduce Trace Data)

          這個東西是一個命令行的事件追蹤工具,可以用來處理Tracelog(后面會提到這個工具)產生的記錄,形成每個線程,每個進程的工作量記錄。

          實際上呢,Reducer就是一個用來進一步分析工具,比如TraceDump(后面提到)可以允許你對一個追蹤日志進行摘要,而Reducer則允許你進行拆分獲得更多的細節,諸如:

          事務統計表:響應時間,每秒的事務數,每個事務的磁盤讀寫,每個事務的網絡流量,CPU的使用(包括核心和用戶空間)。
          映象統計表:事務有關的每個進程,每個進程相關的線程,每個進程的CPU使用(包括kernel和user),每個進程的磁盤讀寫,每個進程的網絡流量。
          磁盤信息:總的磁盤讀寫,每個進程的磁盤讀寫。
          OK,接下來介紹一下語法。

          語法非常簡單:

          reducer -out 20051017183000.htm -h│-help│-?

          -out 20051017183000.htm
          輸出的文件的名字,默認是Workload.txt

          舉例:這里我已經事先使用Tracelog生成了一個logfile.etl,然后,
          reducer -out my_workload.txt c:\logfile.etl就行了。

          --------------------------------------------------

          ----------------------------------------------+
          │ WINDOWS 2000 Capacity Planning Trace


          │ Version : 2128


          │ Type : Default


          +-------------------------------------------------------------------------------------

          ----------------------------------------------+



          │ Build : 2195


          │ Processors: 1


          │ Start Time: 17 Feb 2002 23:14:17.430

          │______________________________________________________________________│ │
          │ End Time : 17 Feb 2002 23:14:38.550


          │ Duration : 21 Sec





          │ Trace Name: NT Kernel Logger


          │ File Name : C:\LogFile.Etl


          │ Start Time: 17 Feb 2002 23:14:17.430

          │______________________________________________________________________│ │
          │ End Time : 17 Feb 2002 23:14:38.550


          │ Duration : 21 Sec





          +-------------------------------------------------------------------------------------

          ----------------------------------------------+


          +-------------------------------------------------------------------------------------

          ----------------------------------------------+
          │ Transaction Statistics


          +-------------------------------------------------------------------------------------

          ----------------------------------------------+
          │ Transaction Sort Trans Response Transaction Disk/Trans

          Tcp/Trans │
          │ Key Time(ms) Rate/sec Reads

          Writes Sends Recieves │
          +-------------------------------------------------------------------------------------

          ----------------------------------------------+
          +-------------------------------------------------------------------------------------

          ----------------------------------------------+


          樣式大概會是這樣的。

          18. Regback.exe (Registry Backup)

          一個注冊表備份用工具,允許你在系統運行期間對注冊表進行備份。我想當你需要測試一個軟件時,最好先備份一下注冊表。在使用這個程序時,至少需要備份文件和文件夾的權限。Regback.exe在運行的時侯需要調用Replacekey函數。

          語法:

          regback destination_dir 20051017183000.htm hivetype hivename more│/?

          destination_dir
          備份文件的位置

          20051017183000.htm
          要創立的文件

          hivetype
          machine或者是users

          hivename
          HKLM或者HKLU

          這里提幾點注意:

          Regback可以備份整個注冊表hive(你可以理解為一個file,比如HKEY_USERS\Default在硬盤上實際上就是%SYSTEMROOT%\SYSTEM32\CONFIG\DEFAULT\DEFAULT.LOG)還包括了ACLs(Access control lists),所以你也可以用這個東東發現和以前不同的ACLs。 Regback不能自動備份Config文件夾以外的文件,你要手動進行,這是為了避免名字沖突。如果當前注冊表并沒有打開的hive需要自己用Xcopy.exe或者是Scopy.exe拷貝。另外,沒有裝入的Hive也要自己弄。如果出錯的話,Regback會在第一次的時候就停止工作。它也不能覆蓋存在的文件,會報錯。還有如果空間不合適的話,備份就不能進行,所以最好先備份到硬盤上,然后再拷貝到磁盤上保存。

          舉兩個例子吧!

          備份全部活動的Hives

          C:\>regback c:\backup
          saving SECURITY to c:\backup\SECURITY
          saving SOFTWARE to c:\backup\software
          saving SYSTEM to c:\backup\system
          saving .DEFAULT to c:\backup\default
          saving SAM to c:\backup\SAM

          ***Hive = '\REGISTRY\USER'\'S-1-5-21-1177238915-1383384898-1957994488-500'
          Stored in file '\Device\HarddiskVolume1\Documents and Settings\Administrator'\'N
          TUSER.DAT'
          Must be backed up manually
          regback users S-1-5-21-1177238915-1383384898-1957994488-50
          0


          ***Hive = '\REGISTRY\USER'\'S-1-5-21-1177238915-1383384898-1957994488-500_Classe
          s'
          Stored in file '\Device\HarddiskVolume1\Documents and Settings\Administrator\Loc
          al Settings\Application Data\Microsoft\Windows'\'UsrClass.dat'
          Must be backed up manually
          regback users S-1-5-21-1177238915-1383384898-1957994488-50
          0_Classes

          你看, 連SAM都可以備份,對于破解SAM,也是有非常大的用處的。

          下面是備份指定的User的Profile
          C:\>regback c:\backup\administrator.bku users s-1-5-21-1177238915-1383384898-195
          7994488-500
          saving s-1-5-21-1177238915-1383384898-1957994488-500 to c:\backup\administrator.
          bku

          這里用的是SID比較特別,只是用起來太麻煩了,輸那么多數字,呵呵!

          最后是做一個網絡備份,也是一個批量腳本。
          注意使用Schedule服務一起搭配。前面提到過regback不能覆蓋文件,一旦有重名的文件將會導致錯誤的發生 。

          echo on
          rem ... Name: doback.bat
          rem ... Purpose: Network backup for Registry files
          rem ... Process: Connect to backup share, delete old backup files, copy over new

          backup files
          rem ... Before using this batch file, create a share containing the following

          directories: backup, config. Set permissions on this share so that appropriate users

          can run this script.

          net use \\myshare\backup

          rem --> delete old backups; regback will not copy over an existing file
          echo y│del 

          24. Sc.exe (Service Controller Tool)

          干好一年以前就寫過這個東西介紹了。大家再看一遍吧!

          我們知道在MStools SDK,也就是在Resource Kit有一個很少有人知道的命令行軟件,SC.exe,這個軟件向所有的Windows NT和Windows 2000要求控制他們的API函數。我們可以在命令行里通過對這些函數設定參數的方式來設定他們(API)。SC.exe也可以顯示服務的狀態,同時也可以從狀態結構區域里重新找到存儲在里面的數值。它還可以列出遠程計算機的服務函數或者是服務狀況結構。SC.exe這個開發工具至少可以比服務控制面板程序和網絡命令行界面(net.exe,這個東西可以告訴你一個服務是
          在運行中,還是停止,還是暫停。)這兩個東西提供更多的細節和準確的信息。雖然上述兩個東西在正常工作的情況下,對于完整的調試是非常好用的,但是如果有新的服務,或者新的代碼被開發出來的時候,這兩個工具提供的信息可能造成誤導。這也就是我們需要用到SC的原因。

          下面舉列說明,如果在開發階段,你的服務在掛住在一個start-pending的時候,控制面板和net.exe同樣報告服務是在運行的。但它掛在一個stop-pending的時候,net.exe報告它運行,而控制面板著報告它停止,如果你試著 啟動它,這是控制面板則會告訴你這個服務正在運行。難道這不是很困惑嗎?呵呵!
          SC.exe可以讓你詢問服務的狀況和取出存儲在狀態結構區域內的數值,控制面板和net.exe不提供服務完整的狀況 。但是無論如何,SC程序可以告訴你這個服務準確的情形,同樣也可以給你看最后的checkpoint數和等待提示。
          這個checkpoint,我叫它檢查點(我覺得他就像一個程序調試時置的斷點),所以我們也可以把看作為一個調試工具,因為它可以提供一個關于在程序停止時還要沿著初始化繼續前進多久準確報告。
          SC.exe也可以允許你調用很多的服務控制API函數,可以讓你從命令行里改變大量的參數。這位服務開發者們提供了很多的優勢。例如,它提供了一個方便的方式來創建或者在注冊表和服務控制管理數據庫中配置服務信息。開發者們不需要在手動的在注冊表里單獨的設置鍵值來配置服務,也不用重起機器來強迫服務控制管理數據庫升級 。
          作為一個命令很工具,SC.exe可以用來測試你自己的系統,你可以設置一個批處理文件來使用不同的參數調用SC.exe來控制服務。這個很有用,如果你想看看你的服務不斷的啟動和停止,我沒有試過哦!讓一個服務一下子
          打開,一下子關閉,聽上去很不錯的。如果你的服務進程里面有多個進程的話,你可以保持一個進程繼續運行不讓它走開,然后讓另一個不斷的打開在關閉,還可以尋找一下內存缺乏導致不完全清楚的證據。
          下面介紹SC,SC QC,and SC QUERY

          SC使用這樣的語法:
          1. SC [Servername] command Servicename [Optionname= Optionvalue]

          2. SC [command]

          這里使用第一種語法使用SC,使用第二種語法顯示幫助。

          下面介紹各種參數。

          Servername
          可選擇:可以使用雙斜線,如\\myserver,也可以是\\192.168.0.1來操作遠程計算機。如果在本地計算機上

          操作
          就不用添加任何參數。

          Command
          下面列出SC可以使用的命令。

          config 改變一個服務的配置。(長久的)

          continue 對一個服務送出一個繼續控制的要求。

          control 對一個服務送出一個控制。

          create 創建一個服務。(增加到注冊表中)

          delete 刪除一個服務。(從注冊表中刪除)

          EnumDepend 列舉服務的從屬關系。

          GetDisplayName 獲得一個服務的顯示名稱。

          GetKeyName 獲得一個服務的服務鍵名。

          interrogate 對一個服務送出一個詢問控制要求。

          pause 對一個服務送出一個暫停控制要求。

          qc 詢問一個服務的配置。

          query 詢問一個服務的狀態,

          也可以列舉服務的狀態類型。

          start 啟動一個服務。

          stop 對一個服務送出一個停止的要求。

          Servicename
          在注冊表中為service key制定的名稱。注意這個名稱是不同于顯示名稱的(這個名稱可以用net start和服務控制面板看到),而SC是使用服務鍵名來鑒別服務的。

          Optionname
          這個optionname和optionvalue參數允許你指定操作命令參數的名稱和數值。注意,這一點很重要在操作名稱和等號之間是沒有空格的。一開始我不知道,結果………………,比如,start= optionvalue,這個很重要。
          optionvalue可以是0,1,或者是更多的操作參數名稱和數值對。
          如果你想要看每個命令的可以用的optionvalue,你可以使用sc command這樣的格式。這會為你提供詳細的幫助。

          Optionvalue
          為optionname的參數的名稱指定它的數值。有效數值范圍常常限制于哪一個參數的optionname。如果要列表請用sc command來詢問每個命令。

          Comments
          很多的命令需要管理員權限,所以我想說,在你操作這些東西的時候最好是管理員。呵呵!

          當你鍵入SC而不帶任何參數時,SC.exe會顯示幫助信息和可用的命令。當你鍵入SC緊跟著命令名稱時,你可以得到一個有關這個命令的詳細列表。比如,鍵入sc create可以得到和create有關的列表。
          但是除了一個命令,sc query,這會導出該系統中當前正在運行的所有服務和驅動程序的狀態。

          當你使用start命令時,你可以傳遞一些參數(arguments)給服務的主函數,但是不是給服務進程的主函數。
          SC create
          這個命令可以在注冊表和服務控制管理數據庫建立一個入口。

          語法1
          sc [servername] create Servicename [Optionname= Optionvalue]

          這里的servername,servicename,optionname,optionvalue和上面的一樣,這里就不多說了。這里我們

          詳細說明一下optionname和optionvalue。

          Optionname Optionvalue
          描述type= own, share, interact, kernel, filesys
          關于建立服務的類型,選項值包括驅動程序使用的類型,默認是share。

          start= boot, system, auto, demand, disabled
          關于啟動服務的類型,選項值包括驅動程序使用的類型,默認是demand(手動)。

          error= normal, severe, critical, ignore
          當服務在導入失敗錯誤的嚴重性,默認是normal。

          binPath= (string)
          服務二進制文件的路徑名,這里沒有默認值,這個字符串是必須設置的。

          group= (string)
          這個服務屬于的組,這個組的列表保存在注冊表中的ServiceGroupOrder下。默認是nothing。

          tag= (string)
          如果這個字符串被設置為yes,sc可以從CreateService call中得到一個tagId。然而,SC并不顯示這個標簽,所以使用這個沒有多少意義。默認是nothing

          depend= (space separated string)有空格的字符串。
          在這個服務啟動前必須啟動的服務的名稱或者是組。

          obj= (string)
          賬號運行使用的名稱,也可以說是登陸身份。默認是localsystem

          Displayname= (string)
          一個為在用戶界面程序中鑒別各個服務使用的字符串。

          password= (string)
          一個密碼,如果一個不同于localsystem的賬號使用時需要使用這個。

          Optionvalue
          Optionname參數名稱的數值列表。參考optionname。當我們輸入一個字符串時,如果輸入一個空的引用這意味著一個空的字符串將被導入。

          Comments
          The SC CREATE command performs the operations of the CreateService API function.
          這個sc create命令執行CreateService API函數的操作。詳細請見CreateService。

          例1
          下面這個例子在一臺叫做(\\myserver)的計算機上為一個叫“NewService”的服務建立的一個注冊表登記。
          sc \\myserver create NewService binpath= c:\winnt\system32\NewServ.exe

          按照默認,這個服務會建立一個WIN32_SHARE_PROCESS使用SERVICE_DEMAND_START啟動方式。這將不會有任何從屬關系,也將會按照localsystem安全上下關系來運行。

          例2
          下面這個例子將在本地計算機上,建立一個服務,它將會是一個自動運行服務,并且運行在他自己的進程上。它從屬于TDI組和NetBios服務上。注意,你必須在從屬中間增加一個空格的引用。

          sc create NewService binpath= c:\winnt\system32\NewServ.exe type= own
          start= auto depend= "+TDI Netbios"

          例3
          服務開發者可以通過臨時改變二進制路徑(影像路徑)的方式來將這個服務運行在內核調試器的上下關系中。下面這個例子就可以讓我們看到如何改變服務的配置。

          sc config NewService binpath= "ntsd -d c:\winnt\system32\Newserv.exe"
          這個例子會引起服務控制管理器調用ntsd.exe使用下例的參數字符串:
          "-d c:\nt\system32\NewServ.exe"

          當系統裝入newserv.exe時ntsd將會轉而打斷調試器,所以斷點可以被設置在服務代碼里。

          SC QC
          這個SC QC“詢問配置”命令可以列出一個服務的配置信息和QUERY_SERVICE_CONFIG結構。

          語法1
          sc [Servername] qc Servicename [Buffersize]

          Parameters
          servername和servicename前面已經介紹過了,這里不再多說。

          Buffersize,可選擇的,列出緩沖區的尺寸。

          Comments

          SC QC命令顯示了QUERY_SERVICE_CONFIG結構的內容。

          以下是QUERY_SERVICE_CONFIG相應的區域。
          TYPE dwServiceType
          START_TYPE dwStartType
          ERROR_CONTROL dwErrorControl
          BINARY_PATH_NAME lpBinaryPathName
          LOAD_ORDER_GROUP lpLoadOrderGroup
          TAG dwTagId
          DISPLAY_NAME lpDisplayName
          DEPENDENCIES lpDependencies
          SERVICE_START_NAME lpServiceStartName

          例1

          下面這個例子詢問了在上面例子中建立的“NewService”服務的配置:

          sc \\myserver qc NewService

          sc顯示下面的信息:

          SERVICE_NAME: NewService
          TYPE : 20 WIN32_SHARE_PROCESS
          START_TYPE : 3 DEMAND_START
          ERROR_CONTROL : 1 NORMAL
          BINARY_PATH_NAME : c:\winnt\system32\NewServ.exe
          LOAD_ORDER_GROUP :
          TAG : 0
          DISPLAY_NAME : NewService
          DEPENDENCIES :
          SERVICE_START_NAME : LocalSystem

          NewService有能力和其他的服務共享一個進程。但是它不是自動啟動的。二進制文件名是NewServ.exe。這個服務不依靠與其它的的服務,而且運行在lcoalsystem的安全上下關系中。這些都是調用QueryServiceStatus基本的返回,如果還需要更多的細節屆時,可以看看API函數文件。

          SC QUERY

          SC QUERY命令可以獲得服務的信息。

          語法:
          sc [Servername] query { Servicename │ Optionname= Optionvalue... }

          參數:

          servername, servicename, optionname, optionvalue不在解釋。只談一下這個命令提供的數值。

          Optionname Optionvalue
          Description

          type= driver, service, all
          列舉服務的類型,默認是service

          state= active, inactive, all
          列舉服務的狀態,默認是active

          bufsize= (numeric value)
          列舉緩沖區的尺寸,默認是1024 bytes

          ri= (numeric value)
          但開始列舉時,恢復指針的數字,默認是0

          Optionvalue
          同上。

          Comments

          SC QUERY命令可以顯示SERVICE_STATUS結構的內容。

          下面是SERVICE_STATUS結構相應的信息:
          TYPE dwServiceType
          STATE dwCurrentState, dwControlsAccepted
          WIN32_EXIT_CODE dwWin32ExitCode
          SERVICE_EXIT_CODE dwServiceSpecificExitCode
          CHECKPOINT dwCheckPoint
          WAIT_HINT dwWaitHint

          在啟動計算機后,使用SC QUERY命令會告訴你是否,或者不是一個啟動服務的嘗試。如果這個服務成功啟動,WIN32_EXIT_CODE區間會將會包含一個0,當嘗試不成功時,當它意識到這個服務不能夠啟動時,這個區間也會提供一個退出碼給服務。

          例子

          查詢“NewService"服務狀態,鍵入:

          sc query NewService

          顯示一下信息:

          SERVICE_NAME: NewService
          TYPE : 20 WIN32_SHARE_PROCESS
          STATE : 1 STOPPED
          (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
          WIN32_EXIT_CODE : 1077 (0x435)
          SERVICE_EXIT_CODE : 0 (0x0)
          CHECKPOINT : 0x0
          WAIT_HINT : 0x0

          注意,這里存在一個給這個服務的退出碼,即使這個服務部不在運行,鍵入net helpmsg 1077,將會得到對
          1077錯誤信息的說明: 上次啟動之后,仍未嘗試引導服務。所以,這里我想說一句,希望大家可以活用net helpmsg,這會對你的學習有很大的幫助。

          下面在對SC query的命令在說明一下:

          列舉活動服務和驅動程序狀態,使用以下命令:
          sc query

          顯示messenger服務,使用以下命令:
          sc query messenger

          只列舉活動的驅動程序,使用以下命令:
          sc query type= driver

          列舉Win32服務,使用以下命令:
          sc query type= service

          列舉所有的服務和驅動程序,使用以下命令:
          sc query state= all

          用50 byte的緩沖區來進行列舉,使用以下命令:
          sc query bufsize= 50

          在恢復列舉時使用index=14,使用以下命令:
          sc query ri=14

          列舉所有的交互式服務,使用以下命令:
          sc query type= service type= interact

          好了,說到這里。SC命令基本上已經說完了。希望大家好好看看,呵呵!相信會有幫助的!!

          25. Scanreg.exe

          又是個注冊表工具,有沒有人煩了?我都快煩了,呵呵!

          一個注冊表檢查工具,基本上就是一個"registry GREP"。支持搜索本地或遠程的Win一家老小的注冊表中的任意東西。

          scanreg -s string -k -v -d -r key -c -e -n

          -s
          要搜索的字符串

          -r
          開始搜索的root,默認是HKEY_CURRENT_USER

          也可以使用以下的格式:
          HKEY_LOCAL_MACHINE === lm
          HKEY_CURRENT_USER === cu
          HKEY_CLASSES_ROOT === cr
          HKEY_USERS === us

          -k
          查詢鍵。

          -v 注意必須指定-k -v -d中的至少一個。
          查詢值。

          -d
          當然是查詢數據。

          -c (默認是不敏感)
          大小寫敏感。

          -e (默認是返回所有合適的)
          只返回卻確合適的。

          -n
          輸出的時候不使用顏色(默認是key紅,values綠,data黃)真不知道微軟的怎么想的!!看上去怪怪的,還有就是匹配的字符串都高亮標出。

          最后來兩個例子:

          scanreg -s version -k -v -d

          scanreg -s version -kvd <--居然這種獨可以?

          scanreg /s version /r \lm\software /kvde 沒有關系,這種都是可以的,呵呵!

          scanreg version \\hello\HKEY_LOCAL_MACHINE -d 操作遠程的東東。

          26. sclist.exe

          可以列出當前運行或者是停止的服務。看看遠程的機器也是功能之一,但是比起SC來說,還是太簡單了!

          sclist -r -s MachineName -?

          -r
          只顯示正在運行的服務。

          -s
          只顯示已經停止的服務。

          Machinename
          本地可以不指出。

          這個簡單大家自己做做,這里不舉例了!! ,不要講我偷懶哦!


          27. Setx.exe

          這個命令行工具提供了一種批量修改環境變量的方法,同時不需要使用任何編程方法或者是腳本。此外,除了可以獲得變量和值之外還可以跟注冊表的值掛上關系。在2000中除了setx.exe之外,其他沒有任何一種命令行工具可以直接設置系統變量值。只有通過控制面板和注冊表編輯器才能夠設置。如果有人說可以用set命令的話, 實際上這個CMD的內部命令只能夠設置當前控制臺窗口的用戶環境變量。 setx允許你通過Command Line Mode,Registry Mode,File Mode,這三種模式來設置環境變量。

          a. Command-Line

          setx variable value -m

          variable
          要設置的環境變量的名字。

          value
          要設置的值。

          -m
          設置計算機環境,默認設置是用戶環境。

          b. Registry Mode

          setx variable -k hive\key\……\value -m

          variable
          要設置的環境變量的名字。

          -k
          指定變量設置會基于注冊表中的信息。

          hive\key\……\value
          注冊表路徑,如:
          HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation\StandardName

          -m
          同命令行模式。

          c. File Mode

          setx variable -f 20051017183000.htm -a x,y │ -r x,y "string" -d d -x -m

          -f 20051017183000.htm
          指定使用的文件名。

          -a x,y
          指定要搜索的絕對坐標或者是偏移量。

          -r x,y "string"
          指定從"string"的相對坐標或者是偏移。

          -d d
          指定附加的分隔符,后一個d表示,可以是",", "\"等等。系統有四個內建的分隔符是:space, tab,

          carriage return, linefeed。附加的可以是任意的ASCII字符。

          -x
          顯示文件坐標,這個時候-a, -r, -d會變忽略。

          -m
          在同上。

          setx將變量寫入到在注冊表的主環境中去。用setx設置的變量將會在下一次啟動的時候生效, 這是2000的局限。當訪問REG_MULTI_SZ時,只能訪問到第一個項目。
          目前setx只可以支持HKCU和HKLM兩個hives。用Setx增加的值不可以用setx去掉,可以在控制面板里面改,也可以在注冊表里面改,這種時候也可以用set把它置空。

          但是還是來幾個例子吧!

          a.Command Line

          Setx MACHINE COMPAQ
          在用戶環境中設置MICHINE為COMPAQ。

          setx MYPATH %PATH%
          設置MYPATH的值為當前PATH變量的值。

          setx MYPATH ~PATH~
          設置MYPATH總是和PATH環境的值保持一致。

          b. Registry

          Setx TZONE -k

          HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation\StandardName
          設置TZONE的值為上面的鍵。比如:"Central Standard Time"

          Setx BUILD -k "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows

          NT\CurrentVersion\CurrentBuildNumber"
          設置BUILD的值為當前的Windows NT版本號,如:1314。

          c. File
          在進行這部分之前先運行ipconfig > ipconfig.out,弄一個ipconfig的文本出來。然后就可以進行操作了


          Setx var -f ipconfig.out -x
          這個命令會顯示這個文件的內容的坐標。如:

          C:\>SETX VAR -f ipconfig.out -x


          (1,0 Windows) (1,1 2000) (1,2 IP) (1,3 Configuration)

          (3,0 Ethernet) (3,1 adapter) (3,2 Local) (3,3 Area) (3,4 Connection

          (5,0 Connection-specific) (5,1 DNS) (5,2 Suffix) (5,3 .) (5,4
          (6,0 IP) (6,1 Address.) (6,2 .) (6,3 .) (6,4 .) (6,5 .) (6,6 .) (6,7 .) (6,8 .)
          (6,9 .) (6,10 .) (6,11 .) (6,12 .) (6,13 (6,14 192.168.1.1)
          (7,0 Subnet) (7,1 Mask) (7,2 .) (7,3 .) (7,4 .) (7,5 .) (7,6 .) (7,7 .) (7,8 .)
          (7,9 .) (7,10 .) (7,11 .) (7,12 .) (7,13 (7,14 255.255.255.0)
          (8,0 Default) (8,1 Gateway) (8,2 .) (8,3 .) (8,4 .) (8,5 .) (8,6 .) (8,7 .) (8,8
          .) (8,9 .) (8,10 .) (8,11

          setx ipaddr -f ipconfig.out -a 5,11

          這個命令會尋找絕對偏移為(5,11)的內容,然后設置ipaddr為這個值。如:

          C:\>setx ipaddr -f ipconfig.out -a 6,14
          Extracted value is: 192.168.1.1

          Setx ipgateway -f ipconfig.out -r 0,11 "Gateway"
          查找Gateway這個字符串偏移0,11的東東,然后寫到ipgateway里面去。

          C:\>Setx ipgateway -f ipconfig.out -r 0,11 "Gateway"
          Extracted value is: 192.168.1.244

          以上所有的修改都會在重起以后看到,可以用set或者是控制面板中的System properties看。

          28. showpriv.exe (show Privilege)

          一個用來顯示用戶或者是組分配的特權的命令行工具,如果要看domain的相關的東西的話,要在DC上使用。使用起來很簡單,showpriv privilege就行了,如:

          C:\>showpriv sesecurityprivilege
          1 account(s) with the sesecurityprivilege user right:
          BUILTIN\Administrators
          All accounts enumerated

          這里主要講一下這個2000的一些privilege。

          Privilege,為本地管理員提供了一種手段,可以控制允許什么人具有什么權限或者能執行什么樣的系統操作,
          如允許交互式登陸等等。這里我們說的特權是指特殊操作所需的權限,如備份呀什么的!一旦授予了某種特權,這些特權就會包括在用戶的安全訪問令牌中。這是一些基本的概念,可以看以下,比較容易明白。
          系統為了管理的方便總是為每個本地組分配了相應的特權,而且從來不改變這個特權,這些東東在NT系統上可以分為內置能力,標準用戶權力,高級用戶權力這么幾種,但是在2000中標準權利和高級權力已經被用戶特權所取代,只有在為委派而信任計算機和用戶帳戶(SeEnableDelegationPrivilege)和把計算機從dock中移出(SeUndockPrivilege)這兩種情況下可以把NT的權利映射到2000中的特權。注意一下2000的一些問題。并非所有能力都有匹配的權利,因此,不可能用權力完全匹配組的內置能力。而由于特定組能力的預定義分配和不能把所有能力復制為權力,就難以區分任務,并且只能強制使用最低特權的概念。
          那么在域一級下就缺少一個安全結構,導致了難以授予管理的功能。2000在AD引入后,就允許區分任務,也可授予domain和OU相應的管理層次。

          下面來談一下具體的一些用戶特權,應當有26個,也有說28個的。

          SeTcbPrivilege
          成為OS的一部分允許進程可以像用戶一樣被鑒別,因此可以像用戶一樣訪問相應的資源。只有底層的鑒別服務需要這樣的特權,所以無論是工作站,獨立服務器,還是DC都沒有把這個設為某人權利。
          SeMachineAccountPrivilege
          添加工作站到域 為了這個特權可以啟用,必須保證這個用戶在域控制器本地安全策略中的才行。

          SeBackupPrivilege
          備份文件和目錄。
          允許用戶繞過文件和目錄的權限來做備份。只有當應用程序嘗試訪問NTFS備份API時才檢查這個特權。默認情況下,這個特權分配給Administrators和Backup Operators。

          SeChangeNotifyPrivilege
          回避遍歷檢查。
          允許用戶來回移動目錄,但是不能列出文件夾的內容。默認情況下,這種特權被賦予Administrators,
          Backup Operators, Power Users, Users ,and Everyone,換句話說就是所有人都有這種權利。

          SeSystemTimePrivilege
          改變系統時間。
          默認情況下Administrators和Power Users有這種權利。

          SeCreatePagefilePrivilege
          創建分頁文件。
          允許用戶創建和改變一個分頁文件的大小。默認情況下,只有Administrators有這個特權。

          SeCreateTokenPrivilege
          創建令牌對象。
          允許進程調用NtCreateToken()或者是其他的Token-Creating APIs創建一個訪問令牌。

          SeCreatePermanentPrivilege
          創建永久共享對象。
          允許進程在2000項目管理器中創建一個目錄對象。

          SeDebugPrivilege
          調試程序。
          允許用戶連接一個Debugger來調試任何進程。默認情況下Administrators有該特權。

          SeEnableDelegationPrivilege
          為委派而信任計算機和用戶帳戶。
          允許用戶為了委派而改變信任,只有當用戶或者是計算機對該對象的帳戶控制標志有寫權限的時候可以。

          SeRemoteShutdownPrivilege
          遠程關閉系統。
          Administrators在默認情況下有此特權。

          SeAuditPrivilege
          產生安全審核。
          允許一個應用程序在安全日志中,創建,產生,增加一條記錄。

          SeIncreaseQuotaPrivilege
          增加限額。
          允許一個有寫屬性的進程利用其他進程從而取得更多的處理器限額,這種特權有利于系統調試,但是也有導致DOS的可能。

          SeIncreaseBaseProrityPrivilege
          增加調度優先級。允許一個有寫屬性的進程利用其它進程來獲得更多的執行優先權。有這種特權的用戶可以在Task管理器中改變一 個進程的調度優先權。默認情況Administrators有該特權。

          SeLoadDriverPrivilege
          安裝和卸載設備驅動程序。
          允許用戶安裝和卸載即插即用設備的驅動程序,不是即插即用的不受這個特權影響,但是只能被

          Administrators所安裝。因為驅動程序是作為被信任的程序來運行的,這需要很高的特權。而這種特權可能會被用于安裝惡意程序,和破壞性的訪問。默認情況下Administrators有該特權。

          SeSecurityPrivilege
          管理審計和安全日志。
          允許用戶指定對象訪問的審計。有這種特權的用戶也可以清空安全日志。默認情況下Administrators有該特權。

          SeSystemEnvironmentPrivilege
          修改firmware環境變量。
          允許用戶使用進程通過一個API來設置系統環境變量,另外,也可以讓用戶使用System Properties來做到以上這一步。默認情況下Administrators有該特權。

          SeProfileSingleProcessPrivilege
          Profile單一進程。
          允許用戶使用性能監視器來監視nonsystem進程。默認情況下Administrators有此特權。


          SeSystemProfilePrivilege
          Profile系統性能。
          允許用戶使用性能監視器來監視system進程。默認情況下Administrators有此特權。

          SeUndockPrivilege
          將計算機中dock中刪除。
          允許用戶使用Eject PC從塢中將計算機移出,默認情況下Administrators, Power Users, Users均有此特

          權。

          SeAssignPrimaryTokenPrivilege
          替換一個進程級令牌。
          允許一個父進程替換相關的子進程的訪問令牌。

          SeRestorePrivilege
          恢復文件和目錄。
          允許用戶繞過文件及目錄權限來恢復備份文件。默認情況下Administrators和Backup Operators有此特權。

          SeShutdownPrivilege
          關閉系統。
          允許用戶關閉本地計算機。默認情況下Administrators, Backup Operators, Power Users, Users都有

          該特權,但是在2000 Server中Users沒有此特權。

          SeSynchAgentPrivilege
          同步目錄服務數據。
          允許一個進程提供目錄同步服務,這個特權只有在DC上。默認情況下域的Administrators和LocalSystem帳戶

          有此特權。

          SeTakeOwnershipPrivilege
          取得文件所有者身份。
          允許用戶取得在系統中任何可得到的對象的所有者身份,包括:AD對象,文件,文件夾,打印機,注冊表鍵,進

          程和線程。默認情況下Administrator有此特權。

          以上就是2000的用戶特權了,是不是很多呢?呵呵!

          29. Sleep.exe (Batch File Wait)

          Sleep可以讓計算機等待一段指定的時間。這個東東對于使用Batch文件會非常有用,在某些情況下也可能會讓AT命令的使用更加方便。

          Sleep time

          time
          要暫停的時間,秒為單位。

          sleep 20
          在運行下一個程序之前等待20s。

          假設我們搞這么一個登陸腳本到計算機上,我想是個不錯的主意。

          @echo off

          echo 2/23/2002
          echo.
          echo 不要忘了明天女朋友生日哦!!呵呵!

          sleep 60

          30. Soon.exe (Near-Future Command Scheduler)

          soon這個命令可以讓一個程序在很短的時間里面啟動,比如幾秒鐘之內。基本上soon就是一個AT的裝配命令,可以簡單的裝配一組合適AT命令來遠程或者是本地啟動一個程序。當然soon使用起來要比AT簡單的多,自然功能也要少一些了。當然soon可以讓一個命令在小于一天的時間內重復啟動,這一點還是很有用的。下面介紹一下

          如何使用。

          soon有兩種命令,一是普通的操作命令,還有就是配置命令。

          1. Scheduling Command
          soon \\computername delay /interactive "command"

          \\computername
          指定你要的計算機,遠程使用時要net use。

          delay
          指定從現在開始到啟動程序的間隔,以秒為單位,默認情況下是本地5s,遠程15s。

          /interactive
          這個和AT命令里面的interactive是一樣的。基本上可以看作是如果你打開一個cmd窗口,它會在桌面上跳出來。默認是off的。只有當Schedule服務以LocalSystem身份啟動時才可以Interactive。

          command
          你想要執行的命令,這里用雙引號來維持命令解釋時候的空格。

          2. Configuration Command

          soon /d /l:n /r:n /i: on│off

          /d
          用這個開關來修改默認配置

          /l:n
          指定LocalDelay的值。

          /r:n
          指定RemoteDelay的值。 注意,這些值都是正整數,而且以秒為單位。

          /in│off
          指定默認情況下是interactive還是uninteractive。

          如果你想每5分鐘啟動一次一個程序可以寫一個這樣的腳本。

          every5.cmd
          soon 300 every5.cmd
          xxxx.exe

          對于遠程啟動時,使用AT命令不能成功的原因多數是因為AT命令需要指定絕對時間,如果不能搞得太清楚的話,我建議你們使用soon命令,在大部分情況下大家需要AT的功能,soon都可以完成,而且很快。基本上srv.exe 這樣的后門都可以用soon來做。 另外不得不提一點,不知道是我的機器的關系還是這個程序本身的bug,很多情況下soon產生的schedule居然會是tomorrow,這個有點讓人搞不懂。大家可以多試試。

          31. Srvany.exe (Applications as Services Utility)

          Srvany一個可以讓Windows應用程序像一個服務那樣運行。也就是說在logoff的時候不關閉,也不用在logon
          的時候重新啟動。也就是就算是沒有人登陸這個程序也可以運行,當然計算機得是開著的,呵呵!此外,如果這個應用程序不忽略WM_ENDSESSION或者CTRL_LOGOFF_EVENT時,程序也會因為logoff而退出。srvany是一個為32-bit應用程序設計的,但是用用16-bit也應該沒有多大問題。如果你安裝過srvany服務的話,在升級或安裝Windows 2000, Windows NT Server, Windows NT Workstation, or applications 時要先disabled。實際上srvany本身就是一個服務,它先把自己啟動起來,然后又在啟動那些配置過的應用程序。就我個人開來這種方法很費力,比起instsrv和srvinstw來說都比較難以使用,最關鍵的是還要手工添加注冊表。下面也就說一下怎么樣讓一個應用程序像一個服務那樣運行。首先我們要安裝Srvany,可以使用instsrv Myservice c:\path\srvany.exe或者srvinstw照提示做就可以了。這個是必要的,我們需要Srvany來啟動程序。當然為了讓程序像服務一樣運行,我們需要編輯注冊表信息,而且還要選擇啟動參數和工作目錄。這里再次提醒手工操作注冊標有危險性,注意備份。

          我們只要在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyService\下
          添加一個Parameters子鍵,這里的MyService是剛剛指定的Srvany的服務名字。
          然后再這個subkey底下建立一個應用程序入口,使用REG_SZ類型。
          接著在指定程序的全路徑,需要包括擴展名。比如Application: REG_SZ: C:\Tools\srv.exe

          為了指定相應的啟動參數我們還得繼續編輯注冊表。
          這個時候要在剛剛的Parameters底下接著創建一個AppParameters條目,也是REG_SZ類型。
          比如:AppParameters: REG_SZ: C:\tmp\example,當然因為srvany已經被安裝為一個服務了,你也可以
          在Services面板里指定。C:\Tools\srv.exe C:\\temp\example。注意,這里使用\\來表示一個\。
          再來就是指定環境變量了。
          添加一個AppEnvironment,REG_MULTI_SZ類型。這個東西就是Services面板里面的Dependencies這一項。 可以根據需要指定,沒有就不需要添加。 還要指定Working Directory。
          也是在Parameters里面建立一個AppDirectory使用REG_SZ。比如:AppDirectory: REG_SZ: C:\Tmp
          當然也可以在Services里面 /D c:\\tmp D:\\Tools\\Vi.exe c:\\tmp\\example。

          一個srvany可以啟動一個應用程序,如果你要用srvany而且是多個程序的話,只要采用不同的servicename啟 動一個srvany就可以了。如果要刪除可以使用instsrv myservice remove,也可以用sc。
          大家可以通過調整以下這幾個注冊表項來為提供相應的訪問。
          HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
          LanmanServer\Parameters\NullSessionShares

          HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
          LanmanServer\Parameters\NullSessionPipes

          HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
          LanmanServer\Parameters\RestrictNullSessAccess

          32. Srinstw.exe (Service Installation Wizard)
          這個安裝服務的工具前面就已經提到過了,而且又是GUI工具,使用起來都照著提示做就可以了,這里就不再多說什么,只是注意卸載服務的時候不要把系統重要的服務趕掉就好了。

          33. Svcacls.exe (service ACL Editor)

          很可惜在這個版本的Reskit里面缺少了這個程序,非常遺憾不能對它進行測試。

          Svcacls是一個可以用來設置服務對象的ACL的命令行工具,基本上就是為了方便administrator進行委派控制而設立的。使用這個工具我們需要administrator特權,當然這個東西也是可以進行委派的。這里就提醒一點,不要刪除任何服務的adminstrators和system許可,不然的話,你可能就要從裝系統來恢復控制了。

          svcacls \\targetcomputer\Service Option

          \\targetcomputer\Service
          這個不用說了。

          Option有以下幾種

          G(grant): trustee: Permissions 增加許可。
          S(Set): trustee: Permissions 重置許可。
          R(Revoke): trustee: 刪除被賦予的explicit permissions。
          D(deny): trustee: 拒絕訪問。注意,使用這個命令的時候要很小心,一旦你用了D:everyone,連

          administrators都沒有權限來訪問這個服務了。

          你可以在一行里面使用這些命令。比如: r:username g:uername:riu。

          trustee
          你要指定的用戶。

          permissions
          相應的權限。

          有Specific許可和generic許可兩種。

          Specific permissions:

          Q: Query Service Configuration (SERVICE_QUERY_CONFIG)
          S: Query Service Status (SERVICE_QUERY_STATUS)
          E: Enumerate Dependent Services (SERVICE_ENUMERATE_DEPENDENTS)
          C: Change Service Configuration (SERVICE_CHANGE_CONFIG)
          T: Start Service (SERVICE_START)
          O: Stop Service (SERVICE_STOP)
          P: Pause/Continue Service (SERVICE_PAUSE_CONTINUE)
          I: Interrogate Service with ControlService() (SERVICE_INTERROGATE)
          U: Allow User-Defined Control Commands (SERVICE_USER_DEFINED_CONTROL)

          Generic permissions:

          F: Full Control (SERVICE_ALL_ACCESS = QSECTOPIU)
          R: Generic Read (GENERIC_READ = QSE)
          W: Generic Write (GENERIC_WRITE = C)
          X: Generic Execute (GENERIC_EXECUTE = TOPIU)

          這個工具為我們提供了一種安全性的選擇,禁止對某些服務的訪問,可以避免一些攻擊的發生。


           

          34. Svcmon.exe (service Monitoring Tool)

          這個工具可以用來監視本地或者是遠程計算機服務的狀態改變,當它發現一個服務開始或者是停止的時候,這個工具將會通過發e-mail或者是Exchange Server來通知你知道。
          這個工具由兩部分組成,Svcmon.exe這個需要你手工拷貝到%SystemRoot%\System32底下,另一個Smconfig
          是一個安裝向導。由于是圖形界面,所以我就不再多說什么東西。這里提醒一下注意,在Exchange

          Recipients那里添如你要提醒的用戶的Email。其他的按照指示做就可以了。

          35. Timethis.exe (Time This)

          我很喜歡這個工具,這個工具可以用來報告一個程序的運行時間。報告的時間可以詳細到0.001s。連net sue都可以拿來測試。 當然使用起來也很簡單。

          timethis commandname

          當你在命令中有<, >, >>,|這樣的符號的時候,請使用雙引號,比如:timethis "dir /a > a.txt"

          使用以后基本上會出來這么一個東西。

          C:\>timethis dir

          TimeThis : Command Line : dir
          TimeThis : Start Time : Sun Mar 03 17:45:27 2002

          Volume in drive C is WIN2000
          Volume Serial Number is 4CE5-8543

          Directory of C:\

          2002-02-23 22:58
          Documents and Settings
          2002-02-23 22:49
          Inetpub
          2002-03-03 11:37
          Program Files
          2002-03-03 14:15
          WINNT
          0 File(s) 0 bytes
          4 Dir(s) 9,512,271,872 bytes free

          TimeThis : Command Line : dir
          TimeThis : Start Time : Sun Mar 03 17:45:27 2002
          TimeThis : End Time : Sun Mar 03 17:45:27 2002
          TimeThis : Elapsed Time : 00:00:00.050

          36. Timezone.exe (Daylight Saving Time Update Utility)

          微軟真是奇怪,居然在ResKit里面加入了這樣的東西,一個調整夏令時的工具。我們現在又不用夏令時,沒有多大用處。隨便說說!

          timezone /g /s startdate enddate /?

          /g
          當前的情況。

          /s startdate enddate
          進行修改,格式是HourayofWeekay:Month

          Hour: 00-23
          DayofWeek: 0=Sunday 1=monday………
          Day指定發生的時間,如果上面是sunday,這里是1的話,就是該月的第一個星期天。
          Month: 1 = January 到12 = December。

          37. Tlocmgr.exe (Telephony Location Manager)

          一個用來管理TAPI的小程序,允許你方便的改變你的TAPI Location。一旦運行以后會在右下角有一個tray,這個實在沒有什么好說的。

          38. Tracedmp.exe (Trace Dump)

          這個工具也是用來處理Tracelog產生的日志的,和前面的Reducer.exe有相象之處。Tracelog產生的是不容易閱讀的,我們可以使用Tracedmp把它轉換比較容易讀的格式,比如Summary.txt這種內容少一點, 也可以是CSV可以比較詳細。還有tracedmp可以直接從Realtime buffer中直接讀出數據來處理。tracedmp解釋tracelog產生的日志是通過一個叫mofdata.guid的文件,這文件里面包含了系統的目錄服務和系統追蹤信息。

          如果要處理 其他的數據,必須把相應的信息加入到mofdata.guid中去。

          tracedmp option -h│-?

          -o 20051017183000.htm
          輸出CSV和summary文件,默認情況下是dumpfile.csv和summary.txt。這里的dumpfile.csv包括每一個
          event的詳細的信息。具體產生的日志的內容代表的信息我在這里就不詳細說了,

          1#管無M:jP提2q's00

          大家可以參看相應的資料。

          -guid
          MOF定義文件,默認的GUID是mofdata.guid,你也可以進行指定。

          -rt
          產生一個real-time trace文件。如果要指定這個選項,tracelog必須是在工作的。

          -summary
          只提供summary.txt文件。一般像這樣用就可以了,軟0g供G4W~$0CTY9Tracedmp c:\logfile.etl。你當然也可以tracedmp -rt ds,來顯示realtime記錄。

          39. Traceenable.exe (Trace Enable)

          這是一個用來enable/disable RAS/RADIUS記錄的GUI工具。這個工具允許我們修改

          HKLM\SOFTWARE\Microsoft\Tracing key下的
          EnableConsoleTracing
          EnableFileTracing
          MaxFileSize
          三個subkeys。如果你熟悉注冊表的話,也可以直接修改。圖形界面的工具就不多說了。提一下面板中的幾個選項。

          Global
          enable console tracing
          允許你實時看目錄。

          enable pool tagging
          打開system pool標記。

          Per Component
          enable console tracing
          在控制臺窗口中顯示日志跟蹤信息。

          enable file tracing
          把信息保存到一個日志文件中。一般在%windir%\tracing。

          max file size
          文件的最大尺寸。

          如果你是在一臺才安裝的計算機中啟用這個東東的話,有些鍵值會不在注冊表中,那就是說在Trace Enable中也看不到,你需要先運行RasPhone。

          40. Tracelog.exe (Trace Log)

          說了半天終于說到這個tracelog.exe了。這個命令行工具可以開始,停止,啟用跟蹤記錄,這些記錄可以用Tracedmp或者是Reducer來看。tracelog在運行時將建立一個buffer,然后如果有數據進入buffer它可以把這些數據轉換為文件保存,也可以進行實時的跟蹤,這個時候我們可以用如tracedmp這樣的應用程序讀出buffer中的數據。

          tracelog managementoption bufferoption logfileoption Systemleveltracingoption

          Provider-specificOption -h│-?

          managementOption: Starting, stopping, updating and querying

          -guid file
          和tracedmp中的是一樣的,都是表示provider的信息。如果開始System tracing可以不用提供Guid,如果是directory service events我們可以指定control.guid。

          -start logger_name
          開始一個trace會話。你要提供一個日志名字,如果是一個system trace可以不需要指定,默認的名字為“NT
          Kernel logger”。

          -stop logger_name
          終止trace會話。如果是system trace可以不用指定logger_name。

          -update option logger_name
          升級當前的trace會話。這個東西在你想改變文件的名字,buffer的參數,realtime模式等時候就會被用到。
          以下這些option可以在kernel logger中用到。

          -rt
          模式開關,調整realtime mode。

          -f logfile_name
          指定新的log文件的名字。

          -ft n
          改變buffer的刷新計數器。

          -max n
          改變buffer的大小。

          "-nodisk" "-noprocess" "-nothread" "-nonet" "-fio" "-pf" "-hf" "-img" "-cm"
          NT kernel logger的一些標志。

          上面這些調整可以一次進行,如:tracelog -update -rt -max 40。

          -x
          停止所有活動的會話。

          -l
          查詢在工作的traces。

          -q
          只查詢system trace。

          BufferOption

          -b n
          設置buffer的大小為n kb。小的buffer會導致經常刷新buffer,

          N%網Q_:j專軟國XE

          基本上使用默認就好。

          -min n
          設置最小buffer,默認是2。

          -max n
          設置最大buffer,默認是25。

          -ft n_seconds
          設置刷新時間。

          -age n_minutes
          修改老化時間。就是分配的buffer沒有使用,

          ?件_F件}Rw_c

          會在多長時間內被釋放。

          LogfileOption

          -rt b
          啟用real time mode。

          -f name
          日志的名字。默認是c:\logfile.etl,如果要使用不同的名字用-o 20051017183000.htm。

          -seq n_mbyte
          一直使用到n_mbyte。

          -cir n_mbyte
          循環使用n_mbyte。


          Systemleveltracingoption
          為kernel tracing提供更多的選項。
          默認情況下kernel tracing包括
          Process start/end
          Disk I/O
          Network TCP/IP, UDP/IP
          Thread start/end

          只有在使用一些開關后,I2R$軟+(網u.I}供@=`R才會產生下面的內容。
          Image Load
          Registry calls
          File I/O
          Page Fault
          但是trace這些東西會產生很大的負擔。

          -fio
          啟用file I/O tracing。

          -pf
          啟用page faults tracing。

          -hf
          啟用hard faults tracing。

          -img
          啟用image load tracing。

          -um
          啟用Process Private tracing。這種情況下buffer建立在Private Process space中,默認是在kernel

          space中。

          -nf
          每n mb更新文件。

          ProviderSpecificOption: Provider Level Options

          -level n

          -flags

          這些都和相應的provider有關。

          下面看個例子,

          打開trace。
          c:\>tracelog start
          Logger Started...
          Operation Status: 0L
          The operation completed successfully.

          Logger Name: NT Kernel Logger
          Logger Id: ffff
          Logger Thread Id: 1360
          Buffer Size: 8 Kb
          Maximum Buffers: 25
          Minimum Buffers: 2
          Number of Buffers: 2
          Free Buffers: 1
          Buffers Written: 3
          Events Lost: 0
          Log Buffers Lost: 0
          Real Time Buffers Lost: 0
          Log File Mode: Sequential
          Enabled tracing: Process Thread Disk TcpIp
          Log Filename: C:\LogFile.Etl

          停止trace
          C:\>tracelog

          posted @ 2007-08-21 16:54 siwei 閱讀(308) | 評論 (0)編輯 收藏

          方法一:
          驗證碼無法顯示的原因是XBM被屏蔽,只需要修復注冊表相關項即可:

          打開記事本,把這一段粘貼進去:
          REGEDIT4

          [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Security]
          "BlockXBM"=dword:00000000

          另存為  a.reg即可,運行后,重新打開瀏覽器。


          方法二:
          今天上網,居然就發現圖形驗證碼無法顯示了.郁悶了老半天,找了這個辦法
          1、運行注冊表編輯器
          2、依次點開HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Internet&nbsp;Explorer\\Security;
          3、在屏幕右邊空白處點擊鼠標右鍵,選擇新建一個名為;“BlockXBM”為的;DWORD&nbsp;鍵,其值為默認的0
          4、退出注冊表編輯器。

          posted @ 2007-08-21 16:48 siwei| 編輯 收藏

          2007年6月18日

          1 定義頭和根元素

          部署描述符文件就像所有XML文件一樣,必須以一個XML頭開始。這個頭聲明可以使用的XML版本并給出文件的字符編碼。
          DOCYTPE聲明必須立即出現在此頭之后。這個聲明告訴服務器適用的servlet規范的版本(如2.2或2.3)并指定管理此文件其余部分內容的語法的DTD(Document Type Definition,文檔類型定義)。
          所有部署描述符文件的頂層(根)元素為web-app。請注意,XML元素不像HTML,他們是大小寫敏感的。因此,web-App和WEB-APP都是不合法的,web-app必須用小寫。

          2 部署描述符文件內的元素次序

          XML 元素不僅是大小寫敏感的,而且它們還對出現在其他元素中的次序敏感。例如,XML頭必須是文件中的第一項,DOCTYPE聲明必須是第二項,而web- app元素必須是第三項。在web-app元素內,元素的次序也很重要。服務器不一定強制要求這種次序,但它們允許(實際上有些服務器就是這樣做的)完全拒絕執行含有次序不正確的元素的Web應用。這表示使用非標準元素次序的web.xml文件是不可移植的。
          下面的列表給出了所有可直接出現在web-app元素內的合法元素所必需的次序。例如,此列表說明servlet元素必須出現在所有servlet-mapping元素之前。請注意,所有這些元素都是可選的。因此,可以省略掉某一元素,但不能把它放于不正確的位置。
          l icon icon元素指出IDE和GUI工具用來表示Web應用的一個和兩個圖像文件的位置。
          l display-name display-name元素提供GUI工具可能會用來標記這個特定的Web應用的一個名稱。
          l description description元素給出與此有關的說明性文本。
          l context-param context-param元素聲明應用范圍內的初始化參數。
          l filter 過濾器元素將一個名字與一個實現javax.servlet.Filter接口的類相關聯。
          l filter-mapping 一旦命名了一個過濾器,就要利用filter-mapping元素把它與一個或多個servlet或JSP頁面相關聯。
          l listener servlet API的版本2.3增加了對事件監聽程序的支持,事件監聽程序在建立、修改和刪除會話或servlet環境時得到通知。Listener元素指出事件監聽程序類。
          l servlet 在向servlet或JSP頁面制定初始化參數或定制URL時,必須首先命名servlet或JSP頁面。Servlet元素就是用來完成此項任務的。
          l servlet-mapping 服務器一般為servlet提供一個缺省的URL:http://host/webAppPrefix/servlet/ServletName。但是,常常會更改這個URL,以便servlet可以訪問初始化參數或更容易地處理相對URL。在更改缺省URL時,使用servlet-mapping元素。
          l session-config 如果某個會話在一定時間內未被訪問,服務器可以拋棄它以節省內存。可通過使用HttpSession的setMaxInactiveInterval方法明確設置單個會話對象的超時值,或者可利用session-config元素制定缺省超時值。
          l mime-mapping 如果Web應用具有想到特殊的文件,希望能保證給他們分配特定的MIME類型,則mime-mapping元素提供這種保證。
          l welcom-file-list welcome-file-list元素指示服務器在收到引用一個目錄名而不是文件名的URL時,使用哪個文件。
          l error-page error-page元素使得在返回特定HTTP狀態代碼時,或者特定類型的異常被拋出時,能夠制定將要顯示的頁面。
          l taglib taglib元素對標記庫描述符文件(Tag Libraryu Descriptor file)指定別名。此功能使你能夠更改TLD文件的位置,而不用編輯使用這些文件的JSP頁面。
          l resource-env-ref resource-env-ref元素聲明與資源相關的一個管理對象。
          l resource-ref resource-ref元素聲明一個資源工廠使用的外部資源。
          l security-constraint security-constraint元素制定應該保護的URL。它與login-config元素聯合使用
          l login-config 用login-config元素來指定服務器應該怎樣給試圖訪問受保護頁面的用戶授權。它與sercurity-constraint元素聯合使用。
          l security-role security-role元素給出安全角色的一個列表,這些角色將出現在servlet元素內的security-role-ref元素的role-name子元素中。分別地聲明角色可使高級IDE處理安全信息更為容易。
          l env-entry env-entry元素聲明Web應用的環境項。
          l ejb-ref ejb-ref元素聲明一個EJB的主目錄的引用。
          l ejb-local-ref ejb-local-ref元素聲明一個EJB的本地主目錄的應用。

          3 分配名稱和定制的UL

          在web.xml中完成的一個最常見的任務是對servlet或JSP頁面給出名稱和定制的URL。用servlet元素分配名稱,使用servlet-mapping元素將定制的URL與剛分配的名稱相關聯。
          3.1 分配名稱
          為了提供初始化參數,對servlet或JSP頁面定義一個定制URL或分配一個安全角色,必須首先給servlet或JSP頁面一個名稱。可通過 servlet元素分配一個名稱。最常見的格式包括servlet-name和servlet-class子元素(在web-app元素內),如下所示:
          <servlet>
          <servlet-name>Test</servlet-name>
          <servlet-class>moreservlets.TestServlet</servlet-class>
          </servlet>

          這表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已經得到了注冊名Test。給 servlet一個名稱具有兩個主要的含義。首先,初始化參數、定制的URL模式以及其他定制通過此注冊名而不是類名引用此servlet。其次,可在 URL而不是類名中使用此名稱。因此,利用剛才給出的定義,URL http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的場所。
          請記住:XML元素不僅是大小寫敏感的,而且定義它們的次序也很重要。例如,web-app元素內所有servlet元素必須位于所有servlet- mapping元素(下一小節介紹)之前,而且還要位于5.6節和5.11節討論的與過濾器或文檔相關的元素(如果有的話)之前。類似地,servlet 的servlet-name子元素也必須出現在servlet-class之前。5.2節"部署描述符文件內的元素次序"將詳細介紹這種必需的次序。
          例如,程序清單5-1給出了一個名為TestServlet的簡單servlet,它駐留在moreservlets程序包中。因為此servlet是扎根在一個名為deployDemo的目錄中的Web應用的組成部分,所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。程序清單5-2給出將放置在deployDemo/WEB-INF/內的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素將名稱Test與TestServlet.class相關聯。圖 5-1和圖5-2分別顯示利用缺省URL和注冊名調用TestServlet時的結果。

          程序清單5-1 TestServlet.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;

          /** Simple servlet used to illustrate servlet naming
          * and custom URLs.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          * http://www.moreservlets.com/.
          * &copy; 2002 Marty Hall; may be freely used or adapted.
          */

          public class TestServlet extends HttpServlet {
          public void doGet(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType("text/html");
          PrintWriter out = response.getWriter();
          String uri = request.getRequestURI();
          out.println(ServletUtilities.headWithTitle("Test Servlet") +
          "<BODY BGCOLOR=\"#FDF5E6\">\n" +
          "<H2>URI: " + uri + "</H2>\n" +
          "</BODY></HTML>");
          }
          }


          程序清單5-2 web.xml(說明servlet名稱的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- … -->
          <servlet>
          <servlet-name>Test</servlet-name>
          <servlet-class>moreservlets.TestServlet</servlet-class>
          </servlet>
          <!-- … -->
          </web-app>

          3.2 定義定制的URL
          大多數服務器具有一個缺省的serlvet URL:
          http://host/webAppPrefix/servlet/packageName.ServletName。雖然在開發中使用這個URL很方便,但是我們常常會希望另一個URL用于部署。例如,可能會需要一個出現在Web應用頂層的URL(如,http: //host/webAppPrefix/Anyname),并且在此URL中沒有servlet項。位于頂層的URL簡化了相對URL的使用。此外,對許多開發人員來說,頂層URL看上去比更長更麻煩的缺省URL更簡短。
          事實上,有時需要使用定制的URL。比如,你可能想關閉缺省URL映射,以便更好地強制實施安全限制或防止用戶意外地訪問無初始化參數的servlet。如果你禁止了缺省的URL,那么你怎樣訪問servlet呢?這時只有使用定制的URL了。
          為了分配一個定制的URL,可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一個任意名稱,可利用此名稱引用相應的servlet;url-pattern描述了相對于Web應用的根目錄的URL。url- pattern元素的值必須以斜杠(/)起始。
          下面給出一個簡單的web.xml摘錄,它允許使用URL http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test或
          http: //host/webAppPrefix/servlet/moreservlets.TestServlet。請注意,仍然需要XML頭、 DOCTYPE聲明以及web-app封閉元素。此外,可回憶一下,XML元素出現地次序不是隨意的。特別是,需要把所有servlet元素放在所有 servlet-mapping元素之前。
          <servlet>
          <servlet-name>Test</servlet-name>
          <servlet-class>moreservlets.TestServlet</servlet-class>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name>Test</servlet-name>
          <url-pattern>/UrlTest</url-pattern>
          </servlet-mapping>
          URL模式還可以包含通配符。例如,下面的小程序指示服務器發送所有以Web應用的URL前綴開始,以..asp結束的請求到名為BashMS的servlet。
          <servlet>
          <servlet-name>BashMS</servlet-name>
          <servlet-class>msUtils.ASPTranslator</servlet-class>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name>BashMS</servlet-name>
          <url-pattern>/*.asp</url-pattern>
          </servlet-mapping>
          3.3 命名JSP頁面
          因為JSP頁面要轉換成sevlet,自然希望就像命名servlet一樣命名JSP頁面。畢竟,JSP頁面可能會從初始化參數、安全設置或定制的URL中受益,正如普通的serlvet那樣。雖然JSP頁面的后臺實際上是servlet這句話是正確的,但存在一個關鍵的猜疑:即,你不知道JSP頁面的實際類名(因為系統自己挑選這個名字)。因此,為了命名JSP頁面,可將jsp-file元素替換為servlet-calss元素,如下所示:
          <servlet>
          <servlet-name>Test</servlet-name>
          <jsp-file>/TestPage.jsp</jsp-file>
          </servlet>
          命名JSP頁面的原因與命名servlet的原因完全相同:即為了提供一個與定制設置(如,初始化參數和安全設置)一起使用的名稱,并且,以便能更改激活 JSP頁面的URL(比方說,以便多個URL通過相同頁面得以處理,或者從URL中去掉.jsp擴展名)。但是,在設置初始化參數時,應該注意,JSP頁面是利用jspInit方法,而不是init方法讀取初始化參數的。
          例如,程序清單5-3給出一個名為TestPage.jsp的簡單JSP頁面,它的工作只是打印出用來激活它的URL的本地部分。TestPage.jsp放置在deployDemo應用的頂層。程序清單5-4給出了用來分配一個注冊名PageName,然后將此注冊名與http://host/webAppPrefix/UrlTest2/anything 形式的URL相關聯的web.xml文件(即,deployDemo/WEB-INF/web.xml)的一部分。

          程序清單5-3 TestPage.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE>
          JSP Test Page
          </TITLE>
          </HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>URI: <%= request.getRequestURI() %></H2>
          </BODY>
          </HTML>


          程序清單5-4 web.xml(說明JSP頁命名的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>PageName</servlet-name>
          <jsp-file>/TestPage.jsp</jsp-file>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> PageName </servlet-name>
          <url-pattern>/UrlTest2/*</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          4 禁止激活器servlet

          對servlet或JSP頁面建立定制URL的一個原因是,這樣做可以注冊從 init(servlet)或jspInit(JSP頁面)方法中讀取得初始化參數。但是,初始化參數只在是利用定制URL模式或注冊名訪問 servlet或JSP頁面時可以使用,用缺省URL http://host/webAppPrefix/servlet/ServletName 訪問時不能使用。因此,你可能會希望關閉缺省URL,這樣就不會有人意外地調用初始化servlet了。這個過程有時稱為禁止激活器servlet,因為多數服務器具有一個用缺省的servlet URL注冊的標準servlet,并激活缺省的URL應用的實際servlet。
          有兩種禁止此缺省URL的主要方法:
          l 在每個Web應用中重新映射/servlet/模式。
          l 全局關閉激活器servlet。
          重要的是應該注意到,雖然重新映射每個Web應用中的/servlet/模式比徹底禁止激活servlet所做的工作更多,但重新映射可以用一種完全可移植的方式來完成。相反,全局禁止激活器servlet完全是針對具體機器的,事實上有的服務器(如ServletExec)沒有這樣的選擇。下面的討論對每個Web應用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的詳細內容。
          4.1 重新映射/servlet/URL模式
          在一個特定的Web應用中禁止以http://host/webAppPrefix/servlet/ 開始的URL的處理非常簡單。所需做的事情就是建立一個錯誤消息servlet,并使用前一節討論的url-pattern元素將所有匹配請求轉向該 servlet。只要簡單地使用:
          <url-pattern>/servlet/*</url-pattern>
          作為servlet-mapping元素中的模式即可。
          例如,程序清單5-5給出了將SorryServlet servlet(程序清單5-6)與所有以http://host/webAppPrefix/servlet/ 開頭的URL相關聯的部署描述符文件的一部分。

          程序清單5-5 web.xml(說明JSP頁命名的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>Sorry</servlet-name>
          <servlet-class>moreservlets.SorryServlet</servlet-class>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> Sorry </servlet-name>
          <url-pattern>/servlet/*</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          程序清單5-6 SorryServlet.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;

          /** Simple servlet used to give error messages to
          * users who try to access default servlet URLs
          * (i.e., http://host/webAppPrefix/servlet/ServletName)
          * in Web applications that have disabled this
          * behavior.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          * http://www.moreservlets.com/.
          * &copy; 2002 Marty Hall; may be freely used or adapted.
          */

          public class SorryServlet extends HttpServlet {
          public void doGet(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType("text/html");
          PrintWriter out = response.getWriter();
          String title = "Invoker Servlet Disabled.";
          out.println(ServletUtilities.headWithTitle(title) +
          "<BODY BGCOLOR=\"#FDF5E6\">\n" +
          "<H2>" + title + "</H2>\n" +
          "Sorry, access to servlets by means of\n" +
          "URLs that begin with\n" +
          "http://host/webAppPrefix/servlet/\n" +
          "has been disabled.\n" +
          "</BODY></HTML>");
          }

          public void doPost(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          doGet(request, response);
          }
          }


          4.2 全局禁止激活器:Tomcat
          Tomcat 4中用來關閉缺省URL的方法與Tomcat 3中所用的很不相同。下面介紹這兩種方法:
          1.禁止激活器: Tomcat 4
          Tomcat 4用與前面相同的方法關閉激活器servlet,即利用web.xml中的url-mapping元素進行關閉。不同之處在于Tomcat使用了放在 install_dir/conf中的一個服務器專用的全局web.xml文件,而前面使用的是存放在每個Web應用的WEB-INF目錄中的標準 web.xml文件。
          因此,為了在Tomcat 4中關閉激活器servlet,只需在install_dir/conf/web.xml中簡單地注釋出/servlet/* URL映射項即可,如下所示:
          <!--
          <servlet-mapping>
          <servlet-name>invoker</servlet-name>
          <url-pattern>/servlet/*</url-pattern>
          </servlet-mapping>
          -->
          再次提醒,應該注意這個項是位于存放在install_dir/conf的Tomcat專用的web.xml文件中的,此文件不是存放在每個Web應用的WEB-INF目錄中的標準web.xml。
          2.禁止激活器:Tomcat3
          在Apache Tomcat的版本3中,通過在install_dir/conf/server.xml中注釋出InvokerInterceptor項全局禁止缺省 servlet URL。例如,下面是禁止使用缺省servlet URL的server.xml文件的一部分。
          <!--
          <RequsetInterceptor
          className="org.apache.tomcat.request.InvokerInterceptor"
          debug="0" prefix="/servlet/" />
          -->

          5 初始化和預裝載servlet與JSP頁面

          這里討論控制servlet和JSP頁面的啟動行為的方法。特別是,說明了怎樣分配初始化參數以及怎樣更改服務器生存期中裝載servlet和JSP頁面的時刻。
          5.1 分配servlet初始化參數
          利用init-param元素向servlet提供初始化參數,init-param元素具有param-name和param-value子元素。例如,在下面的例子中,如果initServlet servlet是利用它的注冊名(InitTest)訪問的,它將能夠從其方法中調用getServletConfig(). getInitParameter("param1")獲得"Value 1",調用getServletConfig().getInitParameter("param2")獲得"2"。
          <servlet>
          <servlet-name>InitTest</servlet-name>
          <servlet-class>moreservlets.InitServlet</servlet-class>
          <init-param>
          <param-name>param1</param-name>
          <param-value>value1</param-value>
          </init-param>
          <init-param>
          <param-name>param2</param-name>
          <param-value>2</param-value>
          </init-param>
          </servlet>
          在涉及初始化參數時,有幾點需要注意:
          l 返回值。GetInitParameter的返回值總是一個String。因此,在前一個例子中,可對param2使用Integer.parseInt獲得一個int。
          l JSP中的初始化。JSP頁面使用jspInit而不是init。JSP頁面還需要使用jsp-file元素代替servlet-class。
          l 缺省URL。初始化參數只在通過它們的注冊名或與它們注冊名相關的定制URL模式訪問Servlet時可以使用。因此,在這個例子中,param1和 param2初始化參數將能夠在使用URL http://host/webAppPrefix/servlet/InitTest 時可用,但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 時不能使用。
          例如,程序清單5-7給出一個名為InitServlet的簡單servlet,它使用init方法設置firstName和emailAddress字段。程序清單5-8給出分配名稱InitTest給servlet的web.xml文件。
          程序清單5-7 InitServlet.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;

          /** Simple servlet used to illustrate servlet
          * initialization parameters.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          * http://www.moreservlets.com/.
          * &copy; 2002 Marty Hall; may be freely used or adapted.
          */

          public class InitServlet extends HttpServlet {
          private String firstName, emailAddress;

          public void init() {
          ServletConfig config = getServletConfig();
          firstName = config.getInitParameter("firstName");
          emailAddress = config.getInitParameter("emailAddress");
          }

          public void doGet(HttpServletRequest request,
          HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType("text/html");
          PrintWriter out = response.getWriter();
          String uri = request.getRequestURI();
          out.println(ServletUtilities.headWithTitle("Init Servlet") +
          "<BODY BGCOLOR=\"#FDF5E6\">\n" +
          "<H2>Init Parameters:</H2>\n" +
          "<UL>\n" +
          "<LI>First name: " + firstName + "\n" +
          "<LI>Email address: " + emailAddress + "\n" +
          "</UL>\n" +
          "</BODY></HTML>");
          }
          }


          程序清單5-8 web.xml(說明初始化參數的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>InitTest</servlet-name>
          <servlet-class>moreservlets.InitServlet</servlet-class>
          <init-param>
          <param-name>firstName</param-name>
          <param-value>Larry</param-value>
          </init-param>
          <init-param>
          <param-name>emailAddress</param-name>
          <param-value>Ellison@Microsoft.com</param-value>
          </init-param>
          </servlet>
          <!-- ... -->
          </web-app>

          5.2 分配JSP初始化參數
          給JSP頁面提供初始化參數在三個方面不同于給servlet提供初始化參數。
          1)使用jsp-file而不是servlet-class。因此,WEB-INF/web.xml文件的servlet元素如下所示:
          <servlet>
          <servlet-name>PageName</servlet-name>
          <jsp-file>/RealPage.jsp</jsp-file>
          <init-param>
          <param-name>...</param-name>
          <param-value>...</param-value>
          </init-param>
          ...
          </servlet>
          2) 幾乎總是分配一個明確的URL模式。對servlet,一般相應地使用以http://host/webAppPrefix/servlet/ 開始的缺省URL。只需記住,使用注冊名而不是原名稱即可。這對于JSP頁面在技術上也是合法的。例如,在上面給出的例子中,可用URL http://host/webAppPrefix/servlet/PageName 訪問RealPage.jsp的對初始化參數具有訪問權的版本。但在用于JSP頁面時,許多用戶似乎不喜歡應用常規的servlet的URL。此外,如果 JSP頁面位于服務器為其提供了目錄清單的目錄中(如,一個既沒有index.html也沒有index.jsp文件的目錄),則用戶可能會連接到此 JSP頁面,單擊它,從而意外地激活未初始化的頁面。因此,好的辦法是使用url-pattern(5.3節)將JSP頁面的原URL與注冊的 servlet名相關聯。這樣,客戶機可使用JSP頁面的普通名稱,但仍然激活定制的版本。例如,給定來自項目1的servlet定義,可使用下面的 servlet-mapping定義:
          <servlet-mapping>
          <servlet-name>PageName</servlet-name>
          <url-pattern>/RealPage.jsp</url-pattern>
          </servlet-mapping>
          3)JSP頁使用jspInit而不是init。自動從JSP頁面建立的servlet或許已經使用了inti方法。因此,使用JSP聲明提供一個init方法是不合法的,必須制定jspInit方法。
          為了說明初始化JSP頁面的過程,程序清單5-9給出了一個名為InitPage.jsp的JSP頁面,它包含一個jspInit方法且放置于 deployDemo Web應用層次結構的頂層。一般,http://host/deployDemo/InitPage.jsp 形式的URL將激活此頁面的不具有初始化參數訪問權的版本,從而將對firstName和emailAddress變量顯示null。但是, web.xml文件(程序清單5-10)分配了一個注冊名,然后將該注冊名與URL模式/InitPage.jsp相關聯。

          程序清單5-9 InitPage.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD><TITLE>JSP Init Test</TITLE></HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>Init Parameters:</H2>
          <UL>
          <LI>First name: <%= firstName %>
          <LI>Email address: <%= emailAddress %>
          </UL>
          </BODY></HTML>
          <%!
          private String firstName, emailAddress;

          public void jspInit() {
          ServletConfig config = getServletConfig();
          firstName = config.getInitParameter("firstName");
          emailAddress = config.getInitParameter("emailAddress");
          }
          %>


          程序清單5-10 web.xml(說明JSP頁面的init參數的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet>
          <servlet-name>InitPage</servlet-name>
          <jsp-file>/InitPage.jsp</jsp-file>
          <init-param>
          <param-name>firstName</param-name>
          <param-value>Bill</param-value>
          </init-param>
          <init-param>
          <param-name>emailAddress</param-name>
          <param-value>gates@oracle.com</param-value>
          </init-param>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> InitPage</servlet-name>
          <url-pattern>/InitPage.jsp</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          5.3 提供應用范圍內的初始化參數
          一般,對單個地servlet或JSP頁面分配初始化參數。指定的servlet或JSP頁面利用ServletConfig的getInitParameter方法讀取這些參數。但是,在某些情形下,希望提供可由任意servlet或JSP頁面借助ServletContext的getInitParameter方法讀取的系統范圍內的初始化參數。
          可利用context-param元素聲明這些系統范圍內的初始化值。context-param元素應該包含param-name、param-value以及可選的description子元素,如下所示:
          <context-param>
          <param-name>support-email</param-name>
          <param-value>blackhole@mycompany.com</param-value>
          </context-param>
          可回憶一下,為了保證可移植性,web.xml內的元素必須以正確的次序聲明。但這里應該注意,context-param元素必須出現任意與文檔有關的元素(icon、display-name或description)之后及filter、filter-mapping、listener或 servlet元素之前。
          5.4 在服務器啟動時裝載servlet
          假如servlet或JSP頁面有一個要花很長時間執行的init (servlet)或jspInit(JSP)方法。例如,假如init或jspInit方法從某個數據庫或ResourceBundle查找產量。這種情況下,在第一個客戶機請求時裝載servlet的缺省行為將對第一個客戶機產生較長時間的延遲。因此,可利用servlet的load-on- startup元素規定服務器在第一次啟動時裝載servlet。下面是一個例子。
          <servlet>
          <servlet-name> … </servlet-name>
          <servlet-class> … </servlet-class> <!-- Or jsp-file -->
          <load-on-startup/>
          </servlet>
          可以為此元素體提供一個整數而不是使用一個空的load-on-startup。想法是服務器應該在裝載較大數目的servlet或JSP頁面之前裝載較少數目的servlet或JSP頁面。例如,下面的servlet項(放置在Web應用的WEB-INF目錄下的web.xml文件中的web-app元素內)將指示服務器首先裝載和初始化SearchServlet,然后裝載和初始化由位于Web應用的result目錄中的index.jsp文件產生的 servlet。
          <servlet>
          <servlet-name>Search</servlet-name>
          <servlet-class>myPackage.SearchServlet</servlet-class> <!-- Or jsp-file -->
          <load-on-startup>1</load-on-startup>
          </servlet>
          <servlet>
          <servlet-name>Results</servlet-name>
          <servlet-class>/results/index.jsp</servlet-class> <!-- Or jsp-file -->
          <load-on-startup>2</load-on-startup>
          </servlet>

          6 聲明過濾器

          servlet版本2.3引入了過濾器的概念。雖然所有支持servlet API版本2.3的服務器都支持過濾器,但為了使用與過濾器有關的元素,必須在web.xml中使用版本2.3的DTD。
          過濾器可截取和修改進入一個servlet或JSP頁面的請求或從一個servlet或JSP頁面發出的相應。在執行一個servlet或JSP頁面之前,必須執行第一個相關的過濾器的doFilter方法。在該過濾器對其FilterChain對象調用doFilter時,執行鏈中的下一個過濾器。如果沒有其他過濾器,servlet或JSP頁面被執行。過濾器具有對到來的ServletRequest對象的全部訪問權,因此,它們可以查看客戶機名、查找到來的cookie等。為了訪問servlet或JSP頁面的輸出,過濾器可將響應對象包裹在一個替身對象(stand-in object)中,比方說把輸出累加到一個緩沖區。在調用FilterChain對象的doFilter方法之后,過濾器可檢查緩沖區,如有必要,就對它進行修改,然后傳送到客戶機。
          例如,程序清單5-11帝國難以了一個簡單的過濾器,只要訪問相關的servlet或JSP頁面,它就截取請求并在標準輸出上打印一個報告(開發過程中在桌面系統上運行時,大多數服務器都可以使用這個過濾器)。

          程序清單5-11 ReportFilter.java
          package moreservlets;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.util.*;

          /** Simple filter that prints a report on the standard output
          * whenever the associated servlet or JSP page is accessed.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          * http://www.moreservlets.com/.
          * &copy; 2002 Marty Hall; may be freely used or adapted.
          */

          public class ReportFilter implements Filter {
          public void doFilter(ServletRequest request,
          ServletResponse response,
          FilterChain chain)
          throws ServletException, IOException {
          HttpServletRequest req = (HttpServletRequest)request;
          System.out.println(req.getRemoteHost() +
          " tried to access " +
          req.getRequestURL() +
          " on " + new Date() + ".");
          chain.doFilter(request,response);
          }

          public void init(FilterConfig config)
          throws ServletException {
          }

          public void destroy() {}
          }

          一旦建立了一個過濾器,可以在web.xml中利用filter元素以及filter-name(任意名稱)、file-class(完全限定的類名)和(可選的)init-params子元素聲明它。請注意,元素在web.xml的web-app元素中出現的次序不是任意的;允許服務器(但不是必需的)強制所需的次序,并且實際中有些服務器也是這樣做的。但這里要注意,所有filter元素必須出現在任意filter-mapping元素之前, filter-mapping元素又必須出現在所有servlet或servlet-mapping元素之前。
          例如,給定上述的ReportFilter類,可在web.xml中作出下面的filter聲明。它把名稱Reporter與實際的類ReportFilter(位于moreservlets程序包中)相關聯。
          <filter>
          <filter-name>Reporter</filter-name>
          <filter-class>moresevlets.ReportFilter</filter-class>
          </filter>
          一旦命名了一個過濾器,可利用filter-mapping元素把它與一個或多個servlet或JSP頁面相關聯。關于此項工作有兩種選擇。
          首先,可使用filter-name和servlet-name子元素把此過濾器與一個特定的servlet名(此servlet名必須稍后在相同的 web.xml文件中使用servlet元素聲明)關聯。例如,下面的程序片斷指示系統只要利用一個定制的URL訪問名為SomeServletName 的servlet或JSP頁面,就運行名為Reporter的過濾器。
          <filter-mapping>
          <filter-name>Reporter</filter-name>
          <servlet-name>SomeServletName</servlet-name>
          </filter-mapping>
          其次,可利用filter-name和url-pattern子元素將過濾器與一組servlet、JSP頁面或靜態內容相關聯。例如,相面的程序片段指示系統只要訪問Web應用中的任意URL,就運行名為Reporter的過濾器。
          <filter-mapping>
          <filter-name>Reporter</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
          例如,程序清單5-12給出了將ReportFilter過濾器與名為PageName的servlet相關聯的web.xml文件的一部分。名字 PageName依次又與一個名為TestPage.jsp的JSP頁面以及以模式http: //host/webAppPrefix/UrlTest2/ 開頭的URL相關聯。TestPage.jsp的源代碼已經JSP頁面命名的談論在前面的3節"分配名稱和定制的URL"中給出。事實上,程序清單5- 12中的servlet和servlet-name項從該節原封不動地拿過來的。給定這些web.xml項,可看到下面的標準輸出形式的調試報告(換行是為了容易閱讀)。
          audit.irs.gov tried to access
          http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html
          on Tue Dec 25 13:12:29 EDT 2001.

          程序清單5-12 Web.xml(說明filter用法的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <filter>
          <filter-name>Reporter</filter-name>
          <filter-class>moresevlets.ReportFilter</filter-class>
          </filter>
          <!-- ... -->
          <filter-mapping>
          <filter-name>Reporter</filter-name>
          <servlet-name>PageName</servlet-name>
          </filter-mapping>
          <!-- ... -->
          <servlet>
          <servlet-name>PageName</servlet-name>
          <jsp-file>/RealPage.jsp</jsp-file>
          </servlet>
          <!-- ... -->
          <servlet-mapping>
          <servlet-name> PageName </servlet-name>
          <url-pattern>/UrlTest2/*</url-pattern>
          </servlet-mapping>
          <!-- ... -->
          </web-app>


          7 指定歡迎頁

          假如用戶提供了一個像http: //host/webAppPrefix/directoryName/ 這樣的包含一個目錄名但沒有包含文件名的URL,會發生什么事情呢?用戶能得到一個目錄表?一個錯誤?還是標準文件的內容?如果得到標準文件內容,是 index.html、index.jsp、default.html、default.htm或別的什么東西呢?
          Welcome-file-list 元素及其輔助的welcome-file元素解決了這個模糊的問題。例如,下面的web.xml項指出,如果一個URL給出一個目錄名但未給出文件名,服務器應該首先試用index.jsp,然后再試用index.html。如果兩者都沒有找到,則結果有賴于所用的服務器(如一個目錄列表)。
          <welcome-file-list>
          <welcome-file>index.jsp</welcome-file>
          <welcome-file>index.html</welcome-file>
          </welcome-file-list>
          雖然許多服務器缺省遵循這種行為,但不一定必須這樣。因此,明確地使用welcom-file-list保證可移植性是一種良好的習慣。

          8 指定處理錯誤的頁面

          現在我了解到,你在開發servlet和JSP頁面時從不會犯錯誤,而且你的所有頁面是那樣的清晰,一般的程序員都不會被它們的搞糊涂。但是,是人總會犯錯誤的,用戶可能會提供不合規定的參數,使用不正確的URL或者不能提供必需的表單字段值。除此之外,其它開發人員可能不那么細心,他們應該有些工具來克服自己的不足。
          error-page元素就是用來克服這些問題的。它有兩個可能的子元素,分別是:error-code和exception- type。第一個子元素error-code指出在給定的HTTP錯誤代碼出現時使用的URL。第二個子元素excpetion-type指出在出現某個給定的Java異常但未捕捉到時使用的URL。error-code和exception-type都利用location元素指出相應的URL。此 URL必須以/開始。location所指出的位置處的頁面可通過查找HttpServletRequest對象的兩個專門的屬性來訪問關于錯誤的信息,這兩個屬性分別是:javax.servlet.error.status_code和javax.servlet.error.message。
          可回憶一下,在web.xml內以正確的次序聲明web-app的子元素很重要。這里只要記住,error-page出現在web.xml文件的末尾附近,servlet、servlet-name和welcome-file-list之后即可。

          8.1 error-code元素
          為了更好地了解error-code元素的值,可考慮一下如果不正確地輸入文件名,大多數站點會作出什么反映。這樣做一般會出現一個404錯誤信息,它表示不能找到該文件,但幾乎沒提供更多有用的信息。另一方面,可以試一下在www.microsoft.com、www.ibm.com 處或者特別是在www.bea.com 處輸出未知的文件名。這是會得出有用的消息,這些消息提供可選擇的位置,以便查找感興趣的頁面。提供這樣有用的錯誤頁面對于Web應用來說是很有價值得。事實上,http://www.plinko.net/404/ 就是把整個站點專門用于404錯誤頁面這個內容。這個站點包含來自全世界最好、最糟和最搞笑的404頁面。
          程序清單5-13給出一個JSP頁面,此頁面可返回給提供位置程序名的客戶機。程序清單5-14給出指定程序清單5-13作為返回404錯誤代碼時顯示的頁面的web.xml。請注意,瀏覽器中顯示的URL仍然是客戶機所提供的。錯誤頁面是一種后臺實現技術。
          最后一點,請記住IE5的缺省配置顯然不符合HTTP規范,它忽略了服務器生成的錯誤消息,而是顯示自己的標準出錯信息。可轉到其Tools菜單,選擇 Internet Options,單擊Advanced,取消Show Friendly HTTP Error Message來解決此問題。

          程序清單5-13 NotFound.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD><TITLE>404: Not Found</TITLE></HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>Error!</H2>
          I'm sorry, but I cannot find a page that matches
          <%= request.getRequestURI() %> on the system. Maybe you should
          try one of the following:
          <UL>
          <LI>Go to the server's <A HREF="/">home page</A>.
          <LI>Search for relevant pages.<BR>
          <FORM ACTION="http://www.google.com/search">
          <CENTER>
          Keywords: <INPUT TYPE="TEXT" NAME="q"><BR>
          <INPUT TYPE="SUBMIT" VALUE="Search">
          </CENTER>
          </FORM>
          <LI>Admire a random multiple of 404:
          <%= 404*((int)(1000*Math.random())) %>.
          <LI>Try a <A >
          random 404 error message</A>. From the amazing and
          amusing plinko.net <A >
          404 archive</A>.
          </UL>
          </BODY></HTML>


          程序清單5-14 web.xml(指出HTTP錯誤代碼的錯誤頁面的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <error-page>
          <error-code>404</error-code>
          <location>/NotFound.jsp</location>
          </error-page>
          <!-- ... -->
          </web-app>


          8.2 exception-type元素
          error-code元素處理某個請求產生一個特定的HTTP狀態代碼時的情況。然而,對于servlet或JSP頁面返回200但產生運行時異常這種同樣是常見的情況怎么辦呢?這正是exception-type元素要處理的情況。只需提供兩樣東西即可:即提供如下的一個完全限定的異常類和一個位置:
          <error-page>
          <exception-type>packageName.className</exception-type>
          <location>/SomeURL</location>
          </error-page>
          這樣,如果Web應用中的任何servlet或JSP頁面產生一個特定類型的未捕捉到的異常,則使用指定的URL。此異常類型可以是一個標準類型,如 javax.ServletException或java.lang.OutOfMemoryError,或者是一個專門針對你的應用的異常。
          例如,程序清單5-15給出了一個名為DumbDeveloperException的異常類,可用它來特別標記經驗較少的程序員(不是說你的開發組中一定有這種人)所犯的錯誤。這個類還包含一個名為dangerousComputation的靜態方法,它時不時地生成這種類型的異常。程序清單5-16給出對隨機整數值調用dangerousCompution的一個JSP頁面。在拋出此異常時,如程序清單5-18的web.xml版本中所給出的 exception-type所指出的那樣,對客戶機顯示DDE.jsp(程序清單5-17)。圖5-16和圖5-17分別給出幸運和不幸的結果。

          程序清單5-15 DumbDeveloperException.java
          package moreservlets;

          /** Exception used to flag particularly onerous
          programmer blunders. Used to illustrate the
          exception-type web.xml element.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          * http://www.moreservlets.com/.
          * &copy; 2002 Marty Hall; may be freely used or adapted.
          */

          public class DumbDeveloperException extends Exception {
          public DumbDeveloperException() {
          super("Duh. What was I *thinking*?");
          }

          public static int dangerousComputation(int n)
          throws DumbDeveloperException {
          if (n < 5) {
          return(n + 10);
          } else {
          throw(new DumbDeveloperException());
          }
          }
          }


          程序清單5-16 RiskyPage.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD><TITLE>Risky JSP Page</TITLE></HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>Risky Calculations</H2>
          <%@ page import="moreservlets.*" %>
          <% int n = ((int)(10 * Math.random())); %>
          <UL>
          <LI>n: <%= n %>
          <LI>dangerousComputation(n):
          <%= DumbDeveloperException.dangerousComputation(n) %>
          </UL>
          </BODY></HTML>


          程序清單5-17 DDE.jsp
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD><TITLE>Dumb</TITLE></HEAD>
          <BODY BGCOLOR="#FDF5E6">
          <H2>Dumb Developer</H2>
          We're brain dead. Consider using our competitors.
          </BODY></HTML>


          程序清單5-18 web.xml(為異常指定錯誤頁面的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <servlet> … </servlet>
          <!-- ... -->
          <error-page>
          <exception-type>
          moreservlets.DumbDeveloperException
          </exception-type>
          <location>/DDE.jsp</location>
          </error-page>
          <!-- ... -->
          </web-app>

          9 提供安全性

          利用web.xml中的相關元素為服務器的內建功能提供安全性。
          9.1 指定驗證的方法
          使用login-confgi元素規定服務器應該怎樣驗證試圖訪問受保護頁面的用戶。它包含三個可能的子元素,分別是:auth-method、realm -name和form-login-config。login-config元素應該出現在web.xml部署描述符文件的結尾附近,緊跟在 security-constraint元素之后。
          l auth-method
          login-config的這個子元素列出服務器將要使用的特定驗證機制。有效值為BASIC、DIGEST、FORM和CLIENT-CERT。服務器只需要支持BASIC和FORM。
          BASIC 指出應該使用標準的HTTP驗證,在此驗證中服務器檢查Authorization頭。如果缺少這個頭則返回一個401狀態代碼和一個WWW- Authenticate頭。這導致客戶機彈出一個用來填寫Authorization頭的對話框。此機制很少或不提供對攻擊者的防范,這些攻擊者在 Internet連接上進行窺探(如通過在客戶機的子網上執行一個信息包探測裝置),因為用戶名和口令是用簡單的可逆base64編碼發送的,他們很容易得手。所有兼容的服務器都需要支持BASIC驗證。
          DIGEST指出客戶機應該利用加密Digest Authentication形式傳輸用戶名和口令。這提供了比BASIC驗證更高的防范網絡截取得的安全性,但這種加密比SSL(HTTPS)所用的方法更容易破解。不過,此結論有時沒有意義,因為當前很少有瀏覽器支持Digest Authentication,所以servlet容器不需要支持它。
          FORM 指出服務器應該檢查保留的會話cookie并且把不具有它的用戶重定向到一個指定的登陸頁。此登陸頁應該包含一個收集用戶名和口令的常規HTML表單。在登陸之后,利用保留會話級的cookie跟蹤用戶。雖然很復雜,但FORM驗證防范網絡窺探并不比BASIC驗證更安全,如果有必要可以在頂層安排諸如 SSL或網絡層安全(如IPSEC或VPN)等額外的保護。所有兼容的服務器都需要支持FORM驗證。
          CLIENT-CERT規定服務器必須使用HTTPS(SSL之上的HTTP)并利用用戶的公開密鑰證書(Pulic Key Certificat)對用戶進行驗證。這提供了防范網絡截取的很強的安全性,但只有兼容J2EE的服務器需要支持它。
          l realm-name
          此元素只在auth-method為BASIC時使用。它指出瀏覽器在相應對話框標題使用的、并作為Authorization頭組成部分的安全域的名稱。
          l form-login-config
          此元素只在auth-method為FORM時適用。它指定兩個頁面,分別是:包含收集用戶名及口令的HTML表單的頁面(利用form-login- page子元素),用來指示驗證失敗的頁面(利用form-error-page子元素)。由form-login-page給出的HTML表單必須具有一個j_security_check的ACTION屬性、一個名為j_username的用戶名文本字段以及一個名為j_password的口令字段。
          例如,程序清單5-19指示服務器使用基于表單的驗證。Web應用的頂層目錄中的一個名為login.jsp的頁面將收集用戶名和口令,并且失敗的登陸將由相同目錄中名為login-error.jsp的頁面報告。

          程序清單5-19 web.xml(說明login-config的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <security-constraint> ... </security-constraint>
          <login-config>
          <auth-method> FORM </auth-method>
          <form-login-config>
          <form-login-page>/login.jsp</form-login-page>
          <form-error-page>/login-error.jsp</form-error-page>
          </form-login-config>
          </login-config>
          <!-- ... -->
          </web-app>


          9.2 限制對Web資源的訪問
          現在,可以指示服務器使用何種驗證方法了。"了不起,"你說道,"除非我能指定一個來收到保護的 URL,否則沒有多大用處。"沒錯。指出這些URL并說明他們應該得到何種保護正是security-constriaint元素的用途。此元素在 web.xml中應該出現在login-config的緊前面。它包含是個可能的子元素,分別是:web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小節對它們進行介紹。
          l web-resource-collection
          此元素確定應該保護的資源。所有security-constraint元素都必須包含至少一個web-resource-collection項。此元素由一個給出任意標識名稱的web-resource-name元素、一個確定應該保護的URL的url-pattern元素、一個指出此保護所適用的 HTTP命令(GET、POST等,缺省為所有方法)的http-method元素和一個提供資料的可選description元素組成。例如,下面的 Web-resource-collection項(在security-constratint元素內)指出Web應用的proprietary目錄中所有文檔應該受到保護。
          <security-constraint>
          <web-resource-coolection>
          <web-resource-name>Proprietary</web-resource-name>
          <url-pattern>/propritary/*</url-pattern>
          </web-resource-coolection>
          <!-- ... -->
          </security-constraint>
          重要的是應該注意到,url-pattern僅適用于直接訪問這些資源的客戶機。特別是,它不適合于通過MVC體系結構利用 RequestDispatcher來訪問的頁面,或者不適合于利用類似jsp:forward的手段來訪問的頁面。這種不勻稱如果利用得當的話很有好處。例如,servlet可利用MVC體系結構查找數據,把它放到bean中,發送請求到從bean中提取數據的JSP頁面并顯示它。我們希望保證決不直接訪問受保護的JSP頁面,而只是通過建立該頁面將使用的bean的servlet來訪問它。url-pattern和auth-contraint元素可通過聲明不允許任何用戶直接訪問JSP頁面來提供這種保證。但是,這種不勻稱的行為可能讓開發人員放松警惕,使他們偶然對應受保護的資源提供不受限制的訪問。
          l auth-constraint
          盡管web-resource-collention元素質出了哪些URL應該受到保護,但是auth-constraint元素卻指出哪些用戶應該具有受保護資源的訪問權。此元素應該包含一個或多個標識具有訪問權限的用戶類別role- name元素,以及包含(可選)一個描述角色的description元素。例如,下面web.xml中的security-constraint元素部門規定只有指定為Administrator或Big Kahuna(或兩者)的用戶具有指定資源的訪問權。
          <security-constraint>
          <web-resource-coolection> ... </web-resource-coolection>
          <auth-constraint>
          <role-name>administrator</role-name>
          <role-name>kahuna</role-name>
          </auth-constraint>
          </security-constraint>
          重要的是認識到,到此為止,這個過程的可移植部分結束了。服務器怎樣確定哪些用戶處于任何角色以及它怎樣存放用戶的口令,完全有賴于具體的系統。
          例如,Tomcat使用install_dir/conf/tomcat-users.xml將用戶名與角色名和口令相關聯,正如下面例子中所示,它指出用戶joe(口令bigshot)和jane(口令enaj)屬于administrator和kahuna角色。
          <tomcat-users>
          <user name="joe" password="bigshot" roles="administrator,kahuna" />
          <user name="jane" password="enaj" roles="kahuna" />
          </tomcat-users>
          l user-data-constraint
          這個可選的元素指出在訪問相關資源時使用任何傳輸層保護。它必須包含一個transport-guarantee子元素(合法值為NONE、 INTEGRAL或CONFIDENTIAL),并且可選地包含一個description元素。transport-guarantee為NONE值將對所用的通訊協議不加限制。INTEGRAL值表示數據必須以一種防止截取它的人閱讀它的方式傳送。雖然原理上(并且在未來的HTTP版本中),在 INTEGRAL和CONFIDENTIAL之間可能會有差別,但在當前實踐中,他們都只是簡單地要求用SSL。例如,下面指示服務器只允許對相關資源做 HTTPS連接:
          <security-constraint>
          <!-- ... -->
          <user-data-constraint>
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
          </security-constraint>
          l display-name
          security-constraint的這個很少使用的子元素給予可能由GUI工具使用的安全約束項一個名稱。
          9.3 分配角色名
          迄今為止,討論已經集中到完全由容器(服務器)處理的安全問題之上了。但servlet以及JSP頁面也能夠處理它們自己的安全問題。
          例如,容器可能允許用戶從bigwig或bigcheese角色訪問一個顯示主管人員額外緊貼的頁面,但只允許bigwig用戶修改此頁面的參數。完成這種更細致的控制的一種常見方法是調用HttpServletRequset的isUserInRole方法,并據此修改訪問。
          Servlet的 security-role-ref子元素提供出現在服務器專用口令文件中的安全角色名的一個別名。例如,假如編寫了一個調用 request.isUserInRole("boss")的servlet,但后來該servlet被用在了一個其口令文件調用角色manager而不是boss的服務器中。下面的程序段使該servlet能夠使用這兩個名稱中的任何一個。
          <servlet>
          <!-- ... -->
          <security-role-ref>
          <role-name>boss</role-name> <!-- New alias -->
          <role-link>manager</role-link> <!-- Real name -->
          </security-role-ref>
          </servlet>
          也可以在web-app內利用security-role元素提供將出現在role-name元素中的所有安全角色的一個全局列表。分別地生命角色使高級IDE容易處理安全信息。

          10 控制會話超時

          如果某個會話在一定的時間內未被訪問,服務器可把它扔掉以節約內存。可利用HttpSession的setMaxInactiveInterval方法直接設置個別會話對象的超時值。如果不采用這種方法,則缺省的超時值由具體的服務器決定。但可利用session-config和session- timeout元素來給出一個適用于所有服務器的明確的超時值。超時值的單位為分鐘,因此,下面的例子設置缺省會話超時值為三個小時(180分鐘)。
          <session-config>
          <session-timeout>180</session-timeout>
          </session-config>

          11 Web應用的文檔化

          越來越多的開發環境開始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio(寫此文時,已被Macromedia收購)以及IBM VisuaAge for Java等。
          大量的web.xml元素不僅是為服務器設計的,而且還是為可視開發環境設計的。它們包括icon、display-name和discription等。
          可回憶一下,在web.xml內以適當地次序聲明web-app子元素很重要。不過,這里只要記住icon、display-name和description是web.xml的web-app元素內的前三個合法元素即可。
          l icon
          icon元素指出GUI工具可用來代表Web應用的一個和兩個圖像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG圖像,用large-icon元素指定一幅32 x 32的圖像。下面舉一個例子:
          <icon>
          <small-icon>/images/small-book.gif</small-icon>
          <large-icon>/images/tome.jpg</large-icon>
          </icon>
          l display-name
          display-name元素提供GUI工具可能會用來標記此Web應用的一個名稱。下面是個例子。
          <display-name>Rare Books</display-name>
          l description
          description元素提供解釋性文本,如下所示:
          <description>
          This Web application represents the store developed for
          rare-books.com, an online bookstore specializing in rare
          and limited-edition books.
          </description>

          12 關聯文件與MIME類型

          服務器一般都具有一種讓Web站點管理員將文件擴展名與媒體相關聯的方法。例如,將會自動給予名為mom.jpg的文件一個image/jpeg的MIME 類型。但是,假如你的Web應用具有幾個不尋常的文件,你希望保證它們在發送到客戶機時分配為某種MIME類型。mime-mapping元素(具有 extension和mime-type子元素)可提供這種保證。例如,下面的代碼指示服務器將application/x-fubar的MIME類型分配給所有以.foo結尾的文件。
          <mime-mapping>
          <extension>foo</extension>
          <mime-type>application/x-fubar</mime-type>
          </mime-mapping>
          或許,你的Web應用希望重載(override)標準的映射。例如,下面的代碼將告訴服務器在發送到客戶機時指定.ps文件作為純文本(text/plain)而不是作為PostScript(application/postscript)。
          <mime-mapping>
          <extension>ps</extension>
          <mime-type>application/postscript</mime-type>
          </mime-mapping>


          13 定位TLD

          JSP taglib元素具有一個必要的uri屬性,它給出一個TLD(Tag Library Descriptor)文件相對于Web應用的根的位置。TLD文件的實際名稱在發布新的標簽庫版本時可能會改變,但我們希望避免更改所有現有JSP頁面。此外,可能還希望使用保持taglib元素的簡練性的一個簡短的uri。這就是部署描述符文件的taglib元素派用場的所在了。Taglib包含兩個子元素:taglib-uri和taglib-location。taglib-uri元素應該與用于JSP taglib元素的uri屬性的東西相匹配。Taglib-location元素給出TLD文件的實際位置。例如,假如你將文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。現在,假如web.xml在web-app元素內包含下列內容。
          <taglib>
          <taglib-uri>/charts.tld</taglib-uri>
          <taglib-location>
          /WEB-INF/tlds/chart-tags-1.3beta.tld
          </taglib-location>
          </taglib>
          給出這個說明后,JSP頁面可通過下面的簡化形式使用標簽庫。
          <%@ taglib uri="/charts.tld" prefix="somePrefix" %>

          14 指定應用事件監聽程序

          應用事件監聽器程序是建立或修改servlet環境或會話對象時通知的類。它們是servlet規范的版本2.3中的新內容。這里只簡單地說明用來向Web應用注冊一個監聽程序的web.xml的用法。
          注冊一個監聽程序涉及在web.xml的web-app元素內放置一個listener元素。在listener元素內,listener-class元素列出監聽程序的完整的限定類名,如下所示:
          <listener>
          <listener-class>package.ListenerClass</listener-class>
          </listener>
          雖然listener元素的結構很簡單,但請不要忘記,必須正確地給出web-app元素內的子元素的次序。listener元素位于所有的servlet 元素之前以及所有filter-mapping元素之后。此外,因為應用生存期監聽程序是serlvet規范的2.3版本中的新內容,所以必須使用 web.xml DTD的2.3版本,而不是2.2版本。
          例如,程序清單5-20給出一個名為ContextReporter的簡單的監聽程序,只要Web應用的Servlet-Context建立(如裝載Web應用)或消除(如服務器關閉)時,它就在標準輸出上顯示一條消息。程序清單5-21給出此監聽程序注冊所需要的web.xml文件的一部分。

          程序清單5-20 ContextReporterjava
          package moreservlets;

          import javax.servlet.*;
          import java.util.*;

          /** Simple listener that prints a report on the standard output
          * when the ServletContext is created or destroyed.
          * <P>
          * Taken from More Servlets and JavaServer Pages
          * from Prentice Hall and Sun Microsystems Press,
          * http://www.moreservlets.com/.
          * &copy; 2002 Marty Hall; may be freely used or adapted.
          */

          public class ContextReporter implements ServletContextListener {
          public void contextInitialized(ServletContextEvent event) {
          System.out.println("Context created on " +
          new Date() + ".");
          }

          public void contextDestroyed(ServletContextEvent event) {
          System.out.println("Context destroyed on " +
          new Date() + ".");
          }
          }


          程序清單5-21 web.xml(聲明一個監聽程序的摘錄)
          <?xml version="1.0" encoding="ISO-8859-1"?>
          <!DOCTYPE web-app
          PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

          <web-app>
          <!-- ... -->
          <filter-mapping> … </filter-mapping>
          <listener>
          <listener-class>package.ListenerClass</listener-class>
          </listener>
          <servlet> ... </servlet>
          <!-- ... -->
          </web-app>


          15 J2EE元素

          本節描述用作J2EE環境組成部分的Web應用的web.xml元素。這里將提供一個簡明的介紹,詳細內容可以參閱http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3規范的第5章。
          l distributable
          distributable 元素指出,Web應用是以這樣的方式編程的:即,支持集群的服務器可安全地在多個服務器上分布Web應用。例如,一個可分布的應用必須只使用 Serializable對象作為其HttpSession對象的屬性,而且必須避免用實例變量(字段)來實現持續性。distributable元素直接出現在discription元素之后,并且不包含子元素或數據,它只是一個如下的標志。
          <distributable />
          l resource-env-ref
          resource -env-ref元素聲明一個與某個資源有關的管理對象。此元素由一個可選的description元素、一個resource-env-ref- name元素(一個相對于java:comp/env環境的JNDI名)以及一個resource-env-type元素(指定資源類型的完全限定的類),如下所示:
          <resource-env-ref>
          <resource-env-ref-name>
          jms/StockQueue
          </resource-env-ref-name>
          <resource-env-ref-type>
          javax.jms.Queue
          </resource-env-ref-type>
          </resource-env-ref>
          l env-entry
          env -entry元素聲明Web應用的環境項。它由一個可選的description元素、一個env-entry-name元素(一個相對于java: comp/env環境JNDI名)、一個env-entry-value元素(項值)以及一個env-entry-type元素(java.lang程序包中一個類型的完全限定類名,java.lang.Boolean、java.lang.String等)組成。下面是一個例子:
          <env-entry>
          <env-entry-name>minAmout</env-entry-name>
          <env-entry-value>100.00</env-entry-value>
          <env-entry-type>minAmout</env-entry-type>
          </env-entry>
          l ejb-ref
          ejb -ref元素聲明對一個EJB的主目錄的應用。它由一個可選的description元素、一個ejb-ref-name元素(相對于java: comp/env的EJB應用)、一個ejb-ref-type元素(bean的類型,Entity或Session)、一個home元素(bean的主目錄接口的完全限定名)、一個remote元素(bean的遠程接口的完全限定名)以及一個可選的ejb-link元素(當前bean鏈接的另一個 bean的名稱)組成。
          l ejb-local-ref
          ejb-local-ref元素聲明一個EJB的本地主目錄的引用。除了用local-home代替home外,此元素具有與ejb-ref元素相同的屬性并以相同的方式使用。

          posted @ 2007-06-18 13:38 siwei 閱讀(223) | 評論 (0)編輯 收藏

               摘要: 本文發表于《開源大本營》                                作者:錢...  閱讀全文

          posted @ 2007-06-18 13:29 siwei 閱讀(225) | 評論 (0)編輯 收藏

          2007年6月14日

          選擇與編組

          選擇允許使用 '|' 字符來在兩個或多個候選項中進行選擇。通過擴展章節標題的正則表達式,可以將其擴充為不僅僅適用于章節標題的表達式。不過,這可沒有想象的那么直接。在使用選擇時,將匹配'|' 字符每邊最可能的表達式。你可能認為下面的 JScript 和 VBScript 表達式將匹配位于一行的開始和結束位置且后跟一個或兩個數字的 'Chapter' 或 'Section':

          /^Chapter|Section [1-9][0-9]{0,1}$/ "^Chapter|Section [1-9][0-9]{0,1}$"

          不幸的是,真正的情況是上面所示的正則表達式要么匹配位于一行開始處的單詞 'Chapter',要么匹配一行結束處的后跟任何數字的 'Section'。如果輸入字符串為 'Chapter 22',上面的表達式將只匹配單詞 'Chapter'。如果輸入字符串為 'Section 22',則該表達式將匹配 'Section 22'。但這種結果不是我們此處的目的,因此必須有一種辦法來使正則表達式對于所要做的更易于響應,而且確實也有這種方法。

          可以使用圓括號來限制選擇的范圍,也就是說明確該選擇只適用于這兩個單詞 'Chapter' 和 'Section'。不過,圓括號同樣也是難處理的,因為它們也用來創建子表達式,有些內容將在后面關于子表達式的部分介紹。通過采用上面所示的正則表達式并在適當位置添加圓括號,就可以使該正則表達式既可以匹配 'Chapter 1',也可以匹配 'Section 3'。

          下面的正則表達式使用圓括號將 'Chapter' 和 'Section' 組成一組,所以該表達式才能正確工作。對 JScript 為:

          /^(Chapter|Section) [1-9][0-9]{0,1}$/

          對 VBScript 為:

          "^(Chapter|Section) [1-9][0-9]{0,1}$"

          這些表達式工作正確,只是產生了一個有趣的副產品。在 'Chapter|Section' 兩邊放置圓括號建立了適當的編組,但也導致兩個待匹配單詞之一都被捕獲供今后使用。由于在上面所示的表達式中只有一組圓括號,因此只能有一個捕獲的 submatch。可以使用 VBScript 的Submatches 集合或者JScript 中RegExp 對象的 $1-$9 屬性來引用這個子匹配。

          有時捕獲一個子匹配是所希望的,有時則是不希望的。在說明所示的示例中,真正想做的就是使用圓括號對單詞 'Chapter' 或 'Section' 之間的選擇編組。并不希望在后面再引用該匹配。實際上,除非真的是需要捕獲子匹配,否則請不要使用。由于不需要花時間和內存來存儲那些子匹配,這種正則表達式的效率將更高。

          可以在正則表達式模式圓括號內部的前面使用 '?:'來防止存儲該匹配供今后使用。對上面所示正則表達式的下述修改提供了免除子匹配存儲的相同功能。對 JScript:

          /^(?:Chapter|Section) [1-9][0-9]{0,1}$/

          對 VBScript:

          "^(?:Chapter|Section) [1-9][0-9]{0,1}$"

          除了 '?:' 元字符,還有兩個非捕獲元字符用于稱之為預查的匹配。一個為正向預查,用 ?= 表示, 在任何開始匹配圓括號內的正則表達式模式的位置來匹配搜索字符串。一個為負向預查,用 '?!' 表示,在任何開始不匹配該正則表達式模式的位置來匹配搜索字符串。

          例如,假定有一個包含引用有 Windows 3.1、Windows 95、Windows 98 以及 Windows NT 的文檔。進一步假設需要更新該文檔,方法是查找所有對 Windows 95、Windows 98 以及 Windows NT 的引用,并將這些引用更改為 Windows 2000。可以使用下面的 JScript 正則表達式,這是一個正向預查,來匹配 Windows 95、Windows 98 以及 Windows NT:

          /Windows(?=95 |98 |NT )/

          在 VBScript 要進行同樣的匹配可以使用下述表達式:

          "Windows(?=95 |98 |NT )"

          找到一個匹配后,緊接匹配到的文字(而不包括預查中使用的字符)就開始對下一次匹配的搜索。例如,如果上面所示的表達式匹配到 'Windows 98',則將從 'Windows' 而不是 '98' 之后繼續查找。

          后向引用

          正則表達式一個最重要的特性就是將匹配成功的模式的某部分進行存儲供以后使用這一能力。請回想一下,對一個正則表達式模式或部分模式兩邊添加圓括號將導致這部分表達式存儲到一個臨時緩沖區中。可以使用非捕獲元字符 '?:', '?=', or '?!' 來忽略對這部分正則表達式的保存。

          所捕獲的每個子匹配都按照在正則表達式模式中從左至右所遇到的內容存儲。存儲子匹配的緩沖區編號從 1 開始,連續編號直至最大 99 個子表達式。每個緩沖區都可以使用 '\n' 訪問,其中 n 為一個標識特定緩沖區的一位或兩位十進制數。

          后向引用一個最簡單,最有用的應用是提供了確定文字中連續出現兩個相同單詞的位置的能力。請看下面的句子:

          Is is the cost of of gasoline going up up?

          根據所寫內容,上面的句子明顯存在單詞多次重復的問題。如果能有一種方法無需查找每個單詞的重復現象就能修改該句子就好了。下面的 JScript 正則表達式使用一個子表達式就可以實現這一功能。

          /\b([a-z]+) \1\b/gi

          等價的 VBScript 表達式為:

          "\b([a-z]+) \1\b"

          在這個示例中,子表達式就是圓括號之間的每一項。所捕獲的表達式包括一個或多個字母字符,即由'[a-z]+' 所指定的。該正則表達式的第二部分是對前面所捕獲的子匹配的引用,也就是由附加表達式所匹配的第二次出現的單詞。'\1'用來指定第一個子匹配。單詞邊界元字符確保只檢測單獨的單詞。如果不這樣,則諸如 "is issued" 或 "this is" 這樣的短語都會被該表達式不正確地識別。

          在 JScript 表達式中,正則表達式后面的全局標志 ('g') 表示該表達式將用來在輸入字符串中查找盡可能多的匹配。大小寫敏感性由表達式結束處的大小寫敏感性標記 ('i') 指定。多行標記指定可能出現在換行符的兩端的潛在匹配。對 VBScript 而言,在表達式中不能設置各種標記,但必須使用 RegExp 對象的屬性來顯式設置。

          使用上面所示的正則表達式,下面的 JScript 代碼可以使用子匹配信息,在一個文字字符串中將連續出現兩次的相同單詞替換為一個相同的單詞:

          var ss = "Is is the cost of of gasoline going up up?.\n"; var re = /\b([a-z]+) \1\b/gim; //創建正則表達式樣式. var rv = ss.replace(re,"$1"); //用一個單詞替代兩個單詞.

          最接近的等價  VBScript 代碼如下:

          Dim ss, re, rv ss = "Is is the cost of of gasoline going up up?." & vbNewLine Set re = New RegExp re.Pattern = "\b([a-z]+) \1\b" re.Global = True re.IgnoreCase = True re.MultiLine = True rv = re.Replace(ss,"$1")

          請注意在 VBScript 代碼中,全局、大小寫敏感性以及多行標記都是使用 RegExp 對象的適當屬性來設置的。

          replace 方法中使用 $1 來引用所保存的第一個子匹配。如果有多個子匹配,則可以用 $2, $3 等繼續引用。

          后向引用的另一個用途是將一個通用資源指示符 (URI) 分解為組件部分。假定希望將下述的URI 分解為協議 (ftp, http, etc),域名地址以及頁面/路徑:

          http://msdn.microsoft.com:80/scripting/default.htm

          下面的正則表達式可以提供這個功能。對 JScript,為:

          /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/

          對 VBScript 為:

          "(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)"

          第一個附加子表達式是用來捕獲該 web 地址的協議部分。該子表達式匹配位于一個冒號和兩個正斜杠之前的任何單詞。第二個附加子表達式捕獲該地址的域名地址。該子表達式匹配不包括 '^'、 '/' 或 ':' 字符的任何字符序列。第三個附加子表達式捕獲網站端口號碼,如果指定了該端口號。該子表達式匹配后跟一個冒號的零或多個數字。最后,第四個附加子表達式捕獲由該 web 地址指定的路徑以及\或者頁面信息。該子表達式匹配一個和多個除'#' 或空格之外的字符。

          將該正則表達式應用于上面所示的 URI 后,子匹配包含下述內容:

          RegExp.$1 包含 "http"

          RegExp.$2 包含 "msdn.microsoft.com"

          RegExp.$3 包含 ":80"

          RegExp.$4 包含 "/scripting/default.htm"


          posted @ 2007-06-14 14:17 siwei 閱讀(197) | 評論 (0)編輯 收藏

          限定符

          有時候不知道要匹配多少字符。為了能適應這種不確定性,正則表達式支持限定符的概念。這些限定符可以指定正則表達式的一個給定組件必須要出現多少次才能滿足匹配。

          下表給出了各種限定符及其含義的說明:

          字符 描述
          * 匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等價于{0,}。
          + 匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價于 {1,}。
          ? 匹配前面的子表達式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等價于 {0,1}。
          {n} n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。
          {n,} n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價于 'o+'。'o{0,}' 則等價于 'o*'。
          {n,m} mn 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。劉, "o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價于 'o?'。請注意在逗號和兩個數之間不能有空格。

          對一個很大的輸入文檔而言,章節數很輕易就超過九章,因此需要有一種方法來處理兩位數或者三位數的章節號。限定符就提供了這個功能。下面的JScript 正則表達式可以匹配具有任何位數的章節標題:

          /Chapter [1-9][0-9]*/

          下面的 VBScript 正則表達式執行同樣的匹配:

          "Chapter [1-9][0-9]*"

          請注意限定符出現在范圍表達式之后。因此,它將應用于所包含的整個范圍表達式,在本例中,只指定了從 0 到 9 的數字。

          這里沒有使用 '+' 限定符,因為第二位或后續位置上并不一定需要一個數字。同樣也沒有使用 '?' 字符,因為這將把章節數限制為只有兩位數字。在 'Chapter' 和空格字符之后至少要匹配一個數字。

          如果已知章節數限制只有99 章,則可以使用下面的 JScript 表達式來指定至少有一位數字,但不超過兩個數字。

          /Chapter [0-9]{1,2}/

          對 VBScript 可以使用下述正則表達式:

          "Chapter [0-9]{1,2}"

          上述表達式的缺點是如果有一個章節號大于 99,它仍只會匹配前兩位數字。另一個缺點是某些人可以創建一個 Chapter 0,而且仍能匹配。一個更好的用來匹配兩位數的 JScript 表達式如下:

          /Chapter [1-9][0-9]?/

          或者

          /Chapter [1-9][0-9]{0,1}/

          對 VBScript 而言,下述表達式與上面等價:

          "Chapter [1-9][0-9]?"

          或者

          "Chapter [1-9][0-9]{0,1}"

          '*'、 '+'和 '?' 限定符都稱之為貪婪的,也就是說,他們盡可能多地匹配文字。有時這根本就不是所希望發生的情況。有時則正好希望最小匹配。

          例如,你可能要搜索一個 HTML 文檔來查找一處包含在 H1 標記中的章節標題。在文檔中該文字可能具有如下形式:

          <H1>Chapter 1 – Introduction to Regular Expressions</H1>

          下面的表達式匹配從開始的小于號 (<) 到 H1 標記結束處的大于號之間的所有內容。

          /<.*>/

           VBScript 的正則表達式為:

          "<.*>"

          如果所要匹配的就是開始的 H1 標記,則下述非貪婪地表達式就只匹配 <H1>。

          /<.*?>/

          或者

          "<.*?>"

          通過在 '*'、 '+' 或 '?' 限定符后放置 '?',該表達式就從貪婪匹配轉為了非貪婪或最小匹配。

           

          定位符

          到現在為止,所看到的示例都只考慮查找任何地方出現的章節標題。出現的任何一個字符串 'Chapter' 后跟一個空格和一個數字可能是一個真正的章節標題,也可能是對其他章節的交叉引用。由于真正的章節標題總是出現在一行的開始,因此需要設計一個方法只查找標題而不查找交叉引用。

          定位符提供了這個功能。定位符可以將一個正則表達式固定在一行的開始或結束。也可以創建只在單詞內或只在單詞的開始或結尾處出現的正則表達式。下表包含了正則表達式及其含義的列表:

          字符 描述
          ^ 匹配輸入字符串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之后的位置。
          $ 匹配輸入字符串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。
          \b 匹配一個單詞邊界,也就是指單詞和空格間的位置。
          \B 匹配非單詞邊界。

          不能對定位符使用限定符。因為在一個換行符或者單詞邊界的前面或后面不會有連續多個位置,因此諸如 '^*' 的表達式是不允許的。

          要匹配一行文字開始位置的文字,請在正則表達式的開始處使用 '^' 字符。不要把 '^' 的這個語法與其在括號表達式中的語法弄混。它們的語法根本不同。

          要匹配一行文字結束位置的文字,請在正則表達式的結束處使用 '$' 字符。

          要在查找章節標題時使用定位符,下面的 JScript 正則表達式將匹配位于一行的開始處最多有兩個數字的章節標題:

          /^Chapter [1-9][0-9]{0,1}/

          VBScript 中相同功能的正則表達式如下:

          "^Chapter [1-9][0-9]{0,1}"

          一個真正的章節標題不僅出現在一行的開始,而且這一行中也僅有這一個內容,因此,它必然也位于一行的結束。下面的表達式確保所指定的匹配只匹配章節而不會匹配交叉引用。它是通過創建一個只匹配一行文字的開始和結束位置的正則表達式來實現的。

          /^Chapter [1-9][0-9]{0,1}$/

          對 VBScript 則使用:

          "^Chapter [1-9][0-9]{0,1}$"

          匹配單詞邊界有少許不同,但卻給正則表達式增加了一個非常重要的功能。單詞邊界就是單詞和空格之間的位置。非單詞邊界就是其他任何位置。下面的 JScript 表達式將匹配單詞 'Chapter' 的前三個字符,因為它們出現在單詞邊界后:

          /\bCha/

          對 VBScript 為:

          "\bCha"

          這里 '\b' 操作符的位置很關鍵。如果它位于要匹配的字符串的開始,則將查找位于單詞開頭處的匹配;如果它位于改字符串的末尾,則查找位于單詞結束處的匹配。例如,下面的表達式將匹配單詞 'Chapter' 中的 'ter',因為它出現在單詞邊界之前:

          /ter\b/

          以及

          "ter\b"

          下面的表達式將匹配 'apt',因為它位于 'Chapter' 中間,但不會匹配 'aptitude' 中的'apt':

          /\Bapt/

          以及

          "\Bapt"

          這是因為在單詞 'Chapter' 中 'apt' 出現在非單詞邊界位置,而在單詞 'aptitude' 中位于單詞邊界位置。非單詞邊界操作符的位置不重要,因為匹配與一個單詞的開頭或結尾無關。



          posted @ 2007-06-14 14:16 siwei 閱讀(300) | 評論 (0)編輯 收藏

          認識正則表達式

          如果原來沒有使用過正則表達式,那么可能對這個術語和概念會不太熟悉。不過,它們并不是您想象的那么新奇。

          請回想一下在硬盤上是如何查找文件的。您肯定會使用 ? 和 * 字符來幫助查找您正尋找的文件。? 字符匹配文件名中的單個字符,而 * 則匹配一個或多個字符。一個如 'data?.dat' 的模式可以找到下述文件:

          data1.dat

          data2.dat

          datax.dat

          dataN.dat

          如果使用 * 字符代替 ? 字符,則將擴大找到的文件數量。'data*.dat' 可以匹配下述所有文件名:

          data.dat

          data1.dat

          data2.dat

          data12.dat

          datax.dat

          dataXYZ.dat

          盡管這種搜索文件的方法肯定很有用,但也十分有限。? 和 * 通配符的有限能力可以使你對正則表達式能做什么有一個概念,不過正則表達式的功能更強大,也更靈活。

          正則表達式的早期起源

          正則表達式的“祖先”可以一直上溯至對人類神經系統如何工作的早期研究。Warren McCulloch 和 Walter Pitts 這兩位神經生理學家研究出一種數學方式來描述這些神經網絡。

          1956 年, 一位叫 Stephen Kleene 的美國數學家在 McCulloch 和 Pitts 早期工作的基礎上,發表了一篇標題為“神經網事件的表示法”的論文,引入了正則表達式的概念。正則表達式就是用來描述他稱為“正則集的代數”的表達式,因此采用“正則表達式”這個術語。

          隨后,發現可以將這一工作應用于使用Ken Thompson 的計算搜索算法的一些早期研究,Ken Thompson是Unix 的主要發明人。正則表達式的第一個實用應用程序就是 Unix 中的qed 編輯器。

          如他們所說,剩下的就是眾所周知的歷史了。從那時起直至現在正則表達式都是基于文本的編輯器和搜索工具中的一個重要部分。

          使用正則表達式

          在典型的搜索和替換操作中,必須提供要查找的確切文字。這種技術對于靜態文本中的簡單搜索和替換任務可能足夠了,但是由于它缺乏靈活性,因此在搜索動態文本時就有困難了,甚至是不可能的。

          使用正則表達式,就可以:

          • 測試字符串的某個模式。例如,可以對一個輸入字符串進行測試,看在該字符串是否存在一個電話號碼模式或一個信用卡號碼模式。這稱為數據有效性驗證。
          • 替換文本。可以在文檔中使用一個正則表達式來標識特定文字,然后可以全部將其刪除,或者替換為別的文字。
          • 根據模式匹配從字符串中提取一個子字符串。可以用來在文本或輸入字段中查找特定文字。

          例如,如果需要搜索整個 web 站點來刪除某些過時的材料并替換某些HTML 格式化標記,則可以使用正則表達式對每個文件進行測試,看在該文件中是否存在所要查找的材料或 HTML 格式化標記。用這個方法,就可以將受影響的文件范圍縮小到包含要刪除或更改的材料的那些文件。然后可以使用正則表達式來刪除過時的材料,最后,可以再次使用正則表達式來查找并替換那些需要替換的標記。

          posted @ 2007-06-14 14:13 siwei 閱讀(216) | 評論 (0)編輯 收藏

          一個正則表達式就是由普通字符(例如字符 a 到 z)以及特殊字符(稱為元字符)組成的文字模式。該模式描述在查找文字主體時待匹配的一個或多個字符串。正則表達式作為一個模板,將某個字符模式與所搜索的字符串進行匹配。

          這里有一些可能會遇到的正則表達式示例:

          JScript VBScript 匹配
          /^\[ \t]*$/ "^\[ \t]*$" 匹配一個空白行。
          /\d{2}-\d{5}/ "\d{2}-\d{5}" 驗證一個ID 號碼是否由一個2位數字,一個連字符以及一個5位數字組成。
          /<(.*)>.*<\/\1>/ "<(.*)>.*<\/\1>" 匹配一個 HTML 標記。

          下表是元字符及其在正則表達式上下文中的行為的一個完整列表:

          字符 描述
          \ 將下一個字符標記為一個特殊字符、或一個原義字符、或一個 后向引用、或一個八進制轉義符。例如,'n' 匹配字符 "n"。'\n' 匹配一個換行符。序列 '\\' 匹配 "\" 而 "\(" 則匹配 "("。
          ^ 匹配輸入字符串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之后的位置。
          $ 匹配輸入字符串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。
          * 匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等價于{0,}。
          + 匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價于 {1,}。
          ? 匹配前面的子表達式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等價于 {0,1}。
          {n} n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。
          {n,} n 是一個非負整數。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價于 'o+'。'o{0,}' 則等價于 'o*'。
          {n,m} mn 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。劉, "o{1,3}" 將匹配 "fooooood" 中的前三個 o。'o{0,1}' 等價于 'o?'。請注意在逗號和兩個數之間不能有空格。
          ? 當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對于字符串 "oooo",'o+?' 將匹配單個 "o",而 'o+' 將匹配所有 'o'。
          . 匹配除 "\n" 之外的任何單個字符。要匹配包括 '\n' 在內的任何字符,請使用象 '[.\n]' 的模式。
          (pattern) 匹配pattern 并獲取這一匹配。所獲取的匹配可以從產生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中則使用 $0$9 屬性。要匹配圓括號字符,請使用 '\(' 或 '\)'。
          (?:pattern) 匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以后使用。這在使用 "或" 字符 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 'industry|industries' 更簡略的表達式。
          (?=pattern) 正向預查,在任何匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始。
          (?!pattern) 負向預查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始
          x|y 匹配 xy。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。
          [xyz] 字符集合。匹配所包含的任意一個字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
          [^xyz] 負值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
          [a-z] 字符范圍。匹配指定范圍內的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范圍內的任意小寫字母字符。
          [^a-z] 負值字符范圍。匹配任何不在指定范圍內的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范圍內的任意字符。
          \b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
          \B 匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
          \cx 匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。 x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字符。
          \d 匹配一個數字字符。等價于 [0-9]。
          \D 匹配一個非數字字符。等價于 [^0-9]。
          \f 匹配一個換頁符。等價于 \x0c 和 \cL。
          \n 匹配一個換行符。等價于 \x0a 和 \cJ。
          \r 匹配一個回車符。等價于 \x0d 和 \cM。
          \s 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。
          \S 匹配任何非空白字符。等價于 [^ \f\n\r\t\v]。
          \t 匹配一個制表符。等價于 \x09 和 \cI。
          \v 匹配一個垂直制表符。等價于 \x0b 和 \cK。
          \w 匹配包括下劃線的任何單詞字符。等價于'[A-Za-z0-9_]'。
          \W 匹配任何非單詞字符。等價于 '[^A-Za-z0-9_]'。
          \xn 匹配 n,其中 n 為十六進制轉義值。十六進制轉義值必須為確定的兩個數字長。例如, '\x41' 匹配 "A"。'\x041' 則等價于 '\x04' & "1"。正則表達式中可以使用 ASCII 編碼。.
          \num 匹配 num,其中 num 是一個正整數。對所獲取的匹配的引用。例如,'(.)\1' 匹配兩個連續的相同字符。
          \n 標識一個八進制轉義值或一個后向引用。如果 \n 之前至少 n 個獲取的子表達式,則 n 為后向引用。否則,如果 n 為八進制數字 (0-7),則 n 為一個八進制轉義值。
          \nm 標識一個八進制轉義值或一個后向引用。如果 \nm 之前至少有is preceded by at least nm 個獲取得子表達式,則 nm 為后向引用。如果 \nm 之前至少有 n 個獲取,則 n 為一個后跟文字 m 的后向引用。如果前面的條件都不滿足,若  nm 均為八進制數字 (0-7),則 \nm 將匹配八進制轉義值 nm
          \nml 如果 n 為八進制數字 (0-3),且 ml 均為八進制數字 (0-7),則匹配八進制轉義值 nml。
          \un 匹配 n,其中 n 是一個用四個十六進制數字表示的 Unicode 字符。例如, \u00A9 匹配版權符號 (?)。

           

          正則表達式的優先權順序

          在構造正則表達式之后,就可以象數學表達式一樣來求值,也就是說,可以從左至右并按照一個優先權順序來求值。

          下表從最高優先級到最低優先級列出各種正則表達式操作符的優先權順序:

          操作符 描述
          \ 轉義符
          (), (?:), (?=), [] 圓括號和方括號
          *, +, ?, {n}, {n,}, {n,m} 限定符
          ^, $, \anymetacharacter 位置和順序
          | “或”操作

          posted @ 2007-06-14 14:12 siwei 閱讀(205) | 評論 (0)編輯 收藏

          普通字符由所有那些未顯式指定為元字符的打印和非打印字符組成。這包括所有的大寫和小寫字母字符,所有數字,所有標點符號以及一些符號。

          最簡單的正則表達式是一個單獨的普通字符,可以匹配所搜索字符串中的該字符本身。例如,單字符模式 'A' 可以匹配所搜索字符串中任何位置出現的字母 'A'。這里有一些單字符正則表達式模式的示例:

          /a/ /7/ /M/

          等價的 VBScript 單字符正則表達式為:

          "a" "7" "M"

          可以將多個單字符組合在一起得到一個較大的表達式。例如,下面的 JScript 正則表達式不是別的,就是通過組合單字符表達式 'a'、'7'以及 'M' 所創建出來的一個表達式。

          /a7M/

          等價的 VBScript 表達式為:

          "a7M"

          請注意這里沒有連接操作符。所需要做的就是將一個字符放在了另一個字符后面。

          特殊字符

          有不少元字符在試圖對其進行匹配時需要進行特殊的處理。要匹配這些特殊字符,必須首先將這些字符轉義,也就是在前面使用一個反斜杠 (\)。下表給出了這些特殊字符及其含義:

          特殊字符 說明
          $ 匹配輸入字符串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,請使用 \$。
          ( ) 標記一個子表達式的開始和結束位置。子表達式可以獲取供以后使用。要匹配這些字符,請使用 \( 和 \)。
          * 匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。
          + 匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。
          . 匹配除換行符 \n之外的任何單字符。要匹配 .,請使用 \。
          [ 標記一個中括號表達式的開始。要匹配 [,請使用 \[。
          ? 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。
          \ 將下一個字符標記為或特殊字符、或原義字符、或后向引用、或八進制轉義符。例如, 'n' 匹配字符 'n'。'\n' 匹配換行符。序列 '\\' 匹配 "\",而 '\(' 則匹配 "("。
          ^ 匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符本身,請使用 \^。
          { 標記限定符表達式的開始。要匹配 {,請使用 \{。
          | 指明兩項之間的一個選擇。要匹配 |,請使用 \|。

          非打印字符

          有不少很有用的非打印字符,偶爾必須使用。下表顯示了用來表示這些非打印字符的轉義序列:

          字符 含義
          \cx 匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。 x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字符。
          \f 匹配一個換頁符。等價于 \x0c 和 \cL。
          \n 匹配一個換行符。等價于 \x0a 和 \cJ。
          \r 匹配一個回車符。等價于 \x0d 和 \cM。
          \s 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。
          \S 匹配任何非空白字符。等價于 [^ \f\n\r\t\v]。
          \t 匹配一個制表符。等價于 \x09 和 \cI。
          \v 匹配一個垂直制表符。等價于 \x0b 和 \cK。

          字符匹配

          句點 (.) 匹配一個字符串中任何單個的打印或非打印字符,除了換行符 (\n) 之外。下面的 JScript 正則表達式可以匹配 'aac'、'abc'、'acc'、'adc'如此等等,同樣也可以匹配 'a1c'、'a2c'、a-c'以及 a#c':

          /a.c/

          等價的 VBScript 正則表達式為:

          "a.c"

          如果試圖匹配一個包含文件名的字符串,其中句點 (.) 是輸入字符串的一部分,則可以在正則表達式中的句點前面加上一個反斜杠 (\) 字符來實現這一要求。舉例來說,下面的 JScript 正則表達式就能匹配 'filename.ext':

          /filename\.ext/

          對 VBScript 而言,等價的表達式如下所示:

          "filename\.ext"

          這些表達式仍然是相當有限的。它們只允許匹配任何單字符。很多情況下,對從列表中匹配特殊字符十分有用。例如,如果輸入文字中包含用數字表示為Chapter 1, Chapter 2諸如此類的章節標題,你可能需要找到這些章節標題。

          括號表達式

          可以在一個方括號 ([ 和 ]) 中放入一個或多個單字符,來創建一個待匹配的列表。如果字符被放入括號中括起來,則該列表稱為括號表達式。括號內和其他任何地方一樣,普通字符代表其本身,也就是說,它們匹配輸入文字中出現的一處自己。大多數特殊字符在位于括號表達式中時都將失去其含義。這里有一些例外:

          • ']' 字符如果不是第一項,則將結束一個列表。要在列表中匹配 ']' 字符,請將其放在第一項,緊跟在開始的 '[' 后面。
          • '\' 仍然作為轉義符。要匹配 '\' 字符,請使用 '\\'。

          括號表達式中所包含的字符只匹配該括號表達式在正則表達式中所處位置的一個單字符。下面的 JScript 正則表達式可以匹配 'Chapter 1'、'Chapter 2'、'Chapter 3'、'Chapter 4' 以及 'Chapter 5':

          /Chapter [12345]/

          在 VBScript 中要匹配同樣的章節標題,請使用下面的表達式:

          "Chapter [12345]"

          請注意單詞 'Chapter' 及后面的空格與括號內的字符的位置關系是固定的。因此,括號表達式只用來指定滿足緊跟在單詞 'Chapter' 和一個空格之后的單字符位置的字符集合。這里是第九個字符位置。

          如果希望使用范圍而不是字符本身來表示待匹配的字符,則可以使用連字符將該范圍的開始和結束字符分開。每個字符的字符值將決定其在一個范圍內的相對順序。下面的 JScript 正則表達式包含了一個等價于上面所示的括號列表的范圍表達式。

          /Chapter [1-5]/

          VBScipt 中相同功能的表達式如下所示:

          "Chapter [1-5]"

          如果以這種方式指定范圍,則開始和結束值都包括在該范圍內。有一點特別需要注意的是,在 Unicode 排序中起始值一定要在結束值之前。

          如果想在括號表達式中包括連字符,則必須使用下述方法之一:

          • 使用反斜杠將其轉義:
            [\-]
          • 將連字符放在括號列表的開始和結束位置。下面的表達式能匹配所有的小寫字母和連字符:
            [-a-z] [a-z-]
          • 創建一個范圍,其中開始字符的值小于連字符,而結束字符的值等于或大于連字符。下面兩個正則表達式都滿足這一要求:
            [!--] [!-~]

          同樣,通過在列表開始處放置一個插入符(^),就可以查找所有不在列表或范圍中的字符。如果該插入符出現在列表的其他位置,則匹配其本身,沒有任何特殊含義。下面的 JScript 正則表達式匹配章節號大于 5 的章節標題:

          /Chapter [^12345]/

          對 VBScript 則使用:

          "Chapter [^12345]"

          在上面所示的示例中,表達式將匹配第九個位置處除1, 2, 3, 4, or 5 之外的任何數字字符。因此, 'Chapter 7' 為一個匹配,同樣 'Chapter 9' 也是如此。

          上面的表達式可以使用連字符 (-) 表示。對 JScript 為:

          /Chapter [^1-5]/

          或者,對 VBScript 為:

          "Chapter [^1-5]"

          括號表達式的典型用法是指定對任何大寫或小寫字母字符或任何數字的匹配。下面的 JScript 表達式給出了這一匹配:

          /[A-Za-z0-9]/

          等價的 VBScript 表達式為:

          "[A-Za-z0-9]"

          posted @ 2007-06-14 14:11 siwei 閱讀(239) | 評論 (0)編輯 收藏

          僅列出標題  下一頁
          主站蜘蛛池模板: 五峰| 文安县| 长乐市| 云浮市| 寻甸| 黑龙江省| 黔南| 新巴尔虎左旗| 雷山县| 临汾市| 肃南| 通渭县| 黄浦区| 邓州市| 石渠县| 阳山县| 株洲县| 庆元县| 桐城市| 马边| 扶绥县| 宜都市| 荔浦县| 莲花县| 泗洪县| 维西| 大足县| 靖江市| 礼泉县| 通辽市| 双桥区| 南宫市| 沂南县| 尼玛县| 特克斯县| 阜宁县| 应城市| 武鸣县| 萨迦县| 永昌县| 泸西县|