顯示具有 CLR 標籤的文章。 顯示所有文章
顯示具有 CLR 標籤的文章。 顯示所有文章

2016年4月18日 星期一

The Benefits of Isolating Applications (隔離應用程式的優點)

本文先說明應用程式'隔離'(isolation)的概念, 接著再說明.NET 實作'隔離'的方式。

[應用程式'隔離'的概念]
在過去,Process boundaries 被用來達到 app 隔離的效果。App 必須被隔離是因為'記憶體位址' (memory address) 是 process 相關 (process-relative)。也就是說,這個 process 使用的 memory address 不能被另一個 process 使用。
因為 memory address 不能共用,因此,兩個 processes 之間也不能直接互相呼叫,也就是不能直接存取程式碼 (必須使用 proxies, 例如 Inter-process communication)。

而現在,managed code 在被執行之前,必須通過'權限驗證'(permission verification)才能被執行 (除非  administrator 已經授權 skip此驗證 )。權限驗證主要是驗證下列兩件事情:
  1. 程式碼是否可能嘗試存取無效的memory address
  2. 程式碼是否可能無法正常運行
如果上述的驗證通過了,此 managed code 稱為 型別安全 (type-safe) [** 注意: 這裡指的 type safe,指的是memory type safety (參閱 這裡),而不是廣義的type safe定義 (例如 integer 與 string 的型別)]。這種'權限驗證'提供了 CLR 具有與過去Process boundaries 相同的app 隔離效果,而且效率更好!

上述的說明,概念上解釋了隔離的重要性。接下來,說明.NET 如何實作隔離

[.NET實作'隔離'的方式]
在.NET中,使用 AppDomain 可以讓 CLR 提供 app 的隔離效果。CLR 允許單一個process裡面執行多個AppDomains,也就是說,單一個processe可以執行多個 apps,如此便增加了 server 端的 scalability。

AppDomain 具有下列優點:
  1). 在某一應用程式中的錯誤不會影響其他應用程式。由於 type-safe 程式碼不會導致記憶體錯誤,所以使用 AppDomain 可確保在某一Domain中執行的程式碼不會影響處理序(process)裡面的其他應用程式。

  2). 可以停止個別應用程式而不需停止整個處理序(process)。使用 AppDomain 可以卸載在單一個 app 中執行的程式碼。[** 注意: 這裡指的是 "卸載一個完整的AppDomain",而不是卸載一個DLL) (卸載AppDomain的方法, 參閱 這裡 ]

  3). 可以防止不同 AppDomain 中對於物件的呼叫。在不同定義域之間傳遞的物件必須用'複製方式傳遞'或由 'Proxy' 存取。
    3-1). 如果物件是複製的,那麼對該物件的呼叫就是區域呼叫。也就是說,呼叫端(caller)和被參考的物件是在同一個AppDomain。
    3-2). 如果物件是透過 Proxy 存取,那麼對物件的呼叫便是遠端呼叫(call remotely)。在這種情況下,呼叫端(caller)和被參考的物件(referenced object)是在不同的應用程式定義域中。跨定義域呼叫(Cross-domain call)是使用與兩個處理序(process)或兩部電腦之間呼叫相同的'遠端呼叫基礎結構'(remote call infrastructure)。因此,所參考之物件的中繼資料 (Metadata) 必須在這兩個AppDomain 中都能使用,才能讓該方法呼叫被 JIT 適當地編譯。如果caller 無權存取所呼叫之物件的中繼資料(Metadata),則編譯可能會失敗,並擲回型別 System.IO.FileNotFound 的例外狀況。

4). 程式碼的行為範圍(behavior scope)是由該應用程式決定。換言之,AppDomain會提供 app 版本原則、它所存取的遠端組件的位置,以及有關哪裡可以載入組件的資訊。



相關連結:
The Benefits of Isolating Applications: MSDN

2016年4月17日 星期日

什麼是 AppDomain (Application domains, 應用程式定義域)

OS 和 CLR 提供了某種 '隔離' (isolatation) 的概念來確保 process 和 process 之間不會相互影響。Application domains 就是這種 '隔離' (isolatation) 的概念。有了AppDomain,CLR便可以提供組件的安全性 (security)、可靠性 (reliability) 、 版本控制(versioning) 以及 卸載組件(unloading assemblies) 。

