2013-01-09 62 views
3

簡短版本: 我希望我的程序能夠(只讀)在運行時訪問其自己的源代碼。有沒有辦法在編譯期間自動將源代碼打包到dll中?如何在dll中包含源代碼?

龍版本:

的背景是,在發生異常時,我想自動創建一個包含發生了什麼的詳細信息的文件。除其他外,該文件應包括導致問題的函數的源代碼。我想通過電子郵件將此文件發送給其他人,並且接收人很可能沒有(或不想安裝)Visual Studio,因此使用符號服務器和類似服務的任何內容都是沒有問題的。它需要是一個純文本文件。

理想情況下,我會在某處找到相關的源代碼文件,只是複製出相關的行。你可以放心地假設,只要我有一個包含整個源代碼的文件夾,我就可以找到我想要的文件和行。

到目前爲止,我可以想出最好的想法 - 我沒有詳細研究它,因爲它似乎無處不在 - 是修改MSBuild文件以創建一個.zip源代碼編譯,並要求.dll和.zip駐留在同一個文件夾中。

大多數的計算器上的發音相似的問題,我發現似乎對付反編譯 .dll文件,這是我想做的事情。我的的源代碼,我想用便捷的方式將它與.dll一起發貨。

更新:很長的版本

似乎有些人嚴重質疑爲什麼我想這樣做,所以這裏的答案:我的軟件的主要目的是測試一些其他軟件。其他軟件有一個GUI。對於一個簡單的例子,假設其它軟件是標準的Windows計算器,然後我的測試用例可能是這個樣子:

calculator.Open(); 
calculator.EnterValue(13); 
calculator.PressButtonPlus(); 
calculator.EnterValue(38); 
calculator.PressButtonEnter(); 
int value = calculator.GetDisplayedValue(); 
Assert.That(value == 51); 
calculator.Close(); 

這些測試是故意寫的非常可讀的方式。

當發生問題時,我想要做的是給計算器的開發人員詳細說明如何以手工方式重現問題,,而不需要我的軟件。 (在這個例子中,他會打開計算器,輸入13,然後按加號,等等。)

也許另一個選擇是讓每個函數calculator.Something()寫出一條信息行到一個日誌,但那會a)做更多的工作,b)只包括測試跑到它中止的地步,以及c)承擔一些函數中忘記寫行的風險,從而給出了所做的不正確表示。但我願意接受其他解決方案,而不是複製源代碼。

+3

一些調試符號文件(.pdb)有問題嗎? – Oded

+0

哇............. – Tigran

+0

@Oded:他的目標客戶端沒有,也不想擁有VS或其他工具。 (出於某種原因) – Tigran

回答

2

在這個問題請看:Do __LINE__ __FILE__ equivalents exist in C#?

C++提供的宏(__LINE____FILE__,等等),與在編譯時代表信息取代。這意味着如果你寫的東西是這樣的:

throw new CException(__FILE__); 

它將編譯到這樣的事情:

throw new CException("test.cpp"); 

導致硬編碼值。 C#編譯器不提供這些宏,並且您不得不使用反射來獲取有關拋出異常的位置的信息。上面鏈接的問題描述了你可以做到的方式。

如果你不能夠提供.PDB符號然後Exception.ToString()(或StackTrace.ToString())的默認行爲將不會返回的行號,但失敗的操作的MSIL偏移。據我記得你可以使用ReSharper的Stack Trace Explorer導航到表示代碼(不是100%確定,但在這裏也有一個關於stackoverflow的提到這個事實的問題)。

0

是的,我還建議將源文件打包成.zip或MSBuild期間的任何文件,然後用你的應用程序/ dll打包.zip文件。在運行時,當發生異常時,您將獲得像Aschratt描述的文件和方法名稱,從.zip中提取文件並在其中找到該方法。

1

您可以包含源文件的副本作爲資源。

  • 在項目文件夾中,創建一個名爲Resources的子文件夾。在那裏複製源文件。
  • 在項目中創建一個資源文件,然後包含您創建的源副本。
  • 設置預生成事件以將實際源文件複製到Resources文件夾,因此您始終擁有更新的副本。在我創建的例子,它運行良好:

    copy $(ProjectDir)*.cs $(ProjectDir)Resources 
    
  • 在你的代碼,現在你可以得到的文件這樣的內容(我猜的資源文件的名稱是Resource1.resx

    // Get the source of the Program.cs file. 
    string contents = Resource1.Program; 
    

項目弄成這個樣子:

Project tree