在C#项目中引用exe文件是不好的做法

时间:2014-04-03 11:06:10

标签: c# .net

我有一个简单的问题。

我知道我可以在我的C#项目中引用.net可执行文件。

我不想用"输出类型:Windows应用程序"只是打个电话。

我只是想知道它是否正确或者是否反对exe文件是不好的做法?

5 个答案:

答案 0 :(得分:25)

是的,出于以下原因,这可能被视为一种不良做法:

  • 错误的项目架构
    如果你需要从.exe调用一些逻辑,那么那个逻辑就错误地放在那里了。相反,您应该将它放在一个单独的dll中,并从您当前引用的可执行文件和引用该可执行文件的应用程序引用相同的.dll。 正如comments below中所建议的那样,将逻辑解压缩到库中可以帮助您避免一些CPU架构限制,我将在下一点中对其进行描述,因为可以构建库来定位任何CPU。

  • 架构限制
    引用的可执行文件可能是为了最佳地解决32位或64位计算机,甚至是特定的CPU(如Itanium)而构建的。可以在没有这些规范 1 的情况下构建库,以便与CPU兼容,因此以后可以被任何项目引用。如果引用具有特定体系结构设置的可执行文件,则应使用与引用项目的兼容设置。我认为这是一种限制,因为您无法将最终产品分发到某些平台。

  • 使单元测试困难 正如Abel in the comments暗示的那样,你的单元测试将进入他们自己的DLL,他们也需要引用可执行文件。如果不使用InternalsVisibleTo属性公开某些内部方法/字段,或者使用反射(这是一种缓慢的替代方法)来检查和断言对象的某些非公开可见状态,则可能很难对其进行测试。可能无法使用InternalsVisibleTo属性集构建可执行文件,如果您回退到反射,则可能会遇到.NET安全问题,导致无法反映可执行文件的成员(因为测试套件是在更严格的设置中执行的) ,例如)。

    您还将遇到上述架构限制,这将导致您的单元测试使用相同的架构。如果您的测试套件在远程计算机上执行,这可能是一个问题,作为自动构建的一部分(例如在TravisCI,Bamboo,TeamCity等中)。然后,CI代理必须符合可执行文件和测试套件的CPU体系结构。如果没有合适的代理,则不能运行任何测试。此外,如果您使用公共CI平台构建应用程序并执行测试,则可以将其视为法律意义中可执行文件的分发。您可能会违反可执行文件的许可证 - 有关详细信息,请参阅下一节。

  • 潜在的许可问题
    您应该仔细分发您的申请。如果引用的可执行文件需要额外的许可证或费用才能使用,您必须强制用户在您的应用程序旁边接受该可执行文件的许可证(并在需要时付费),否则您将面临风险用你的软件非法分发它。这也意味着你有正确的来引用可执行文件。

  • 未知后果
    可执行文件将复制到bin文件夹中,并与应用程序一起安装。没有人知道如果有人浏览bin文件夹并执行它会发生什么。这有一些问题:

    • 由于输入不当,可执行文件崩溃或行为不当。通常,如果它没有任何GUI,就会发生这种情况(例如,如果用户双击命令行程序,它将不会以命令行参数的形式获得任何输入,从而导致崩溃或行为异常)。

    • 程序的所有者不打算使用可执行文件,因为这在合法或逻辑上与软件的功能相矛盾。

然而,在某些情况下,引用可执行文件是合理的,但这些很少见:

  • 可执行文件来自第三方,并且不存在具有相同功能的库,并且没有其他方法可链接到该功能。它也可能是您的雇主或客户建立的项目的明确要求。
  • 可执行文件以其他语言编写,您需要通过互操作与其进行通信。

只要后者不适用于您,特别是如果您开发自己引用的可执行文件,我肯定会建议将所需的逻辑提取到单独的库中。


1 实际上,您也可以构建一个可执行文件来定位任何CPU,如Dominic Kexel's comment所述。相反的情况也是可能的 - 为特定的CPU构建一个库,但它不常见,因为可执行文件通常是为硬件定制的。 因此,为了澄清我的观点,我想到了引用第三方可执行文件,或者因其他原因无法重建的可执行文件,并且该可执行文件已针对某些特定体系结构进行了优化。如果您可以重建并更改该可执行文件'有针对性的CPU,那么你绝对可以将所需的逻辑提取到一个DLL中。

答案 1 :(得分:9)

如果你在项目中包含一个可执行文件作为资源,那么我认为如果它解决了你的问题并且有效,那就没什么大不了的了(虽然从理论上讲,将常见的逻辑提取到一个单独的{ {1}}可用于多个项目)。

但是:您可能希望将.dll包含为嵌入式资源,以便在构建项目时直接在输出目录中看到它:

右键单击项目节点,然后选择.exe并找到Add > Existing Item文件。现在在解决方案资源管理器中右键单击它,选择.exe并将properties设置为 Build Action

现在它将“烘焙”到您自己的.dll或.exe或您正在构建的任何内容中,而不是简单地复制到您的输出目录中。

答案 2 :(得分:3)

.NET DLL或EXE都是程序集,您可以通过引用它们来使用exe或dll。 使用您的代码运送exe是没有问题的,除非您不想单独执行此exe。

答案 3 :(得分:2)

没关系,如果它可以帮助您及时发货。

从长远来看,这不是好事。所以可能只是给自己留个笔记,一旦你有足够的时间来修改它更好

但首先,如果你现在没有足够的时间,那就没关系:让它运转起来。

答案 4 :(得分:1)

我对这个问题的回答远未达成共识。
能够将.NET可执行程序集引用为库是.NET和CLI设计的功能之一。此功能使您不必创建单独的项目,然后再在其中移动和修改逻辑。
如果您担心项目在交付时的外观,那么ILMerge是您的朋友。而且,如果您引用的是经过严格许可的第三方库,则可以告诉ILMerge在合并过程中跳过它。
但是,@Ivaylo Slavov指出,如果您的项目是依赖于体系结构(x86 / x64)的,则必须走艰难的路。