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

2016年5月1日 星期日

PlatformTarget 不同而造成的 Build warning

[Problem description]
在 Build C# 的過程當中,當某個 Project A 有 reference 到 Project B,如果這兩個 Projects 的 PlatformTarget 不同,則 MS-Build 結果有可能出現下列 Warning 訊息: (此 warning 不會出現在 VS-Build )

"warning MSB3270: There was a mismatch between the processor architecture of the project being build "MSIL" and the processor architecture of the reference "[internal C# dll]", "x86"."


[Root cause]
這是因為 兩個 Projects 的 Debug platform (或是 Release platform) 不相同所造成。如下圖所示:
MasterDiskAutoTool.Test.csproj 是一個 Unit test project,它會 reference 到 AutoTool.csproj。
然而,MasterDiskAutoTool.Test.csproj 的 release build platform 為 Any CPU,與 AutoTool.csproj 的 release build platform 的 x86 不相同。
因此,MS-Build 的結果有可能產生 Warning



[Solution]
把 MasterDiskAutoTool.Test.csproj 的 release build platform 改為 x86 (與 AutoTool.csproj 一樣),然後 MS-Build 就沒有Warning 了。
如下圖所示:




**PS: 另外一個因為Platforms 不同所造成的執行時期錯誤,請參閱 這裡


相關連結:
VS compile warning - “mismatch between processor architecture” stack overflow

2016年4月17日 星期日

Regex Tester (Regular Expressions 線上debug pattern)

發現一個不錯的網站, 可以直接在線上 debug 與 test Regular Expressions的 pattern,而且它還有解釋 pattern 的每個意義:

  regular expressions 101



先關連結:
Regular Expression的學習筆記

2016年4月13日 星期三

NUnit gets wrong configuration file (NUnit test 讀不到 app.config)

[Problem description]
要讀取應用程式的app.config,若使用下列的 API,在 NUnit 環境下可能會讀取到錯誤的 config:

if (File.Exists(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile))
{
    // do something
}

雖然使用此 API,在執行應用程式時可以正確回傳應用程式的config 檔案 (ex: <MyAppName>.exe.config),可是在 NUnit 環境下,使用此API 卻會回傳另外的 config 檔案!
例如:
  • 使用 VS2010 + Resharper (v6.1) 會回傳 ~\UnitTest\bin\Debug 目錄下的 UnitTest.dll.config 
  • 使用 VS2015 + Resharper (v10.0) 會回傳 %temp% 目錄下某個隨機子目錄的 config 檔案
這種不確定性會造成 unit test 不夠 robust, 而且上述兩種環境都無法正確讀取到<MyAppName>.exe.config。

[Root cause]
AppDomain.CurrentDomain 可以用來取得目前應用程式的 domain 。
  1. 對於應用程式來說, AppDomain.CurrentDomain 指的是 exe 所在的目錄,一般是位於~\bin\Debug 
  2. 對於 NUnit  來說,它沒有 exe 檔案,所以指的是 UnitTest.dll 所在的目錄: ~\UnitTest\bin\Debug
  3. 然而, 使用 VS2015 + Resharper (v10.0) 卻指向 %temp% ,這個應該是設定上的問題。
既然在使用NUnit 上透過 AppDomain.CurrentDomain 只能取得 NUnit 自己的 domain ,無法取得我們想要的應用程式 domain ,因此無法透過此API 取得 <MyAppName>.exe.config

[Solution]
有下列幾種 work around:
  1). 改用應用程式的 Settings.setting 取代 <MyAppName>.exe.config
  2). 移除 app.config 與 MyAppName 的直接相依性, 改用 dependency injection 來建立 app.config 與 MyAppName的關係,如此便很方便 Mock 這個 app.config 在NUnit的程式碼當中




相關連結:
app.config 與 Settings.setting 的差異: MSDN forums, StackOverflow, User settings - MSDN
什麼是 AppDomain
AppDomain.CurrentDomain 屬性
Application 與 AppDomain.CurrentDomain 的差異

2016年4月9日 星期六

System.BadImageFormatException: Could not load file or assembly '...' ( Platform target 不一致)

[Problem description]
當某個 Project A (ex: unit test project) 使用某個 Project B,此時 compile 沒有問題,但是執行 Project A 卻發生下列錯誤訊息:

System.BadImageFormatException : Could not load file or assembly 'Project B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.

[Root cause]
Project A 與 Project B 並不同為是 32-bit (或是 64-bit) 平台 (target platform)

[Solution]
編輯這兩個Projects 的 Platform target 同為 x86 (或是 64),如下:

2016年2月23日 星期二

Unit Test Runner failed to load test assembly

用 ReSharper 在執行 Unit Test (on VS 2010 ) 的時候,若發生"could not load nunit.framework",請嘗試將 nunit.framework 的 Copy Local 設為 True。如此 nunit.framework.dll 才會被 copy 到此unit test project 的 output folder,讓此 unit test project 可以 reference。

說明如下:
當一個 DLL 被加入至一個 project 當作 reference ,這個 DLL 預設的 Copy Local =True。
然而,若此 DLL 已經被註冊到 GAC ,則應該設此 DLL 的 Copy Local =False,否則有可能會 Build falied。
註1: 有關 Copy Local,請參閱:
The Copy Local property determines whether a reference is copied to the local bin path. At run time, a reference must exist in either the Global Assembly Cache (GAC) or the output path of the project. If this property is set to true, the reference is copied to the output path of the project at run time.