概念問題
什麼是 .NET?
簡單地說,Microsoft® .NET 是 Microsoft 以服務的方式遞交軟體的一種政策。有關完整資訊,請參閱有關該主題的白皮書(英文)。
以下是白皮書的摘要,簡要介紹了 .NET 的關鍵内容:
- Microsoft .NET 平台 包括用于建立和操作新一代服務的 .NET 基礎結構和工具、用于實施多資訊用戶端的 .NET 使用者經驗,以及用于啟用新一代智能 Internet 裝置的 .NET 構造塊服務和 .NET 裝置軟體。
- Microsoft .NET 産品和服務 包括 Microsoft® Windows.NET(其核心內建了一組構造塊服務)、MSN.NET、個人訂閱服務、Microsoft® Office.NET、Microsoft® Visual Studio.NET 和 Microsoft® bCentral™ for .NET。
- 第三方 .NET 服務 許多領域的合作夥伴和開發人員都有機會在 .NET 平台上提供企業和垂直服務。
此問題針對的是 .NET 架構。.NET 架構是 .NET 平台基礎結構的一部分。有關 .NET 架構的詳細資訊,請參閱下一個問題。
傳回頁首
什麼是 .NET 架構?
.NET 架構是建立、部署和運作 Web 服務及其他應用程式的一個環境。它包括三個主要部分:公共語言運作時、架構類和 ASP.NET。
傳回頁首
.NET 架構是否隻适用于建立 Web 站點的使用者?
.NET 架構使您可以建立優秀的 Web 應用程式。但它也可以幫助您建立現在的各種應用程式。與目前建立應用程式的方式相比,.NET 在編寫任何 Windows 軟體(使用 ATL/COM、MFC、Microsoft® Visual Basic® 或标準 Microsoft® Win32®)方面都具有更大的優勢。當然,如果您是開發 Web 站點,那麼從 ASP.NET 開始,您就會感受到 .NET 架構的強大吸引力。
傳回頁首
從何處可以獲得 .NET 架構 SDK?
現在可以從 MSDN Online Downloads(英文)下載下傳 .NET 架構 SDK 的 Beta 1 版。鑒于其大小,我們以多種方式提供此 Beta 版:作為一個下載下傳檔案 (106 MB),分為 11 部分下載下傳,或者從 Microsoft Developer Store 定購其 CD:
- 美國/加拿大(英語)
- 國際(英語)
傳回頁首
.NET 架構可以運作于哪些平台?
Beta 1 版可以運作在 Microsoft® Windows® 2000、Windows 95/98/ME 和 Windows NT® 4.0 上。
另外,還有一個稱為 .NET 精簡架構的 .NET 架構版本。它用于使蜂窩電話和增強型電視等裝置也具有 .NET 架構的某些功能。.NET 精簡架構将運作在 Windows CE 和其他嵌入式作業系統上。
傳回頁首
.NET 架構支援哪些程式設計語言?
.NET 架構與程式設計語言無關。事實上任何語言都可以支援 .NET 架構。目前,您可以用許多語言來建立 .NET 程式,包括:C++、Microsoft® Visual Basic.NET、JScript® 和 Microsoft 的最新語言——C#。以後,也會有大量的第三方語言可以用來建立 .NET 架構應用程式,包括 COBOL、Eiffel、Perl、Python、Smalltalk 等等。
傳回頁首
.NET 架構和 COM+ 服務之間是什麼關系?
在 .NET 架構中,不僅可以完全通路 COM+ 服務,而且也更容易建立服務元件。
.NET 架構元件可被添加至 COM+ 應用程式中。在 COM+ 應用程式中,.NET 架構元件可以利用自動元件服務,例如:事務、對象池、排隊元件、事件等等。
傳回頁首
.NET 架構和 DCOM 之間是什麼關系?
DCOM 是用于程序間通訊的 COM 基礎結構。.NET 架構支援大量用于程序間通訊的可插入通道和格式化程式。在托管代碼和非托管代碼之間進行轉換時,.NET 架構使用了 COM 基礎結構,尤其是 DCOM。所有使用 COM+ 服務的方案都使用了托管到非托管轉換,是以預設使用 DCOM。對于注重互操作性的程序間通訊,.NET 架構也支援 SOAP(簡單對象通路協定)。
傳回頁首
.NET 架構是否僅僅是 Windows DNA 的新名稱?
不。Windows DNA 是用于建立緊耦合的分布式 Web 應用程式的一種體系結構。由于分布式應用程式變得需要更多的松耦合原理,是以 Microsoft 在 .NET 中發展了該體系結構。.NET 架構是 .NET 體系結構的一部分。
傳回頁首
運作時技術問題
術語
什麼是公共語言運作時 (CLR)?
公共語言運作時是 .NET 架構應用程式的執行引擎。
它提供許多服務,包括:
- 代碼管理(加載和執行)
- 應用程式記憶體隔離
- 類型安全驗證
- IL 到本機代碼的轉換
- 中繼資料(增強的類型資訊)通路
- 為托管對象管理記憶體
- 強制代碼通路安全
- 異常處理,包括跨語言異常
- 托管代碼、COM 對象和現有 DLL(非托管代碼和資料)之間的互操作
- 自動進行對象布局
- 對開發人員服務(配置、調試等)的支援
傳回頁首
什麼是公共類型系統 (CTS)?
公共類型系統是多資訊類型系統,它被内置在公共語言運作時中,支援大多數程式設計語言中的類型和操作。公共類型系統支援大量程式設計語言的完全實作。
傳回頁首
什麼是公共語言規範 (CLS)?
公共語言規範是一組結構和限制,用作庫編寫者和編譯器編寫者的指南。它使任何支援 CLS 的語言都可以完全使用庫,并且使這些語言可以互相內建。公共語言規範是公共類型系統的子集。對于那些需要編寫代碼供其他開發人員使用的應用程式開發人員,公共語言規範也非常重要。如果開發人員遵循 CLS 規則來設計公共通路的 API,那麼就可以在支援公共語言運作時的任何其他程式設計語言中很容易地使用這些 API。
傳回頁首
什麼是 Microsoft 中間語言 (MSIL)?
MSIL 是與 CPU 無關的指令集。.NET 架構程式被編譯成 MSIL。它包含加載、存儲、初始化和調用對象方法的指令。
與中繼資料和公共類型系統結合,MSIL 允許真正的跨語言內建。
MSIL 在執行前被轉換為機器代碼,而不是一邊解釋一邊執行。
傳回頁首
什麼是托管代碼和托管資料?
托管代碼是編寫為支援公共語言運作時服務的代碼(請參閱“什麼是公共語言運作時?”)。為了支援這些服務,代碼必須向運作時提供最小級别的資訊(中繼資料)。預設情況下,所有 C#、Visual Basic.NET 和 JScript.NET 代碼都是托管代碼。Visual Studio.NET C++ 代碼在預設情況下不是托管代碼,但通過指定指令行開關 (/CLR),編譯器也可以生成托管代碼。
與托管代碼密切相關的是托管資料。托管資料是由公共語言運作時的垃圾回收器進行配置設定和釋放的資料。預設情況下,C#、Visual Basic 和 JScript.NET 資料是托管資料。不過,通過使用特殊的關鍵字,C# 資料可以被标記為非托管資料。Visual Studio.NET C++ 資料在預設情況下是非托管資料(即使在使用 /CLR 開關時),但是在使用 C++ 的托管擴充時,可以使用“__gc”關鍵字将類标記為托管類。就象該名稱所顯示的那樣,它表示類執行個體的記憶體由垃圾回收器管理。另外,該類也完全成為 .NET 架構的成員,同時具備它所帶來的好處和限制。好處的一個例子是:它可以與其他語言編寫的類正确地進行互操作(如托管的 C++ 類可以從 Visual Basic 類繼承);限制的一個例子是:托管類隻能從一個基類繼承。
傳回頁首
程式集
什麼是程式集?
程式集是 .NET 架構應用程式的主要構造塊。它是作為一個單一實作單元(包含一個或多個檔案)來建立、辨別和部署的功能集合。所有的托管類型和資源都可以被标記為僅在其實作單元内通路,或者标記為可由該單元以外的代碼來通路。
程式集通過清單來進行自我說明。清單是每個程式集的不可或缺的組成部分。清單:
- 建立程式集辨別(以文本名稱的格式)、版本、類别和數字簽名(如果要在應用程式之間共享該程式集)。
- 定義組成程式集實作的檔案(通過名稱和檔案散列)。
- 指定組成程式集的類型和資源,包括哪些是從程式集中導出的。
- 逐條記錄編譯時對其他程式集的依存。
- 指定程式集正确運作所需要的權限的集合。
此資訊在運作時用于解析引用、強制版本綁定政策以及驗證所加載的程式集的完整性。因為每一類型都被加載到程式集的上下文中,是以運作時可以确定并定位任何正在運作的對象的程式集。程式集也是應用了代碼通路安全權限的單元。在确定授予其所包含的代碼哪些權限時,每個程式集的辨別證據都被認為是獨立的。
程式集的自我說明特征也有助于實作無影響安裝和 XCOPY 部署。
傳回頁首
什麼是專用程式集和共享程式集?
專用程式集僅由單一應用程式使用,并且存儲在該應用程式的安裝目錄中(或其子目錄中)。共享程式集是可被多個應用程式引用的程式集。要共享一個程式集,該程式集必須明确為這個目的而建立,這可以通過給其指定加密的增強型名稱(用作共享名稱)來實作。相反,專用程式集名稱隻要求在使用它的應用程式中是唯一的。
通過區分專用和共享程式集,我們介紹明确決定共享的要點。隻需簡單地将專用程式集部署在應用程式目錄中,即可確定應用程式隻在建立和部署它的那部分中運作。對專用程式集的引用隻在專用應用程式目錄内部進行解析。
選擇建立和使用共享程式集可以有多種原因,例如表達版本政策的能力。共享程式集具有加密的增強型名稱,這項事實意味着隻有程式集的作者才擁有密鑰來生成程式集的新版本。是以,如果您做出政策聲明,希望接受程式集的新版本,則您可以确信版本更新将由作者來控制和驗證。否則,您就不會接受它們。
對于在本地安裝的應用程式,共享程式集通常被明确安裝在全局程式集緩存中(程式集的本地緩存由 .NET 架構維護)。.NET 架構的版本管理特性的關鍵在于下載下傳的代碼不會影響本地安裝的應用程式的執行。下載下傳的代碼被放在一個特殊的下載下傳緩存中,即使某些下載下傳元件被編譯為共享程式集,也不能在機器上全局使用這些代碼。
與 .NET 架構一起釋出的類都被編譯為共享程式集。
傳回頁首
如果我想建立一個共享程式集,在标記和管理密鑰對方面是否需要額外的開銷?
建立共享程式集确實涉及到加密密鑰方面的工作。建立程式集時,隻有公共密鑰是必要的。支援 .NET 架構的編譯器提供指令行選項(或使用自定義屬性),用于在建立程式集時提供公共密鑰。通常在資源資料庫中保留一份常用的公共密鑰,并使編譯腳本指向此密鑰。在釋出程式集之前,必須使用相應的私人密鑰将其完全标記。這是通過 SDK 工具 SN.exe(增強型名稱)來完成的。
增強型名稱标記不象 Authenticode 一樣需要使用證書。它不涉及第三方組織,不需要付費,也不受證書限制。另外,驗證增強型名稱的額外開銷遠遠小于驗證 Authenticode 的開銷。不過,增強型名稱不會生成任何信任某個出版商的語句。增強型名稱使您可以确信給定程式集的内容沒有被篡改,在運作時為您加載的程式集來自于您開發時針對的出版商。但它不會生成有關是否信任出版商身份的語句。
傳回頁首
名稱空間與程式集名稱之間有什麼差別?
名稱空間是類型的一種邏輯命名方案,其中簡單類型名稱(如 MyType)前面帶有用點分隔的層次結構名稱。這樣的命名方案完全在開發人員的控制之下。例如,鍵入 MyCompany.FileAccess.A 和 MyCompany.FileAccess.B 在邏輯上将會具有與檔案通路相關的功能。.NET 架構使用一種層次結構命名方案,用于将類型按相關功能的邏輯類别進行分組,例如,ASP.NET 應用程式架構或遠端處理功能。設計工具可以利用名稱空間使開發人員更容易在代碼中浏覽和引用類型。名稱空間的概念與程式集的概念之間沒有任何聯系。一個程式集可以包含其層次結構名稱具有不同名稱空間根的類型,而一個邏輯名稱空間根可以跨越多個程式集。在 .NET 架構中,名稱空間是在設計時進行邏輯命名的便捷方式,而程式集在運作時為類型建立名稱作用域。
傳回頁首
應用程式部署和隔離
部署 .NET 應用程式時可以使用哪些選項?
通過使應用程式的無影響安裝和 XCOPY 部署成為可能,.NET 架構簡化了部署。因為所有的請求首先在專用應用程式目錄中進行解析,是以隻需簡單地将一個應用程式的目錄檔案複制到磁盤中,即可運作該應用程式,而不需要注冊。
此方案對于 Web 應用程式、Web 服務和獨立的桌面應用程式特别有吸引力。不過,在有些方案中 XCOPY 還不足以擔當分發機制。例如,當應用程式具有很少的專用代碼,而依賴于可用的共享程式集;或者應用程式不是安裝在本地(而是按需下載下傳)。對于這些情況,.NET 架構提供了擴充的代碼下載下傳服務以及與 Windows Installer 的內建。.NET 架構提供的代碼下載下傳支援通過目前平台提供了許多優勢,包括增量下載下傳、代碼通路安全性(不再有“Authenticode”對話框)和應用程式隔離(為一個應用程式下載下傳的代碼不會影響其他應用程式)。Windows Installer 是 .NET 應用程式可以使用的另外一個強大的部署機制。在 Windows Installer 1.5 中,Windows Installer 的所有特性(包括發行、公布和應用程式修補)都可以在 .NET 應用程式中使用。
傳回頁首
如果我已經編寫了一個程式集,并希望在多個應用程式中使用它,我應該在何處部署它?
要由多個應用程式使用的程式集(如共享程式集)需要部署到全局程式集緩存中。在預釋出版和 Beta 版中,使用 Alink SDK 工具的 /i 選項可将程式集安裝到緩存中:
al /i:myDll.dll
Windows Installer 的後續版本能夠将程式集安裝到全局程式集緩存中。
傳回頁首
如何才能看到在全局程式集緩存中安裝了哪些程式集?
.NET 架構附帶了一個 Windows 外殼擴充,用于檢視程式集緩存。在 Windows 資料總管中,轉至 % windir%/assembly 以激活檢視器。
傳回頁首
什麼是應用程式域?
應用程式域(通常是 AppDomain)是用于隔離應用程式的虛拟程序。在同一個應用程式作用域中建立的所有對象(換句話說,從該應用程式的入口點開始沿着對象激活序列的任何地方)都在同一個應用程式域中建立。多個應用程式域可以存在于一個作業系統程序中,使它們成為隔離應用程式的簡便方式。
作業系統程序通過使用各不相同的記憶體位址空間來提供隔離。盡管它是有效的,但也是代價昂貴的,并且不能達到大型 Web 伺服器所需要的數量。與其相比,公共語言運作時通過管理在應用程式域中運作的代碼的記憶體使用來強制進行應用程式隔離。這樣就確定它不會通路應用程式域以外的記憶體。需要注意的是,隻有類型安全的代碼才能以這種方式管理(當在應用程式域中加載不安全代碼時,運作時不能保證隔離)。
傳回頁首
垃圾回收
什麼是垃圾回收?
垃圾回收是使計算機能檢測何時不再能夠通路某個對象的一種機制。它将自動釋放由該對象使用的記憶體(也調用使用者編寫的稱為“結束者”的清理例程)。一些垃圾回收器(如由 .NET 使用的)會壓縮記憶體,并是以減少程式的工作集。
傳回頁首
非确定性垃圾回收是如何影響代碼的?
對于大多數程式設計人員而言,擁有一個垃圾回收器(并且使用可作為垃圾回收的對象)意味着永遠不需要操心釋放記憶體或引用計數對象,即使您使用了複雜的資料結構。但如果您通常在同一個用于釋放對象記憶體的代碼塊中釋放系統資源(檔案句柄、鎖定等等),那麼在編碼樣式方面需要做一些修改。使用可作為垃圾回收的對象時,您應該提供一種方法,來明确釋放系統資源(也就是說,由您的程式控制),同時允許垃圾回收器在壓縮工作集時釋放記憶體。
傳回頁首
是否能夠避免使用可作為垃圾回收的堆?
所有支援運作時的語言都允許您從可作為垃圾回收的堆中配置設定類對象。這在快速配置設定方面帶來了好處,并且使程式設計人員無需自己來計算何時應該顯式“free”每個對象。
CLR 還提供了 ValueTypes 對象——它們與類相似,但 ValueType 對象是在運作時堆棧(不是堆)中配置設定的,是以當您的代碼退出定義這些對象的過程時,将自動回收它們。這就是 C# 中“struct”的操作方式。
C++ 的托管擴充使您可以選擇類對象配置設定的位置。如果使用 __gc 關鍵字聲明為托管類,它們将從可作為垃圾回收的堆中配置設定;如果它們不包含 __gc 關鍵字,它們将與普通的 C++ 對象一樣從 C++ 堆中配置設定,并且使用“free”方法顯式釋放。
有關垃圾回收的的詳細資訊,請參閱:
- 垃圾回收:Microsoft .NET 架構中的自動記憶體管理(英文)
- 垃圾回收 - 第 2 部分:Microsoft .NET 架構中的自動記憶體管理(英文)
傳回頁首
遠端處理
如何在公共語言運作時中進行程序内和程序間通訊?
程序内通訊有兩種:在單一應用程式域的上下文中,或者跨應用程式域。在同一個應用程式域的上下文中,使用代理作為監聽機制,而不涉及封送處理/序列化。當跨應用程式域時,使用運作時二進制協定來作封送處理/序列化。
程序間通訊為每個特定目的使用一個可插入通道和格式化程式協定。
- 如果開發人員使用 soapsuds.exe 工具指定終結點來生成中繼資料代理,那麼預設值是帶有 SOAP 格式化程式的 HTTP 通道。
-
如果開發人員在托管世界中執行顯式遠端處理,需要明确指定使用的通道和格式化程式。這可以通過配置檔案用可管理的方式來表示,或者用 API 調用來加載特定通道。選項如下:
帶有 SOAP 格式化程式的 HTTP 通道(HTTP 在 Internet 上或任何必須通過防火牆進行通信的時候運作良好)
帶有二進制格式化程式的 TCP 通道(對于區域網路,TCP 是性能較高的選項)
帶有 SOAP 格式化程式的 SMTP 通道(僅對跨計算機有意義)
在托管代碼和非托管代碼之間進行轉換時,COM 基礎結構(尤其是 DCOM)用于遠端處理。在 CLR 的中間版本中,這也适用于服務元件(使用 COM+ 服務的元件)。在最終版本中,配置任何遠端元件都是可能的。
對象的分布式垃圾回收由名為“租用生存期”的系統來管理。每個對象都有一個租用時間,當到期時,該對象與 CLR 的遠端處理基礎結構斷開連接配接。對象具有一個預設的更新時間——當用戶端成功地調用了對象時,租用将被更新。用戶端可以顯式更新租用。
傳回頁首
互操作性
是否可以在 .NET 架構程式中使用 COM 對象?
是。您現在部署的任何 COM 元件都可以在托管代碼中使用。通常情況下,所需的調整是完全自動進行的。
特别是,可以使用運作時可調用包裝 (RCW) 從 .NET 架構通路 COM 元件。此包裝将 COM 元件提供的 COM 接口轉換為與 .NET 架構相容的接口。對于 OLE 自動化接口,RCW 可以從類型庫中自動生成;對于非 OLE 自動化接口,開發人員可以編寫自定義 RCW,手動将 COM 接口提供的類型映射為與 .NET 架構相容的類型。
傳回頁首
是否可以在 COM 程式中使用 .NET 架構元件?
是。您現在建立的托管類型都可以通過 COM 通路。通常情況下,所需的配置是完全自動進行的。托管開發環境的某些新特性不能在 COM 中通路。例如,不能在 COM 中使用靜态方法和參數化構造函數。一般,提前确定給定類型所針對的使用者是一種較好的辦法。如果類型需要在 COM 中使用,您将被限制在使用 COM 可通路的特性。
預設情況下,托管類型可能是可見的,也可能是不可見的,這由用于編寫托管類型的語言決定。
特别是,可以使用 COM 可調用包裝 (CCW) 從 COM 通路 .NET 架構元件。這與 RCW(請參閱上一個問題)相似,但它們的方向相反。同樣,如果 .NET 架構開發工具不能自動生成包裝,或者如果自動方式不是您所需要的,則可以開發自定義的 CCW。
傳回頁首
是否可以在 .NET 架構程式中使用 Win32 API?
是。使用 P/Invoke,.NET 架構程式可以通過靜态 DLL 入口點的方式來通路本機代碼庫。
下面是 C# 調用 Win32
MessageBox函數的示例:
using System;
using System.Runtime.InteropServices;
class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MessageBox(int hWnd, String strMessage, String strCaption,
uint uiType);
public static void Main()
{
MessageBox( 0, "您好,這是 PInvoke!", ".NET", 0 );
}
}
傳回頁首
安全性
如何使代碼與安全系統協調工作?
通常,這不成問題——大多數應用程式能安全地運作,不會受惡意攻擊的幹擾。通過簡單地使用标準類庫來通路資源(如檔案)或執行受保護的操作(例如反轉類型的私有成員),安全性由這些庫來實施。應用程式開發者需要完成的一項簡單工作是包括權限請求(一種公開的安全性),将代碼可能接收的權限限制在它所需要的權限範圍内。這也確定了如果代碼被允許運作,它在運作時将具有所需的所有權限。
僅當開發人員需要編寫提供新型資源的新基類庫時,他們才需要直接處理安全系統。在這種情況下,并非所有的代碼都有潛在的安全性問題,代碼通路安全機制将其限制在替代了安全系統的那部分代碼上。
傳回頁首
為什麼在網絡共享驅動器中運作代碼時會發生安全異常?
預設安全政策僅給來自本地 Intranet 區域的代碼授予有限的權限。這個區域是由 Internet Explorer 安全設定定義的,它們應該配置為與企業内部的本地網絡相比對。由于由 UNC 或映射驅動器(例如使用 NET USE 指令)命名的檔案都需要在本地網絡上發送,是以它們也在本地 Intranet 區域中。
預設值是為不安全的 Intranet 這種最壞情況而設定的。如果您的 Intranet 比較安全,您可以修改安全政策(用 CASPol 工具),給本地 Intranet 或其一部分(例如特定的計算機共享名)授予更多的權限。
傳回頁首
如何編寫代碼,使它在安全系統停止該代碼時運作?
當代碼試圖執行未經授權的操作時,将發生安全異常。權限是基于代碼(尤其是其位置)來授予的。例如,從 Internet 中運作的代碼所得到的權限比在本地計算機上運作的代碼所得到的權限要少,這是因為經驗證明,它的可靠性要低一些。是以,要運作由于安全異常而失敗的代碼,您必須增加授予它的權限。一個簡單的方法是将代碼移到更受信任的位置(例如本地檔案系統)。但這種方法并不是在任何情況下都有效(Web 應用程式是一個很好的例子,企業網絡上的 Intranet 應用程式是另一個例子)。是以,不要改變代碼位置,而是通過更改安全政策給該位置授予更多的權限。請使用代碼通路安全政策工具 (caspol.exe) 或圖形化管理工具(在 Beta 2 和更高版本中可以得到)來執行此操作。如果您是代碼的開發人員或發行者,您也可以對它進行數字簽名,然後修改安全政策,給帶有該數字簽名的代碼授予更多權限。但是,在執行上述任何操作時,請記住此代碼被授予較少的權限,是因為它不是來自受信任的來源——在将代碼移至本地計算機或更改安全政策以前,您應該確定這些代碼不會執行惡意或損壞性的操作。
傳回頁首
如何管理個人或企業計算機的安全性?
目前,CASPol 指令行工具是管理安全性的唯一方法。安全政策由兩個級别組成:按計算機和按使用者。我們計劃在 .NET 架構第一版中提供全面的管理工具以及企業政策管理支援。
傳回頁首
基于證據的安全性是如何與 Windows 2000 安全性配合工作的?
基于證據的安全性(基于授權碼)能與 Windows 2000 安全性(基于登入身份辨別)配合工作。例如,要通路一個檔案,托管代碼必須具有代碼通路安全檔案權限,也必須在具有 NTFS 檔案通路權限的登入身份辨別下運作。.NET 架構中包括的托管庫也為基于角色的安全性提供了類。這些都使應用程式能夠與 Windows 登入身份辨別及使用者組配合工作。