下面我們運(yùn)行一下本文下載包中的一個(gè).NET執(zhí)行文件。 ⑴ 從本文最后下載文件,將文件解壓縮到C:/CodeDownloadDemo文件夾。 ⑵ 在IIS中創(chuàng)建一個(gè)虛擬文件夾CodeDownloadDemo。 ⑶ 將虛擬文件夾映射到C:/CodeDownloadDemo/Loader/Bin文件夾。 ⑷ 啟動(dòng)IE瀏覽器,輸入下面的URL:http://localhost/CodeDownloadDemo/loader.exe。 看到loader應(yīng)用程序在瀏覽器外面運(yùn)行了嗎?應(yīng)用程序一旦開始運(yùn)行,即使關(guān)閉了瀏覽器,我們?nèi)钥梢栽L問應(yīng)用程序。對(duì)于任何其他.NET應(yīng)用程序,我們都可以照此辦理,只要將它放到Web服務(wù)器上,然后用瀏覽器啟動(dòng)即可。 二、UrlScan工具的影響 只要Web服務(wù)器上沒有安裝UrlScan工具,上面的例子就可以毫無問題地運(yùn)行。UrlScan工具隨同IIS Lockdown工具一起發(fā)行,它的功能是禁止向Web服務(wù)器發(fā)送非法的請(qǐng)求。默認(rèn)情況下,UrlScan工具認(rèn)為包含執(zhí)行文件的URL都是非法的,因此假如Web服務(wù)器上安裝了UrlScan,對(duì)http://localhost/CodeDownloadDemo/loader.exe的訪問將被禁止。 要檢查系統(tǒng)中是否已經(jīng)安裝了UrlScan工具,可以在控制面板中打開“添加或刪除程序”,查看“當(dāng)前安裝的程序”清單。 另外,我們還可以修改UrlScan的默認(rèn)配置,使其答應(yīng)對(duì)執(zhí)行文件的請(qǐng)求,即修改一下UrlScan用來檢測(cè)合法/非法請(qǐng)求的INI配置文件。UrlScan的配置文件保存在c:/windows/system32/inetsvr/urlscan/urlscan.ini,下面是該文件的一個(gè)片斷: [DenyExtensions] ; Deny executables that could ; run on the server .was_exe .bat .cmd .com 這個(gè)配置文件片斷中,.exe文件擴(kuò)展名已經(jīng)改成了.was_exe,表示.exe擴(kuò)展名不再被禁止。但必須注重的是,這是解除UrlScan限制的一種簡(jiǎn)便方法,可能帶來安全風(fēng)險(xiǎn)。對(duì)于正式為用戶提供服務(wù)的Web服務(wù)器,修改配置之前務(wù)必閱讀UrlScan的文檔或詢問網(wǎng)絡(luò)治理員。 修改UrlScan的INI配置文件之后,必須重新啟動(dòng)IIS服務(wù)器,才能讓修改生效。例如,在命令行環(huán)境中執(zhí)行IISRESET.exe就可以重新啟動(dòng)IIS服務(wù)器。 三、自動(dòng)部署應(yīng)用程序的其余部分 前面我們了解了如何自動(dòng)部署一個(gè)執(zhí)行文件,這種辦法對(duì)于loader(約45 KB)之類的小型應(yīng)用程序有效,但通常的應(yīng)用程序都要大于45 KB,例如,假如應(yīng)用程序有3 MB,我們不應(yīng)該讓用戶每次運(yùn)行時(shí)都重新下載一個(gè)3 MB的文件。解決這個(gè)問題需要用到.NET自動(dòng)部署機(jī)制的第二部分技術(shù)。 和前面的辦法相比,一種更好的辦法是將主執(zhí)行程序安裝到用戶的硬盤上,讓這個(gè)主執(zhí)行程序按需下載應(yīng)用程序的其余部分。例如,當(dāng)用戶要用到應(yīng)用程序的Invoicing模塊時(shí)就下載Invoicing部分,要用到Employees模塊時(shí)就下載Employees部分(參見圖2)。
圖2:自動(dòng)部署一個(gè)應(yīng)用程序
這種類型的部署通常稱為“滴流”部署(Tickle Down Deployment)。.NET框架提供了支持滴流布署技術(shù)的必要工具類,即System.Reflection名稱空間中的Assembly。Assembly類能夠從遠(yuǎn)程服務(wù)器下載一個(gè)程序集,并在本地緩沖以供以后引用。例如,利用下面的代碼可以從http://localhost/CodeDownloadDemo/Loader/下載ModuleA.dll程序集,然后從該程序集創(chuàng)建EmployeeForm類的實(shí)例: '指定URL Dim URL As String URL = _ "http://localhost/CodeDownLoadDemo/ModuleA.DLL" '從指定的URL裝入程序集 Dim a As [Assembly] a = [Assembly].LoadFrom(URL) '獲得一個(gè)EmployeeForm類的引用 Dim t As Type = a.GetType("ModuleA.EmployeeForm") '創(chuàng)建窗體的實(shí)例,并顯示出窗體 Dim o As Object = Activator.CreateInstance(t) o.Show() 這個(gè)代碼片斷雖然簡(jiǎn)單,卻用到了.NET框架許多值得關(guān)注的特性。下面我們就來逐一分析這些特性。 首先,[Assembly].LoadFrom這行代碼利用HTTP協(xié)議下載一個(gè)DLL。在本例中,URL指向localhost,但它同樣也可以指向一個(gè)遠(yuǎn)程服務(wù)器,例如http://www.mycompany.com/myapp。這就是說,我們只要一行代碼,并指定一個(gè)適當(dāng)?shù)腢RL,其余工作就全交給.NET了,不管程序集是本地的還是遠(yuǎn)程的。 其次,從遠(yuǎn)程服務(wù)器下載得到一個(gè)DLL之后,a.GetType這行代碼從該DLL提取一個(gè)類的引用。注重,類的名稱以字符串的形式指定,這意味著,我們可以在運(yùn)行時(shí)臨時(shí)決定要引用的類的名稱。這一點(diǎn)非常重要,因?yàn)楝F(xiàn)在我們可以在運(yùn)行時(shí)決定要引用的是ModuleA.EmployeeForm,還是ModuleA.InvoiceForm。對(duì)于VB.NET和C#之類強(qiáng)類型的語言,這一特性顯得尤其寶貴,它提供的靈活性是這類語言中非常罕見的。 最后,Activator.CreateInstance(t)這行代碼實(shí)際創(chuàng)建了EmployeeForm類的一個(gè)實(shí)例。有了類的實(shí)例之后,接下來就可以調(diào)用它的方法,設(shè)置它的屬性。在上面的例子中,我們調(diào)用了EmployeeForm類的Show方法。 四、localhost與127.0.0.1的區(qū)別 當(dāng)我們指定的URL是“http://localhost”形式時(shí),前面兩節(jié)介紹的辦法都不會(huì)出現(xiàn)問題。但是,假如我們改用http://127.0.0.1形式的URL,就會(huì)碰到問題。例如,假如用http://127.0.0.1/CodeDownloadDemo/loader.exe這個(gè)URL來打開loader.exe,就會(huì)看到類似圖3的錯(cuò)誤信息: