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

我有一个简单的问题。

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

我不想用“输出类型:Windows应用程序”进行不必要的项目来调用一些dll。

我只是想知道它是否可以或者是一个不好的做法来引用exe文件?

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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