构建Visual Studio项目而无需访问引用的dll

时间:2010-03-16 08:41:20

标签: c# .net visual-studio assemblies stub

我有一个项目,它有一组二进制依赖项(程序集dll,我没有源代码)。在运行时,需要在机器上预安装这些依赖项,并且在编译时,它们在源代码树中是必需的,例如在lib文件夹中。 由于我还为此程序提供了源代码,因此我想为其启用简单的下载和构建体验。不幸的是,我不能重新分配dll,这使事情变得复杂,因为VS不会在没有访问引用的dll的情况下链接项目。

无论如何,如果没有真正引用的dll,是否可以构建和链接此项目?

也许有一种方法可以告诉VS链接自动生成的dll存根,以便它可以在没有原始存储的情况下重建?也许有第三方工具可以做到这一点?这个领域有任何线索或最佳实践吗?

我意识到这个人必须有权访问dll才能运行代码,所以他可以将它们添加到构建过程中,但我只是想让他们省下收集所有dll和放置的痛苦他们手动在lib文件夹中。

5 个答案:

答案 0 :(得分:2)

也许其中一个想法可以帮助您解决问题:

  • 从第三方dll中的所有类派生接口。将这些接口放入自己的项目(相同的解决方案)并添加对此接口程序集的引用。还要将EventHandler添加到AppDomain.AssemblyResolve并尝试在运行时查找并加载程序集。 (学分归NG)
    • 根据dll的大小以及对公共部分进行更改的频率,这可能会产生真正的痛苦。
  • 提供readme.txt,您可以在其中解释如何获取所需的程序集以及用户应将其放在项目路径中的位置。通常情况下,VS非常智能,可以在将程序集放入项目引用它的正确位置后立即删除感叹号(可能您必须在解决方案资源管理器中按刷新)(致记者转到Paul)
    • 不要忘记将readme.txt添加到解决方案,方法是右键单击解决方案,然后选择“添加 - >”;现有项目'。在这种情况下,它将在visual studio解决方案资源管理器中获得一个非常突出的位置,用户可以双击读取它。
  • 在您的解决方案中创建另一个项目,该项目能够自动下载所有需要的dll并将它们放入正确的位置。也许它应该在开始下载之前检查这些所需文件是否已经存在。设置原始项目的项目依赖项,以便它依赖于此项目。因此它将始终在原始版本之前构建。然后在原始项目的预构建事件中启动此下载帮助工具,不要忘记使用int值退出程序。 0表示成功,任何其他错误,因此Visual Studio也知道您的工具是否成功并在挂起缺少的dll之前停止编译过程。
    • 也许几乎不可能自动下载文件,因为您需要登录网页或使用某些无法通过工具自动化的cookie,flash,验证码等。

答案 1 :(得分:2)

对于上述所有好的建议,同意了。话虽这么说,也许有一个有效的场景,通常不需要外部DLL?所以这就是你做的。你包装并隔离它们。 (它比创建接口更高级别的抽象,因此更容易维护)。

在Visual Studio中,如果您不重新编译引用外部DLL的特定VS项目,那么您可以在不使用这些DLL的情况下编译VS解决方案项目的其余部分。因此,如果您以某种方式用您自己的DLL包装外部DLL,然后将这些包装器仅作为二进制文件分发,则共享源代码的人将不需要外部DLL来编译主解决方案。

<强>考虑: 1.将包装器代码分离为独立项目的额外工作。 2.其他VS Projects必须添加对包装器DLL的引用,作为“文件系统”引用“LIB”文件夹,而不是“项目引用”。 3. VS Solution配置必须禁用包装器DLL的编译。如果需要,应添加新配置以明确重新编译它们。 4.每个Wrapper DLL的VS Project定义应包括一个构建后事件,以将它们复制到预期的“LIB”文件夹位置。 5.在运行时,外部DLL必须存在于应用程序的bin目录或计算机的GAC中,否则必须明确加载。注意:如果缺少它们,则只有当它们在运行时实际调用时,它们的缺失才会导致运行时错误。即如果代码在一般情况下没有调用它们,则不需要它们。 6.在运行时,您可以捕获加载外部DLL的错误,并向用户显示一条漂亮的错误消息,说“为了使用此功能,请安装以下产品:xyz”。哪个比显示“AssemblyLoadException ...请使用FusionLogViewer ...等”更好 7.在应用程序启动时,您可以测试和检测丢失的DLL,然后禁用依赖它们的特定功能。

例如:根据这种模式,我可以有一个与Microsoft CRM和SAP集成的应用程序,但仅适用于特定功能,即导入/导出。
在设计时,如果开发人员不需要更改包装器,他们将能够在没有这些外部DLL的情况下重新编译。 在运行时,如果用户从不调用此函数,则应用程序将永远不会调用包装器,因此不需要外部DLL。

答案 2 :(得分:0)

保存他们收集所有程序集的痛苦并将它们自己放在lib文件夹中。然后将它们与存储库中的源代码一起提交。这样,人们从存储库中检出代码也将获得编译项目所需的一切。

答案 3 :(得分:0)

一种相当大的可能性是使用分离的接口模式并在运行时以编程方式加载dll。

答案 4 :(得分:0)

我宁愿让编译时依赖性失败我的构建而不是运行时错误可能需要一些时间来追踪。

在您的解决方案中放置一个Readme.txt,明确说明依赖性是什么,在哪里获取它们以及如何处理它们。