简短版本 我希望我的程序能够(只读)在运行时访问自己的源代码。有没有办法在编译期间自动将源代码打包到dll中?
长版:
背景是当发生异常时,我想自动创建一个包含所发生事件细节的文件。除其他外,此文件应包括导致问题的函数的源代码。我想通过电子邮件将此文件发送给其他人,并且接收者很可能没有(或者不想安装)Visual Studio,因此任何使用符号服务器等的东西都是不可能的。它必须是纯文本文件。
理想情况下,我会找到相关的源代码文件,然后复制相关的行。你可以放心地假设,只要我有一个包含整个源代码的文件夹,我就能找到我想要的文件和行。
到目前为止我能想出的最好的想法 - 而且我没有详细研究过它,因为它看起来很乱 - 无论如何都是修改MSBuild文件以在编译期间创建源的.zip ,并要求.dll和.zip驻留在同一个文件夹中。
我发现的大多数关于stackoverflow的类似问题似乎都涉及反编译 .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)承担了在一个函数中忘记写行的风险,从而给出了所做内容的错误表示。但我对其他解决方案持开放态度,而不是复制源代码。
答案 0 :(得分: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上也有一个提到这个事实的问题。)
答案 1 :(得分:1)
您可以将源文件的副本包含为资源。
Resources
的子文件夹。将源文件复制到那里。设置预构建事件以将实际源文件复制到Resources
文件夹,因此您始终拥有更新的副本。在我创建的示例中,这很有效:
copy $(ProjectDir)*.cs $(ProjectDir)Resources
在你的代码中,现在你可以得到这样的文件内容(我想资源文件的名称是Resource1.resx
:
// Get the source of the Program.cs file.
string contents = Resource1.Program;
项目结束了这样:
答案 2 :(得分:0)
是的,我还建议在MSBuild中以.zip或其他方式打包源,并将.zip打包到您的application / dll。在运行时,当发生异常时,您将获得Aschratt描述的文件和方法名称,从.zip中提取文件并在其中查找方法。