AppDomain 是由runtime host 所建立。Runtime host 啟動 CLR之後, 然後再 開始執行 app 。也就是說,Runtime host 會為這個 app 建立一個AppDomain

有關什麼是 AppDomain的詳細說明, 請參閱 這裡


相關連結:
Application Domains : MSDN

2016年4月7日 星期四

Use Costura.Fody to bundle all assemblies into one ( 比 ILMerge 更好用 )

不論是 ILMerge 或是 LibZ,使用上都有一些限制 (參閱: 這裡)
在此,介紹一下 Costura.Fody ,它比 ILMerge或Libz更強大好用:

  • 可將 reflection, native DLLs, 或是3rd party 有使用 reflection 的應用程式整合成一個執行檔。
  • 可把 WPF 應用程式與其他 .Net 的DLL檔案 merge 成為單一執行檔。
  • 比 ILMerge 有更加的壓縮比率。大概是 ILMerge 壓縮出來執行檔的70%。


1).下載 Costura.Fody - 使用VS2015 的 NuGet Package Manager
  • 由 Reference 的 Manage NuGet Packages...下載 Costura.Fody (做法同 LibZ 的下載方式)

2).使用 Costura.Fody 來bundle 所有的 assemblies:
  • 下載之後,在這個project 底下有一個FordyWeavers.xml,編輯此 FodyWeavers.xml,把debug symbols 排除,如下:
          <?xml version="1.0" encoding="utf-8"?>
          <Weavers>
                <Costura IncludeDebugSymbols='false' />
          </Weavers>
  • 然後,在 VS2015 上面 Build 這個 project,<MyApp.exe> 檔案 size 會變大,變成一個單一執行檔。
       *** Costura.Fody 也可以直接用在 WPF app 上面!  夠簡單吧!

3).下載安裝Costura.Fody 之後,若要在VS2015設定 break point 來 debug 了,可以把 .csproj檔案修改如下:
  • <Import Project="~\..\..\Fody.targets" Condition=" '$(Configuration)' == 'Release' " />

相關連結:



2016年3月25日 星期五

Use LibZ to distribute the WPF applications or libraries as single file ( 把WPF應用程式整合成一個執行檔 )

ILMerge的使用有下列限制:
  • 若.Net 應用程式有使用reflection, native DLLs, 或是3rd party 有使用 reflection, 則 ILMerge無法將應用程式整合成一個執行檔。
  • ILMerge 不能把 WPF 應用程式與其他 .Net assemblies 整合成為單一執行檔 (因為 WPF 把 .Net assemblies 編碼成 binary resources ,造成 ILMerge 不能修改這些 assemblies )。


 LibZ 可以解決ILMerge的限制:
  • 即使.Net 應用程式有使用reflection, native DLLs, 或是3rd party 有使用 reflection, 使用 LibZ 也可以把這些原件 embed 成為單一執行檔。(參閱: 這裡)
  • 根據上述,LibZ 可將WPF 應用程式與其他 .Net 的DLL檔案 embed 成為單一執行檔。


下載 LibZ - 使用VS2015 的 NuGet Package Manager (註 1)
  • 由 Reference 的 Manage NuGet Packages...下載 LibZ.Tool (註 2),如下:












  • 或是由Package Manager Console 輸入下載指令,如下:
 PM>Install-Package Libz.Tool 






















使用 LibZ 來embed 所有的DLL檔案:

  • 透過command-line (或是Post-build event command line) 輸入以下指令 - 
libz inject-dll --assembly <MyApp.exe> --include *.dll
  • 然後,<MyApp.exe> 檔案 size 會變大,就變成一個單一執行檔。 
[註 1]
NuGet Package Manager 是由 Microsoft 開發的一組Tools,整合在 VS2015 裡面。可以針對 VS的 Project 所需要的 Package (ex: 3rd party components, Resharper, Libz, Fody...) 進行下載,安裝/反安裝,升級,建構 。

[註 2]
NuGet Package Manager 下載的檔案會放在預設的packages folder 裡面。packages folder的位置 與 solution 位置相同,如下圖所示:


若要修改下載路徑,作法如下:
1). 在solution 相同位置建立一個 nuget.config 檔案
2). 編輯 nuget.config,如下圖所示: